-
-
Save dmnsgn/4a6ad76de1b5928f13f68f406c70bb09 to your computer and use it in GitHub Desktop.
| class SingletonDefaultExportInstance { | |
| constructor() { | |
| this._type = 'SingletonDefaultExportInstance'; | |
| } | |
| singletonMethod() { | |
| return 'singletonMethod'; | |
| } | |
| static staticMethod() { | |
| return 'staticMethod'; | |
| } | |
| get type() { | |
| return this._type; | |
| } | |
| set type(value) { | |
| this._type = value; | |
| } | |
| } | |
| export default new SingletonDefaultExportInstance(); | |
| // ... | |
| // index.js | |
| import SingletonDefaultExportInstance from './SingletonDefaultExportInstance'; | |
| // Instantiate | |
| // console.log(new SingletonDefaultExportInstance); // is not a constructor | |
| // Prototype Method | |
| console.log(SingletonDefaultExportInstance.type, SingletonDefaultExportInstance.singletonMethod()); | |
| // Getter/Setter | |
| SingletonDefaultExportInstance.type = 'type updated'; | |
| console.log(SingletonDefaultExportInstance.type); | |
| // Static method | |
| console.log(SingletonDefaultExportInstance.constructor.staticMethod()); |
Be careful with this, because it's not a "true" singleton. It relies on the require cache for "singleton-ness", which isn't reliable.
For example, requiring the file above as require('./SingletonDefaultExportInstance') will result in a different instance of the module from require('./singletondefaultexportInstance') (assuming a case insensitive file-system).
@jasonkarns - so how do you export TRUE TRUE singleton?
Yes, would be good to discuss :) Also for others coming across this later.
IMHO, case insensitivity seems like it should be a bug with require's implementation if you're actually able to import a package that way.
it also fails as a singleton if you have two copies of the package, for example in a mono repo where packages can have their own node_modules
This is part of a series on Singletons, if you are looking for different ways of implementing it: https://medium.com/@dmnsgn/singleton-pattern-in-es6-d2d021d150ae
@codewithcheese You could work around the issue and store instances even more "global" and use globalThis (works on Node and Browser)
// a.js
export class A {
constructor(){
console.log('A constructor()')
}
static get instance() {
return (globalThis[Symbol.for(`PF_${A.name}`)] ||= new this());
}
}
// index.js
import { A } from './a.js';
console.log('A.instance', A.instance);
console.log('A.instance', A.instance);Or if you do not want to export A and just the single instance:
// a.js
class A { // <- no export here
// same code
}
const {instance} = A; // destruct `static get instance`
export {
instance // ... and export instance. (optional re-naming if you do not want to import something called "instance"
}
As a named export:
or if you want to export as the class' name: