如何使用 webpack 在块之间共享单例实例?
How to share singletons instances between chunks with webpack?
我在使用 Webpack 4 时遇到问题,尝试使用异步块预加载一些数据,然后在加载数据时,将另一个使用 webpack 计算的块附加到 dom。
两个块使用同一个实例,一个单例,一次作为容器加载数据,另一次读取那些加载的数据。
我希望它尽可能清楚。它与 Webpack 3 一起工作,可能是我们有超过 6 个月的运气,但我们今天迁移到 webpack 4,并且症状很明显:
- 在第一个块中,在加载数据时,创建并填充了实例。在这种情况下尝试使用数据时,似乎没问题。
- 在第二个块中,之后加载,实例不存在,或者没有填充。
我遇到了同样的问题并通过添加解决了它:
optimization: {
runtimeChunk: {
name: 'commons' // <-- THIS
},
...
}
到webpack配置。
我将对问题和答案进行一些扩展。
这是问题所在:
假设您使用 Webpack 将代码分成两个块(我们称它们为 a.bundle.js
和 b.bundle.js
),并且您从 Web 浏览器中分别加载每个块。让我们进一步假设您有 class 在 a.bundle.js
中调用了 MySingleton
,它有一个静态数据成员。问题是每个块都会看到该静态数据成员的不同版本,因为它会有效地为每个包创建一个新的 class。它实际上就像它在 bundle A 中创建了一个 MySingleton1
class,在 bundle B 中创建了一个单独的 MySingleton2
class,并且两者完全独立运行。
解决方法(扩展):
Ed_le_fou 的答案是正确的——您需要将优化/runtimeChunk 添加到您的 webpack。
执行此操作后,将生成一个名为 commons.bundle.js
的新文件(名称可能因您的配置而异)。然后,您需要在 a.bundle.js
或 b.bundle.js
之前的页面中包含这个新的公共文件,以便单例正常工作。
如此有效,您最终会得到这样的结果:
<script type="text/javascript" src="/commons.bundle.js"></script>
<script type="text/javascript" src="/a.bundle.js"></script>
<script type="text/javascript" src="/b.bundle.js"></script>
我在使用 Webpack 4 时遇到问题,尝试使用异步块预加载一些数据,然后在加载数据时,将另一个使用 webpack 计算的块附加到 dom。
两个块使用同一个实例,一个单例,一次作为容器加载数据,另一次读取那些加载的数据。
我希望它尽可能清楚。它与 Webpack 3 一起工作,可能是我们有超过 6 个月的运气,但我们今天迁移到 webpack 4,并且症状很明显:
- 在第一个块中,在加载数据时,创建并填充了实例。在这种情况下尝试使用数据时,似乎没问题。
- 在第二个块中,之后加载,实例不存在,或者没有填充。
我遇到了同样的问题并通过添加解决了它:
optimization: {
runtimeChunk: {
name: 'commons' // <-- THIS
},
...
}
到webpack配置。
我将对问题和答案进行一些扩展。
这是问题所在:
假设您使用 Webpack 将代码分成两个块(我们称它们为 a.bundle.js
和 b.bundle.js
),并且您从 Web 浏览器中分别加载每个块。让我们进一步假设您有 class 在 a.bundle.js
中调用了 MySingleton
,它有一个静态数据成员。问题是每个块都会看到该静态数据成员的不同版本,因为它会有效地为每个包创建一个新的 class。它实际上就像它在 bundle A 中创建了一个 MySingleton1
class,在 bundle B 中创建了一个单独的 MySingleton2
class,并且两者完全独立运行。
解决方法(扩展):
Ed_le_fou 的答案是正确的——您需要将优化/runtimeChunk 添加到您的 webpack。
执行此操作后,将生成一个名为 commons.bundle.js
的新文件(名称可能因您的配置而异)。然后,您需要在 a.bundle.js
或 b.bundle.js
之前的页面中包含这个新的公共文件,以便单例正常工作。
如此有效,您最终会得到这样的结果:
<script type="text/javascript" src="/commons.bundle.js"></script>
<script type="text/javascript" src="/a.bundle.js"></script>
<script type="text/javascript" src="/b.bundle.js"></script>