webpackwebpack-4webpack-splitchunks

Is there a way to use splitChunksPlugin in Webpack 4 to manually control which modules get placed into which output bundles?


I'm in kind of a unique situation where I need to break my bundle up into separate files but I don't have the luxury of having the total number of files or the names of those files changing over time as the app grows and new dependencies are installed, etc.

The following configuration is wrong, but I think it will illustrate best what I am trying to accomplish. I've read all through the docs but can't seem to find anything along these lines.

optimization: {
  splitChunks: {
    react: {
      test: /node_modules\/react/
    },
    vendor: {
      test: /node_modules\/(?!react)/
    },
    svgIcons: {
      test: /src\/js\/components\/icons/
    },
  }
}

The intent being that we would end up with the following 4 bundles:

react.bundle.js - Contains all react-related dependencies
vendor.bundle.js - Contains all other vendor files from node modules
svgIcons.bundle.js - Contains a group of app component files that match my test
bundle.js - The default bundle containing everything else.

Is there a way to do this?


Solution

  • After some more digging I eventually figured it out. Essentially, this is what you need:

    First of all, in the output object...

    output: {
      filename: "[name].js"
    }
    

    You need the [name] variable otherwise your bundles won't pick up the correct names.

    Next, in the optimization object...

    optimization: {
      splitChunks: {
        cacheGroups: {
          react: {
            chunks: 'initial',
            name: 'react',
            test: /node_modules\/react/,
            enforce: true,
          },
          vendor: {
            chunks: 'initial',
            name: 'vendor',
            test: /node_modules\/(?!react)/,
            enforce: true,
          },
          icons: {
            chunks: 'initial',
            name: 'icons',
            test: /src\/js\/components\/icons/,
            enforce: true,
          },
        },
      },
    },
    

    Results in the following bundles:

    react.js
    vendor.js
    icons.js
    bundle.js