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?
In javascript we can use module as singleton.
Modules are “singletons” in Python because import only creates a single copy of each module; subsequent imports of the same name keep returning the same module object.
}module. exports = Singleton; As we can see we actually created two classes PrivateSingleton and Singleton . This is a trick to hide (create pseudo-private) constructor in Singleton class.
By using singletons in your project, you start to create technical debt. Singletons tend to spread like a virus because it's so easy to access them. It's difficult to keep track of where they're used and getting rid of a singleton can be a refactoring nightmare in large or complex projects.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With