lei li
lei li

Reputation: 1342

Use module as singleton

In javascript we can use module as singleton.

//a.js
export default {str:'aaa'}

//b.js
import singleton from 'a.js'
singleton.str='bbb'

//c.js
import singleton from 'a.js'
singleton.str='ccc'

I want to use it to be the configure of my module. Is there any risk? It will always be a singleton in every module system?

Upvotes: 10

Views: 3070

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

I want to use it to be the configure of my module. Is there any risk? It will always be a singleton in every module system?

Yes, an ESM module (and a commonjs module) is guaranteed to return the same instance. **

While this is bad design (because it's mutable global state anyone can import and change and it's hard to keep track of) - it's entirely guaranteed to always work.

If you're interested in the details of how Node.js loads modules - you can see the reference of the resolver algorithm in our docs and the relevant bits for CommonJS here.


This is safe to rely on. I'll try to explain why. Imagine modules didn't work this way:

//a.js
export default class Foo { /* some code */ }

//b.js
import Foo from './a';

If whenever b and other files import the class Foo they might get a different instance - stuff like instanceof wouldn't work across modules and it would be impossible to rely on references.

This is generally why this is both guaranteed and supported.

As a fun side node - ES Modules are live references :]

**the caveat is that it's possible to "opt out" - for example by deleting the module from require.cache and setting require.parent in commonjs. However, this is never the default behavior.

Upvotes: 14

Related Questions