Reputation: 1342
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
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