Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is dependency repeated many times in Webpack artifact?

I have a multi-entry point webpack build and I am working on optimizing artifact size for production. webpack-bundle-analyzer produced the following picture:

enter image description here

It's obvious that the AtlasKit dependencies make up a huge chunk of the total artifact size. Specifically, I see that styled-components.es.js is repeated many times. More so, this same dependency is is also present in vendor.js which itself is shared among all other packages.

Can anyone explain why styled-components.es.js is repeated all over and why it cannot be shared via single dependency in vendor.js? Is there anything I can do to remove duplicates and only depend on the single styled-components.es.js dependency in vendor.js?

I found it a bit strange that AtlasKit dependencies have a nested node_modules folder that is included in the package. Why is dist not enough? Maybe that's part of the reason why styled-components.es.js cannot be shared via vendor.js?

enter image description here

I tried to exclude the dependency manually via webpack's IgnorePlugin (similar to moment.js locales) but failed so far to do so.

Any insights would be greatly appreciated. Thanks!

like image 838
Tobi Avatar asked Sep 15 '17 01:09

Tobi


2 Answers

It sounds like you want to consolidate a dependency from multiple chunks into a common chunk: For this I would recommend looking into webpack.CommonsChunkPlugin.

Of particular interest is the minChunks property you can pass to the plugin:

minChunks: number|Infinity|function(module, count) -> boolean, // The minimum number of chunks which need to contain a module before it's moved into the commons chunk. // The number must be greater than or equal 2 and lower than or equal to the number of chunks. // Passing Infinity just creates the commons chunk, but moves no modules into it. // By providing a function you can add custom logic. (Defaults to the number of chunks)

I advise trying to add this plugin to your Webpack config:

new webpack.optimize.CommonsChunkPlugin({
  children: true,
  async: true,
  minChunks: 3
})

This usage is described further in "Extra async commons chunk".

If you are interested in seeing the amount of code shared between your chunks, consider trying samccone/bundle-buddy for Webpack as well.

If you are already using CommonsChunkPlugin, I would need to see your Webpack config to provide further information.

like image 167
Peter Avatar answered Oct 14 '22 07:10

Peter


While I don't know exactly what fixed the issue, I just noticed that the latest release of Atlaskit now works with tree-shaking. I now get minimal artifacts with everything shared from Atlaskit in a big vendor.js.

enter image description here

like image 37
Tobi Avatar answered Oct 14 '22 07:10

Tobi