Understand Webpack4 using the Common Chunk strategy Webpack4 splitchunks

  • Initially, chunks (and internally imported modules) are associated through parent-child relationships in the internal WebPack graph. The CommonsChunkPlugin was used to avoid duplication of dependencies between them, but further optimization was not possible. Starting with WebPack V4, CommonsChunkPlugin has been removed and replaced with Optimization.splitchunks.

module.exports =  {
  mode: 'production'.entry: path.resolve(__dirname, '.. /src/entry1.js'),
  output: {
    path: path.resolve(__dirname, '.. /dist'),
    filename: '[name].[chunkhash:8].js'.chunkFilename: '[name].[chunkhash:8].chunk.js',},module: {
    rules: [{test: /.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'}},optimization: {
    splitChunks: {
        chunks: 'all'./ / split range: three models async (do not split the entry documents) | initial entry documents (only split) | all default async all files (split)
        minSize: 30000.// The minimum size (bytes) of chunk to be generated.
        minChunks: 1.// if a packet is referenced >= once, chunks will be split (default: minChunks=1).
        maxAsyncRequests: 5.// The maximum number of parallel requests inside the asynchronous module (non-entry module)
        maxInitialRequests: 3.// The maximum number of requests for parallel loading of import modules (import files split not more than 3 files, splitting too many modules leads to too many requests, which is not worth the loss)
        automaticNameDelimiter: '~'.// The separator of the generated name
    // name: true, // if chunk does not have a name, the name of the splitChunks should be an ID instead
      // name: 'split ', // can merge and rename split files
        cacheGroups: {
            vendors: {
            // minChunks: 1, // if a third-party packet is referred to >= once, the chunk will be split (minChunks=1 by default).
            test: /[\\/]node_modules[\\/]/.// Filter only modules imported from the node_modules folder
            priority: -10./ / weight
            },
            default: {
            minChunks: 2.// Local packages are referenced >=2 times, and the chunk modules are split, with less weight than vendors (vs priority)
            priority: -20.// Vendors reference packages first, and then find local packages, because the default weight is smaller than vendors
            reuseExistingChunk: true,}}},},plugins: [
    new CleanWebpackPlugin(['dist'] and {root: process.cwd()
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '.. /public/index.html')}),new BundleAnalyzerPlugin(),
  ]
}
Copy the code

Enable default async mode, single file entry

npm run default
Copy the code

Enable default async mode, multi-file entry

npm run entry2
Copy the code

Test maxInitialRequests

npm run maxInitialRequests
Copy the code

Test maxAsyncRequests

npm run maxAsyncRequests
Copy the code

The output

When the parent chunk and the child chunk introduce the same module?

  • When the parent chunk and the sub-chunk introduce the same module at the same time, the parent chunk’s module will not be separated. Instead, the module in the sub-chunk will be deleted and the parent chunk’s module will be retained. This is because optimization. RemoveAvaliableModules default is true

How does GM Vendors extract to a Vendor (specified)?

  • todo

By default cacheGroups, third-party packages are referenced> = 1The local package will be split, and the local package will be referenced> = 2Will be broken up,

cacheGroups: {
    vendors: {
        // minChunks: 1, // if a third-party packet is referred to >= once, the chunk will be split (minChunks=1 by default).
        test: /[\\/]node_modules[\\/]/.// Filter only modules imported from the node_modules folder
        priority: -10
    },
    default: {
        minChunks: 2.// Local packages are referenced >=2 times, and the chunk modules are split, with less weight than vendors (vs priority)
        priority: -20.// Vendors reference packages first, and then find local packages, because the default weight is smaller than vendors
        reuseExistingChunk: true  Vendors reference packages first, and then find local packages}}Copy the code

1. Package the file and rename it?

  • If the chunk does not have a name, the name of the splitChunks is replaced with an ID. Of course, you can also customize the name attribute

When assigning the same name to different split chunks, all vendor modules are placed in a shared chunk, although this is not recommended as it may result in more code being downloaded.

splitChunks.usedExports

optimization: {
    splitChunks: {... - name:true.// If the chunk does not have a name, the name of the splitChunks should be an ID instead. You can also specify the name attribute ~~
      + name: 'Split out'.// You can merge and rename split files
        cacheGroups: {
            vendors: {... },default: {... }}}},Copy the code

2. How can VENDORS extract into an entry, VENDORS ~ XXX.chunk. js?

  • MaxAsyncRequests: 5, // maxInitialRequests () within asynchronous modules (non-entry modules) : 3, // The maximum number of requests for the parallel loading of the entry module (the entry file split is not more than 3 files, splitting too many modules leads to too many requests, which is not worth the loss)Copy the code
splitChunks: {
      // chunks can have three values: async,initial,all; Decide whether to split the code if it meets the criteria.
      // Initial indicates that only non-import () asynchronous imported code is split, async indicates that only asynchronous code blocks are split, and all indicates that both asynchrons are split.
      chunks: 'async'.// Only when the size is satisfied
      // For example, if the import dependency package is smaller than 30KB, the code block will not be split
      minSize: 30000.// When the bundle reaches maxSize, it must be split
      // For example, jquery and LoDash are combined to 140KB and maxSize is set to 80KB
      maxSize: 0.// The minimum number of chunks to be referenced
      // For example, if an entry block and an asynchronous block both reference Lodash, new chunks will not be added for Lodash if minChunks are larger than 2
      minChunks: 1.// The maximum number of times an asynchronous code block can be split
      // Suppose an import() module is 2MB and maxSize is set to 500KB. If this attribute is set to 1, the module can split at most one bundle.
      maxAsyncRequests: 5.// This property is identical to maxAsyncRequests but works with initial
      maxInitialRequests: 3.// The bundle automatically names the connection character used
      automaticNameDelimiter: '~'.// The length of the bundle name is limited when the bundle is automatically named
      automaticNameMaxLength: 30.// The value can be bool or string. If true, the default name is used; otherwise, the ordinal name is used. String Specifies the file name
      name: true.// Customize grouping
      cacheGroups: {
      
        // Each attribute is a grouping
        vendors: {
        
          // Import the path's re match, which is the module code referenced by all node_modules
          test: /[\\/]node_modules[\\/]/.// The priority defaults to 0. If two groups reference the same module, the group with the higher priority gets the module
          priority: -10
          
        },
        default: {
          minChunks: 2.priority: -20.// Whether to reuse existing modules in other chunks
          // The default value is false, which indicates that the module is split to be used by both parties
          reuseExistingChunk: true}}}Copy the code

Some hints

  • The default configuration works well in most scenarios
  • Webpack’s Externals are better suited for moving third-party libraries onto CDN
  • The test matching rule can also be a method, with more flexible grouping

More on this

webpack 4: Code separation, block diagram and optimization plugin splitChunks choose not clear for splitChunks add maxSize splitChunks. What’s the use of maxAsyncRequest reuseExistingChunk examples of use