Case against enabling `AutomaticCommonsChunksPlugin` in webpack by default
sjsyrek opened this issue · 8 comments
Is this a bug report?
No. This is a discussion of the changes recently introduced by the AutomaticCommonsChunksPlugin
webpack plugin, that is now enabled by default in CRA v2. The issue is that the vendor chunk produced for our application is approaching 100KB in size, which seems to defeat the purpose of using dynamic imports for code splitting.
Here are the chunks we get in CRA v2.0.0-next.66cc7a90 without the new plugin enabled:
File sizes after gzip:
73.97 KB (-55.31 KB) build/static/js/main.d1abdfcb.js
48.3 KB build/static/js/LandingPage.f0ddef0e.chunk.js
16.42 KB build/static/js/Calendar.e70e80b4.chunk.js
9.18 KB build/static/js/CarClassPage.cc65304c.chunk.js
2.35 KB build/static/js/NotFoundPage.40cd51b8.chunk.js
1.51 KB build/static/js/FullScreenModal.a1abcd70.chunk.js
1.15 KB (-5.37 KB) build/static/css/main.3287133e.css
482 B build/static/js/CityPage.f084c178.chunk.js
Here are the chunks we get in CRA v2.0.0-next.a671462c:
91.78 KB build/static/js/vendors.65bb2654.chunk.js
16.41 KB (-31.9 KB) build/static/js/LandingPage.60fe2b8b.chunk.js
8 KB (-65.97 KB) build/static/js/main.b62c6c3c.chunk.js
3.84 KB (-5.34 KB) build/static/js/CarClassPage.57a04e32.chunk.js
3.29 KB build/static/css/vendors.470d376f.chunk.css
2.06 KB build/static/css/LandingPage.c6f351b7.chunk.css
1.36 KB build/static/js/runtime~main.5afc2beb.js
1.1 KB (-417 B) build/static/js/FullScreenModal.a7d8d07f.chunk.js
1.09 KB (-63 B) build/static/css/main.5bd1cab6.chunk.css
1.09 KB build/static/css/CarClassPage.2ea1f4b6.chunk.css
466 B (-16 B) build/static/js/CityPage.67cf514e.chunk.js
444 B (-1.92 KB) build/static/js/NotFoundPage.a1daedf0.chunk.js
102 B build/static/css/FullScreenModal.e95a181c.chunk.css
Our concern is that the size of the vendor chunk will continue to grow as we add more third party components to our application, and with this plugin enabled by default, we will be unable to customize the code splitting effectively.
Proposed solutions
- Disable
AutomaticCommonsChunksPlugin
or make it opt-in - Use some kind of heuristic to produce more than one vendor chunk, for example by optionally generating a vendor chunk for each user-defined dynamic import that includes third party code
Related PRs/issues
According to documentation splitChunks
applies some kind of heuristic and based on it produce more than one vendor chunk https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366. In CRA it configured to always produce only one chunk I guess because of this:
create-react-app/packages/react-scripts/config/webpack.config.prod.js
Lines 161 to 164 in 52449c3
splitChunks.name
- When assigning equal names to different split chunks, all vendor modules are placed into a single shared chunk, though it's not recommend since it can result in more code downloaded.
Im not currently in any CRA releated project where I can test this and toy with chunking. But if I remember correctly you can configure webpack to work like this:
Vendors for chunk A, B & C => vendors-all.js
Vendors for Chunk A & B => vendors-A-and-B.js
Feel free to open a PR!
@andriijas Thanks for the response! The problem is that we can't configure webpack in CRA unless we eject. That's an option but not an attractive one unless it's really necessary.
Easiest way for you is to fiddle with cra in node_modules of your app and see if you can find any bug in the configuration, then copy solution to cloned cra src and submit PR with propsal for discussion. when done just remove your local node_modules and yarn/npm to reset.
Always producing a single vendor file should not be a default.
Even after doing code splitting still, vendor bundle will be having all code(vendor)
@andriijas It's not a bug, in this case. It's the expected behavior. The issue is that this behavior can be suboptimal in many scenarios, for example if the vendor bundle ends up being too large. It defeats the purpose of code splitting, which is why I am asking for more fine-grained control of this setting. The only fiddle with CRA we would do is switching off AutomaticCommonsChunksPlugin
. The difference in chunk sizes this plugin causes vs. not having it is shown above.
For reference: parcel-bundler/parcel#885
I'm not arguing against it - I had a hard time trying to figure out sane defaults when I made the webpack 4 pr. Just open a pr and argue for the case.