How to code split one of two entries in Webpack 4?
Asked Answered
S

2

4

I’ve got a seemingly pretty straightforward Webpack code splitting setup that I’m having trouble migrating to Webpack 4. I have two entries, called main and preview. I want to do an initial code split into a vendor chunk for the vendor modules in main, but I want to keep preview as a single chunk.

Relevant part of the working configuration in Webpack 3:

{
  entry: {
    main: './src/application.js',
    preview: './src/preview.js',
  },
  plugins: [{
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      chunks: ['main'],
      minChunks({context}) {
        if (!context) {
          return false;
        }
        const isNodeModule = context.indexOf('node_modules') !== -1;
        return isNodeModule;
      },
    }),
  }]
}

Specifically, using the chunks property in the CommonsChunkPlugin options allows me to do what I need to do easily. Is there an equivalent in Webpack 4’s optimization.splitChunks configuration?

Spiky answered 15/3, 2018 at 11:49 Comment(0)
C
7

The following Webpack 4 config only splits main module vendor dependencies into a separate chunk. Other dependencies for preview remains within that chunk.

{
    entry: {
        main: './test/application.js',
        preview: './test/preview.js'
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendors: {
                    name: 'vendors',
                    chunks: 'all',
                    enforce: true,
                    priority: 1,
                    test(module, chunks) {
                        const name = module.nameForCondition && module.nameForCondition();
                        return chunks.some(chunk => chunk.name === 'main' && /node_modules/.test(name));
                    }
                }
            }
        }
    }
}

Shared dependencies are included in the vendors bundle unless we configure the preview cacheGroup with higher priority to enforce that all dependencies included here should remain inside this chunk.

For more Webpack 4 related info/config you can review this webpack-demo project.


In order to enforce splitting all vendors dependencies from main and reuse them from main and preview chunks you must configure the preview cacheGroup as:

preview: {
    name: 'preview',
    chunks: 'all',
    enforce: true,
    priority: 0,
    test(module, chunks) {
        return chunks.some(chunk => chunk.name === 'preview');
    }
}

Note that the cacheGroup for preview chunk has lower priority than the vendors one to ensures that all main dependencies which are also dependencies in preview are also referenced from the preview bundle.

Casavant answered 18/3, 2018 at 5:59 Comment(2)
Thank you! My goal is for the preview bundle to totally self-contained, so it sounds like I will need to configure a higher-priority cacheGroup for it. However, I’d still like for dependencies used in both preview and main to be split into the vendor chunk for main’s purposes. Is that possible?Spiky
Your'e welcome. In order to move all dependencies from main (including the shared ones with preview) you need to add the cacheGroup config for preview with lower priority to avoids this chunk to be splitted but also re-use shared dependencies (references dependencies already extracted from main to vendors). Hope this helps!Casavant
N
3

Or:

splitChunks: {
  cacheGroups: {
    vendors: {
      test: /[\\/]node_modules[\\/]/,
      name: "vendors",
      // Exclude preview dependencies going into vendors.
      chunks: chunk => chunk.name !== "preview"
    },
  },
},

Please read the documentation of chunks for more details.

Neilson answered 6/7, 2018 at 15:32 Comment(1)
For future readers: Notice that each entry itself is a chunk. And this answer is what I'm using, since more elegant.Derna

© 2022 - 2024 — McMap. All rights reserved.