在 webpack 或汇总模块捆绑过程中是不是保证保留单例?

Posted

技术标签:

【中文标题】在 webpack 或汇总模块捆绑过程中是不是保证保留单例?【英文标题】:Is singleton guaranteed to be preserved during webpack or rollup module bundling process?在 webpack 或汇总模块捆绑过程中是否保证保留单例? 【发布时间】:2018-09-09 04:16:59 【问题描述】:

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

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

// a.js (singleton module)
class A 

// Create singleton
export const a = new A();

现在我可以在其他模块的任何地方使用这个实例化对象:

// 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);

理论上,应该可以如上所述管理单例创建。但到今天为止,我们使用像 Webpack.jsRollup.js 这样的模块捆绑器来为浏览器提供 javascript。如果这些打包程序意外/有意地多次包含某个模块怎么办。我能想象的最简单的事情是,如果我有某种 symlinks 可以通过不同的路径解析到同一个模块。或者它可能只是模块解析过程中的一个错误。

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

有一个话题我还没有完全研究过。我知道 ES 符号 是全球唯一的,它们用于创建私有对象成员。那是我的下一个问题 - 符号的这种特性有没有办法帮助我创建一个真正的单例?(我相信如果捆绑过程不健全,符号也会遇到同样的问题。) p>

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

注意:我不是试图防范 Module bundler 中的错误。 Bug 类比只是一个比喻来说明这个想法。

【问题讨论】:

我确实知道,如果 Webpack 应用代码拆分,不同的块会有自己的上下文,并且不会保留单例。你可以通过引入一个公共块来解决这个问题:webpack.js.org/plugins/commons-chunk-plugin 【参考方案1】:

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

//singleton.js

let instance;

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


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

a === b // true

【讨论】:

以上是关于在 webpack 或汇总模块捆绑过程中是不是保证保留单例?的主要内容,如果未能解决你的问题,请参考以下文章

ts + webpack 捆绑节点找不到模块“路径”

Webpack

如何单独捆绑供应商脚本并根据需要使用 Webpack?

Webpack 捆绑许可证合规性?

使用 webpack [request] 魔术注释将动态模块捆绑在一起

是否可以使用webpack单独导入捆绑的webpack和库?