I'm working on a webpack
configuration file and I feel like I'm either missing something basic or totally misunderstanding what I thought was the main feature of webpack
. I've got a very basic webpack.config.js
file that looks like this:
module.exports = {
"entry": {
"app": [
"./bundle.js"
]
},
"output": {
"filename": "bundle-[name].bundle.js",
"path": path.resolve(__dirname, "build"),
},
}
If I use this file, I get a bundle that is 18.8Mb. If I use webpack-bundle-analyzer
, I see huge amounts of duplication everywhere. In an effort to get it to combine all the common stuff together into a single additional bundle, I tried using the CommonsChunkPlugin
as follows:
module.exports = {
"entry": {
"app": [
"./bundle.js"
]
},
"output": {
"filename": "bundle-[name].bundle.js",
"path": path.resolve(__dirname, "build"),
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2,
})
]
}
With this, the bundle is still 18.8Mb, and a 5.79kb common bundle gets generated. No luck. Then I tried explicitly naming the bits I wanted to put in the common bundle with:
module.exports = {
"entry": {
"common": ["react", "react-dom", "mobx", "mobx-react", "three", "three-trackballcontrols"],
"app": [
"./bundle.js"
]
},
"output": {
"filename": "bundle-[name].bundle.js",
"path": path.resolve(__dirname, "build"),
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2,
})
]
}
Now I get two bundles, one that is 18Mb and another that is 2.95Mb (20.95Mb in total). So still not moving in the right direction. However, if I go through and try and spot the modules I think are being duplicated the most and define a resolution alias for them, e.g.,
module.exports = {
"entry": {
"app": [
"./bundle.js"
]
},
resolve: {
alias: {
"react": path.resolve(__dirname, "node_modules", "react"),
"react-dom": path.resolve(__dirname, "node_modules", "react-dom"),
"mobx": path.resolve(__dirname, "node_modules", "mobx"),
"mobx-react": path.resolve(__dirname, "node_modules", "mobx-react"),
"rxjs": path.resolve(__dirname, "node_modules", "rxjs"),
"three": path.resolve(__dirname, "node_modules", "three"),
...
}
},
"output": {
"filename": "bundle-[name].bundle.js",
"path": path.resolve(__dirname, "build"),
},
}
Now, I get a single bundle that is only 6.1Mb. Now I realize 6.1Mb is still pretty large (I'm not running the production optimizations with webpack
at this point), but it is 1/3 the size of the original bundle, so that is a huge win. But my disappointment is that I had to manually go through and figure out what the duplicated modules were. I thought part of the whole point of webpack
was that it would do this for me?
In general, things like react
are marked as peer dependencies in the various packages. But I know of at least one where three
is listed as a dependency (not a peer dependency). Could that be influencing all of this? If so, then the problem is that for that particular module I'm not sure it makes sense to mark three
as a peer dependency because one could not really predict whether it would make sense to add it as a dependency at the application level.
The bottom line is that I suspect I'm doing something wrong. I'd like to fix this "the right way" so that webpack
can do this automatically. But I'm not sure why it is insisting on duplicating these packages. I'm working with webpack
3.6.0, BTW.
Thanks for any suggestions.