我试图从3升级到Webpack 4,并且遇到共享捆绑关闭的问题。
我的网址设置为创建shared.js
文件,在a.js
和b.js
之间共享我的代码。特别是,在shared.js
包中,有一个带有store
变量的索引文件。我们只导出一个名为getStore()
的函数,它返回store
。 getStore
的{{1}}号调用发生在a.js
和b.js
个文件的不同位置。
我们页面上的脚本阵容如下所示:
/** some html **/
<script src=""/scripts/shared.js""></script>
<script src=""/scripts/a.js""></script>
<script src=""/scripts/b.js""></script>
在Webpack 3中,第一次从getStore()
调用shared.js
(即将来电)中的a.js
代码时,会创建store
的实例然后从store
调用中调用返回getStore()
。随后从getStore()
调用a.js
,它不再创建store
的实例,而是从getStore()
返回相同的值。然后在a.js
完成并b.js
运行后,当b.js
调用getStore()
时,它不会实例化store
,而是使用与a.js
相同的实例用过的。在这种情况下,store
与[{1}}和a.js
之间的实例相同。
但是在Webpack 4中,行为有所不同。当b.js
调用a.js
中的代码时,当代码首次引用shared.js
时,与之前类似,它将创建getStore()
的新实例,而store
运行并调用a.js
它返回相同的实例。但是,当getStore()
初始引用b.js
代码时,它不会使用相同的shared.js
实例,而是会在a.js
内创建store
的新实例。 {1}}脚本运行,在调用b.js
时引用第二个store
。在这种情况下,有两个getStore()
个实例,每个实例对store
和a.js
都是唯一的。
不确定Webpack 4中导致此问题的不同之处。我们在Webpack 3中使用b.js
切换,现在使用内置的优化设置。以下是它们的配置方式。
WEBPACK 3:
CommonChunksPlugin
WEBPACK 4:
plugins: [..., new webpack.optimize.CommonsChunkPlugin({
name: 'shared',
filename: '[name].js',
minChunks: 2
})]
两个Webpack配置都吐出大致相同大小的文件,在调试和查看调用堆栈时,optimization: {
splitChunks: {
cacheGroups: {
shared: {
name: 'shared',
chunks: 'initial',
minChunks: 2
}
}
}
}
的调用来自相应的a / b.js文件。
是否有解释为什么getStore()
和a.js
获取Webpack 4中b.js
shared.js
对象的单独实例与获取与Webpack 3中相同实例的实例?当脚本相互依赖时,它们的闭包/作用域应如何处理共享代码?
答案 0 :(得分:1)
Idk,如果您知道的话,但我想分享我的发现。
TL; DR:拆分块在每个调用它的库的公共块中实例化该模块的新实例。
从乞求开始,您的webpack库应具有以下功能。
var r = n(34);
这将在该库中调用一个检索模块的方法:
function n(t) {
if (n[t])
return n[t].exports;
var e = n[t] = {
i: t,
l: !1,
exports: {}
};
return s[t].call(e.exports, e, e.exports, o),
e.l = !0,
e.exports
}
我找不到任何文档,但是t
是用于引用模块的数字(请记住)。 s
是包含库可以使用的所有模块的对象,而n
是包含所有库已使用的模块的对象。 >基本上是将它们缓存。当n[t]
不存在时,webpack将一个通用对象添加到n
中,并调用return s[t].call(e.exports, e, e.exports, o)
。
假设t
是34,webpack会调用以下方法
34: function(e, t, n) {
"use strict";
n.r(t);
var r = n(36);
t.default = function() {
var e = r.a.pageLevelOOM && r.a.adinfoOOMHeader
, t = r.a.pageLevelOOM && r.a.serverOOMHeader;
return r.a.adinfoOverride ? e : t
}
},
快速注释,常见的块将添加到webpackJsonp
下的窗口中。如果在浏览器的控制台中输入window.webpackJsonp[0][1]
,将会看到一个具有数字键且值是函数的对象。
这里的关键部分是,webpack基本上像这样在公共块中实例化每个模块。因此,每个库都将在通用块中拥有自己的模块版本。