First, let’s walk through how Gatsby generates the JavaScript runtime that performs rehydration after the initial HTML is loaded, and all client-side work thereafter (such as the instantaneous loading of subsequent pages). There are several files involved in the process.
The entry point is the build-javascript.ts file in Gatsby (located in the src/commands directory), which dynamically generates a Webpack configuration by invoking src/utils/webpack.config.js. Depending on which stage is being handled (build-javascript
, build-html
, develop
, or develop-html
), this can result in significantly different configurations. For example, consider the Webpack configuration generated for the build-javascript
stage, reproduced here with comments:
{
entry: {
app: `.cache/production-app`
},
output: {
// e.g. app-2e49587d85e03a033f58.js
filename: `[name]-[contenthash].js`,
// e.g. component---src-blog-2-js-cebc3ae7596cbb5b0951.js
chunkFilename: `[name]-[contenthash].js`,
path: `/public`,
publicPath: `/`
},
target: `web`,
devtool: `source-map`,
mode: `production`,
node: {
___filename: true
},
optimization: {
runtimeChunk: {
// e.g. webpack-runtime-e402cdceeae5fad2aa61.js
name: `webpack-runtime`
},
splitChunks: {
chunks: `all`,
cacheGroups: {
// disable webpack's default cacheGroup
default: false,
// disable webpack's default vendor cacheGroup
vendors: false,
// Create a framework bundle that contains React libraries
// They hardly change so we bundle them together
framework: {},
// Big modules that are over 160kb are moved to their own file to
// optimize browser parsing & execution
lib: {},
// All libraries that are used on all pages are moved into a common
// chunk
commons: {},
// When a module is used more than once we create a shared bundle to
// save user's bandwidth
shared: {},
// All CSS is bundled into one stylesheet
styles: {}
},
// Keep maximum initial requests to 25
maxInitialRequests: 25,
// A chunk should be at least 20kb before using splitChunks
minSize: 20000
},
minimizers: [
plugins.minifyJs(),
plugins.minifyCss(),
]
}
plugins: [
// A custom webpack plugin that implements logic to write out
// chunk-map.json and webpack.stats.json
plugins.extractStats(),
]
}
The splitChunks
portion of this Webpack configuration, which removes loaders, rules, and other output, is the most important part, because it contributes to how code splitting occurs in Gatsby and how the most optimized bundle is generated. Gatsby tries to create generated JavaScript files that are as granular as possible (“granular chunks”) by deduplicating all modules. Once Webpack is finished compiling the bundle, it ends up with a few different bundles, which are accounted for in Table 14-4.
Filename | Description |
---|---|
app-[contenthash].js | This bundle is produced from production-app.js and is configured in webpack.config.js. |
webpack-runtime-[contenthash].js | This bundle contains webpack-runtime as a separate bundle (configured in the optimization section) and is usually required with the app bundle. |
framework-[contenthash].js | This bundle contains React and as a separate bundle improves cache hit rate, because the React library is seldom updated as frequently. |
commons-[contenthash].js | Libraries used on every Gatsby page are bundled into this file so that they are downloaded only once. |
component—[name]-[contenthash].js | This represents a separate bundle for each page to enable code splitting. |
Leave a Reply