是否可以确保在webpack或汇总模块捆绑过程中保留单例?

Har*_*til 7 javascript singleton web-frontend webpack rollupjs

了解单例会创建共享的全局状态这一事实,在某些情况下我可能想要单例,例如redux存储/状态对象。

如果使用的是ES模块,则可以使用以下简单代码创建单例:

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

// Create singleton
export const a = new A();
Run Code Online (Sandbox Code Playgroud)

现在,我可以在另一个模块的任何地方使用此实例化的对象:

// 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);
Run Code Online (Sandbox Code Playgroud)

从理论上讲,如上所述,应该有可能管理单例创建。但是从今天开始,我们使用诸如Webpack.jsRollup.js之类的模块捆绑器来向浏览器提供JavaScript。如果这些捆绑器意外/有意地多次包含某个模块,该怎么办。我能想到的最简单的事情是,如果我有某种符号链接可以通过不同的路径解析为同一模块。或者它可能只是模块解析过程中的一个错误。

我的问题是- 这些模块捆绑程序是否始终确保创建单例对象的模块在任何情况下都保持单例状态?

我没有完全研究一个主题。我知道ES符号在全球范围内是唯一的,它们用于创建私有对象成员。这是我的下一个问题- 符号的这种特性是否可以帮助我创建真正的单例?(我认为如果捆绑过程不健全,符号也会遭受同样的问题。)

最后,最后一个问题:是否有可能在JavaScript中可靠地创建真正的单例?

注意:我不是要防范Module bundler中的错误。错误类比只是说明这一想法的一种表象。

Isi*_*osa 0

我经常在汇总中使用该模式,并且从未遇到过问题。或者你可以像这样定义一个单例:

//singleton.js

let instance;

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

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

a === b // true
Run Code Online (Sandbox Code Playgroud)