5

I'm having trouble with Webpack 4, trying to preload some data with an async chunk, then when data is loaded, append an other chunk computed with webpack to the dom.

Both chunks use the same instance, a Singleton, once as a container while loading data, the other time to read those loaded datas.

I hope it's as clear as possible. It was working with Webpack 3, might be some luck we had for over 6 months, but we migrated to webpack 4 today, and the symptom is quite clear :

  • in the first chunk, while loading datas, the instance is created and populated. When trying to use the datas in this context, it seems ok.
  • in the second chunk, loading afterwards, the instance does not exist, or is not populated.

2 Answers2

3

I had the same problem and fixed it by adding:

optimization: {
  runtimeChunk: {
    name: 'commons' // <-- THIS
  },
  ...
}

to the webpack configuration.

github issue

Ed_le_fou
  • 147
  • 5
3

I'm going to expand a bit on both the question and the answer.

Here's the issue:

Let's assume you use Webpack to split your code into two chunks (let's call them a.bundle.js and b.bundle.js) and that you load each of these individually from your web browser. Let's further assume you have class called MySingleton in a.bundle.js that has a static data member. The issue is that each chunk will see a different version of that static data member, because it will effectively create a new class for each bundle. It's effectively like it creates a MySingleton1 class inside bundle A and a separate MySingleton2 class inside bundle B, and the two operate entirely independently.

Here's the solution (expanded upon):

Ed_le_fou's answer is correct -- you need to add optimization / runtimeChunk to your webpack.

Once you do that, it will result in a new file called commons.bundle.js (the name may vary depending on your configuration). You then need to include this new common file in the page prior to either a.bundle.js or b.bundle.js in order for singletons to work correctly.

So effectively you'll end up with something like this:

<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>
DashFwd2
  • 101
  • 3