BlogCode

How to name a webpack chunk (including split and common chunks)

Written by Codemzy on March 30th, 2022

Naming your Webpack chunks helps you understand the contents of each bundle of code, and keep consistency between deploys. In this post, we look at named outputs, including dynamic imports, split chunks, and common chunks.

I recently wrote about code splitting with Webpack and using the SplitChunksPlugin. In that blog post, I touched upon how Webpack might create chunks based on common files that are shared between other chunks.

Let's say your app has two features.

  1. Feature A
  2. Feature B

And you've used code splitting to reduce your bundle size, and now expect to have three bundles.

  • app.js
  • feature-a.bundle.js
  • feature-b.bundle.js

But if a few of your components are shared between these bundles, this code will be duplicated. To keep your bundles small, you can use the SplitChunksPlugin to split out these common bundles rather than duplicating your code.

These shared bundles might get random names or numbers given to them, like 981.bundle.js.

And that's all ok, but when you make changes, those names might change. The code could disappear. And your users could end up with a ChunkLoadError.

If you just want to know how to name these common chunk bundles, scroll down to "Naming common chunks".

Naming your entry file

Naming your entry file, like app.js in Webpack is fairly simple, using a webpack.config.js file.

const path = require('path');

module.exports = {
  entry: './src/app.js',
  output: {
    filename: 'app.bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
 };

The above configuration would give you an output bundle called app.bundle.js. And that works great. Until your Webpack bundle gets too big. Then you need to split up your code into smaller chunks (known as code splitting).

You can add multiple entry points if you need to, give the entry points names, and provide a [name] output pattern to generate the name. Here's the set-up to do this in webpack.config.js straight from the Webpack docs.

const path = require('path');

module.exports = {
  entry: {
    app: './src/app.js',
    print: './src/print.js',
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
 };

Now you get two output bundles called app.bundle.js and print.bundle.js.

But this is all very manual. And only applies to entry points. What if app.bundle.js was getting big, and you want to split that up into multiple bundles? With dynamic code splitting, you can stick with one entry point and split the rest of the code inside your app. But how do you name those bundles?

Naming your dynamic split chunks

You can use dynamic imports in your code to tell Webpack to split the imported code into a separate chunk.

I'm not going to go into great detail about code splitting, because this post is about naming your chunks rather than creating them. If you want to learn more about code splitting and how to do it, check out How to reduce your ReactJS bundle size with Webpack code splitting.

As a basic guide, your imports would go from this:

import { featureA } from './featureA';

To this:

import("./featureA").then(result => {
  // do something
});

Or you might use a feature of the framework you are using. For example, if you are using ReactJS, you might use React.lazy().

const FeatureA = React.lazy(() => import('./FeatureA'));

But these chunks have no name!

To name these dynamic chunks, you can add a pattern to output.chunkFilename in webpack.config.js.

output: {
  filename: '[name].bundle.js',
  chunkFilename: '[name].chunk.bundle.js',
  path: path.resolve(__dirname, 'dist'),
},

And pass a webpackChunkName comment to Webpack with your import.

import(/* webpackChunkName: "featureA" */ './featureA')

Now Webpack knows what to name your chunks, and you can better understand what each bundle of code represents.

You might also want to use a [contenthash] in the file name for cache-busting reasons!

Naming your common chunks

Remember at the start of this blog post how we discussed that Webpack might split your code even further?

Before Webpack 4, there was a CommonsChunkPlugin that would automatically name these "common" chunks with the names of the chunks they are used by.

Let's say your code was used in both feature A a and feature B b chunks. Your common chunk would be called a-b. If you also had a feature C c and some code across all three features, you would get another chunk named a-b-c.

I found this naming pattern pretty useful because I could know where the chunks were being used in my application.

But in Webpack 4 and up, this naming pattern stopped happening with the new SplitChunksPlugin. But you can get it back!

You just need to add a name function to the settings, which you can include in your webpack.config.js under optimization.

// ...
  optimization: {
    splitChunks: {
      name: (module, chunks, cacheGroupKey) => {
        const allChunksNames = chunks.map((chunk) => chunk.name).join('-');
        return allChunksNames;
      },
    },
  },
};

Naming your vendor chunks

You're probably not just bundling up your code in Webpack, but other people's codes too. Maybe a framework like ReactJS, or a utility library like Lodash.

If your separate out these modules to improve browser caching and minimise the impact of future updates, it's helpful to name these code chunks too.

I covered more about why you would separate frameworks like ReactJS in my last blog post how to reduce your ReactJS bundle size with Webpack code splitting.

To name these chunks, you can use optimization.splitChunks again, but this time, cacheGroups.

optimization: {
  splitChunks: {
    // ...
    cacheGroups: {
      reactVendor: {
        test: /[\\/]node_modules[\\/](react|react-dom|react-router-dom)[\\/]/,
        name: 'vendor-react',
        chunks: 'all',
      },
      corejsVendor: {
        test: /[\\/]node_modules[\\/](core-js)[\\/]/,
        name: 'vendor-corejs',
        chunks: 'all',
      },
    },
  },
},

You create a group, tell it what to include with some Regex in test, and give it a name e.g. vendor-react.


And that's how you can name your Webpack chunks, whether they are dynamically imported, or created by Webpack on-demand as common bundles.

You can learn more about code splitting and how to minimise your ReactJS bundles in How to reduce your ReactJS bundle size with Webpack code splitting.