Code Splitting is a technique used to divide your app into more smaller files.
By default webpack create a new bundle file for every entry chunk and async chunk, to avoid duplicated dependencies across them and for other kinds of optimizations webpack comes with SplitChunksPlugin with some configuration pre-set out of the box.
SplitChunksPlugin allow to split your code into more files without having to do it by yourself. This is useful to improve performance of the app, the browser will cache your app files instead of re-downloading them every time an user visit the website.
Out of the box SplitChunksPlugin only split chunks based on its default configuration.
After you run npm run dev
, the bundle main.js (also called entry chunk) contains the webpack runtime plus codes from entry point index.js.
Inside index.js there are some dynamic imports:
import("react"); // -> vendors-node_modules_react_index_js.js
import("./a"); // -> src_a_js.js
import("./b"); // -> src_b_js.js
Dynamic Import is a webpack specific sytnax used to tell webpack to create separate files for those modules (also called async chunks).
Note that small-component.js is inside both src_a_js.js and dev/src_b_js.js because it's smaller then 20kb, as per default SplitChunksPlugin configuration.
Because react
it's a vendor dependency from node_modules it's extracted in a separate file called vendors-node_modules_react_index_js.js.
If you import a file that weight more then 20kb it'll be splitted into a separate file. Inside a.js and b.js change the import satements to include the large file import "large-component.js"
insdead of the small one.
Try to change all dynamic imports to regular import statements and run the build: everything will be included inside main.js bundle.
If you want to split all chunks types set optimization.splitChunks.chunks: 'all'
.
To have more control over code splitting you can use cacheGroups option.
If you're changing the configuration, you should measure the impact of your changes to ensure there's a real benefit.
If you want to give a specific name to an async chunk, you can use webpackChunkName
as comment inside dynamic import, this will cause the files to be named [name].js
instead of just [id].js
:
// The output file will be named react.js
import(/* webpackChunkName: 'react' */ 'react');
Webpack 5 will automatically assign useful file names in development mode even when not using webpackChunkName.