Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is singleton guaranteed to be preserved during webpack or rollup module bundling process?

Understanding the fact that singleton creates a shared global state, there will be situations where I might want singleton such as redux store/state object.

If I am using ES modules, I can use the simple code as follows to create singleton:

// a.js (singleton module)
class A {}

// Create singleton
export const a = new A();

Now I can use this instantiated object anywhere in another modules:

// b.js
// Import singleton
import { a } from './a.js';

console.log(a);


// c.js - some other nested file
import { a } from '../../a.js';

console.log(a);

In theory, it should be possible to manage singleton creation as described above. But as of today, we use module bundlers like Webpack.js or Rollup.js to serve JavaScript to the browser. What if these bundlers accidentally/intentionally include some module more than once. The simplest possible thing I can imagine is if I have some sort of symlinks that resolves to the same module via different paths. Or it could simply be a bug in module resolution process.

My question is - do these module bundlers always ensure that a module creating a singleton object stays singleton under every circumstance?

There is one topic which I have not fully looked into. I know ES Symbols are globally unique and they are used to create private object members. That is my next question - Is there a way this characteristics of the symbol can help me create a true singleton? (I believe that symbols will suffer the same problem if bundling process is not sound.)

Finally, last question: Is it ever possible to reliably create a true singleton in JavaScript?

Note: I am not trying to guard against a bug in Module bundler. Bug analogy just is a figure of speech to illustrate the idea.

like image 539
Harshal Patil Avatar asked Mar 30 '18 05:03

Harshal Patil


1 Answers

I use that pattern quite often with rollup and never had a problem. Alternatively you can define a singleton like this:

//singleton.js

let instance;

class Singleton{
    constructor(){
        if(instance){
          return instance; 
        }
        instance = this;
   }
}

var a = new Singleton();
var b = new Singleton();

a === b // true
like image 165
Isidrok Avatar answered Oct 11 '22 12:10

Isidrok