This article is about 1500 words. It takes about 10 minutes to read it and 1 hour to try it out. Please correct any mistakes.

The original

Webpack4 has been around for two months, and everyone, including me, is still trying to figure out how to use splitChunk. I have also seen a lot of other people’s configuration demo, all feel not satisfied or did not get a good solution, the issue below the question also few people reply, can only operate by themselves, by the way, if you have better, welcome to leave the address in the comment area.

Commonly used parameters

  • MinSize (default: 30000) : The minimum size to form a new block of code
  • MinChunks (default: 1) : The minimum number of times this code block should be referred to before it is split
  • MaxInitialRequests (default: 3) : Maximum number of parallel requests for an entry
  • MaxAsyncRequests (default: 5) : Maximum number of concurrent quests for on-demand loads.
  • Chunks (async by default) : Initial, async, and all
  • Test: Controls which modules are matched by the cache group. If passed untouched, it selects all modules by default. Value types that can be passed: RegExp, String, and Function
  • Name (name of the packaged chunks) : string or function (the function can customize the name based on the condition)
  • Priority: indicates the priority of the cache group packaging.

If you’re still unfamiliar with these configurations, scroll through the documentation

The body of the

Overview of all the configuration, and then run the common requirements according to the demo.

optimization: {
  splitChunks: {
     chunks: "async", // Must choose one of the three:"initial" | "all"| (recommended)"async"MaxAsyncRequests: maxAsyncRequests: maxAsyncRequests: maxAsyncRequests: 5, maxInitialRequests: 3, maxInitialRequests: 3, automaticNameDelimiter:'~',// pack the name delimiter:function(){}, // The packaged name, which this option acceptsfunctionVendor :{// key is the name of the entry defined in the entry name: chunks:"initial", // Must choose one of the three:"initial" | "all" | "async"(Default is async)test: / react | lodash /, / / verify the regular rules, if conform to extract the chunk name:"vendor"// Chunk name to be cached minSize: 30000, minChunks: 1, enforce:trueMaxAsyncRequests: 5, maxAsyncRequests: 5, // maxInitialRequests: 3, reuseExistingChunk:true// You can set whether to reuse the chunk}}}},Copy the code

Let’s look at the first example

	entry: {
		pageA: "./pageA"Utility1.js utility2.js pageB:"./pageB"Utility2.js utility3.js pageC:"./pageC"Utility3.js}, optimization: {splitChunks: {cacheGroups: {Commons: {chunks:"initial",
					minChunks: 2,
					maxInitialRequests: 5, // The default limit is too small to showcase the effect
					minSize: 0 // This is example is too small to create commons chunks
				}
			}
		}
	},
Copy the code

Utility2. Js Commons ~pageB~ pagec.js Utility1. Js = utility1 and utility1 = utility1. Js = utility1 and utility1 = utility1 If utility1.js is used twice, it will create a new chunk instead of merging it into Commons ~pageB~ pagec.js.

mpageA.js pageB.js pageC.js

There’s a place is the need to optimize, is pageA. Js pageB. Js pageC. Js code is not much, but I came out of the bag is very big, must have been some webpack run file, plus runtimeChunk directly

    runtimeChunk: "single"// Equivalent to runtimeChunk: {name:"manifest"
    }
Copy the code

It’s all right now

Reference third-party module pageA reference vue.js pageB reference react react-dom

    vendor: {
		test: /node_modules/,
		chunks: "initial",
		name: "vendor",
		priority: 10,
		enforce: true
	}
Copy the code

However, in this case, all libraries of pageA pageB pageC are packaged together in vendor.js

What if I want to split this vendor.js into pagea-vendor. js pageb-vendor. js? I tried for a long time to find the easiest way to remove the manual vendor and let the plugin handle it automatically.

splitChunks: {
      chunks: "all",
      cacheGroups: {
				commons: {
					chunks: "initial",
					minChunks: 2,
					maxInitialRequests: 5, // The default limit is too small to showcase the effect
					minSize: 0 // This is example is too small to create commons chunks
				}
			}
		},
Copy the code

After I changed webPack mode to Production, I found that it didn’t work. The same configuration in production mode was a little weird. Vvendor – pageb. js was merged into pageb. js.

Later I toss about for a long time also analysis can not come out why, oneself toss out a way, or Lao Tze manual come, automation side go

        commons: {
          chunks: "initial",
          minChunks: 2,
          maxInitialRequests: 5, // The default limit is too small to showcase the effect
          minSize: 0 // This is example is too small to create commons chunks
	},
        'vendor-pageA': {
          test: /vue/, // direct usetestTo do path matching chunks:"initial",
          name: "vendor-pageA",
          enforce: true,},'vendor-pageB': {
          test: /react/, // direct usetestTo do path matching chunks:"initial",
          name: "vendor-pageB",
          enforce: true,},Copy the code

I managed to wrap up what I wanted.

Dynamic introduction

In this case, splitChunk should be able to automatically handle async, child, and other async situations in commonChunk. In this case, splitChunk should be able to automatically handle async and child situations in commonChunk.

import(/* webpackChunkName: "common-async.js"* /"./common-async").then(common => {
  console.log(common);
})
Copy the code

Not bad. It’s packed out

At this point, try introducing the common code F.js in the common-async.js and see if it can be repackaged

The F.JS was successfully removed and the other documents were not repackaged. It was good.

Places to note

  • The e splitChunks configuration item is inherited and overwritten by cacheGroups, but test, priorty, and reuseExistingChunk can only be used to configure cacheGroups.
  • It is best to include chunks for each item in the cacheGroups argument, otherwise you may not be able to package what you want.
  • The default minSize is 30KB (note that the size is pre-compression). Be sure to set a value below 30KB, otherwise you may not be able to pack what you want, and this should be added to cacheGroups.
  • Priority is useful in some cases where you can set the priority of bundles that are chunks.

The example above has a Commons, but the name can be set or not set, which I didn’t, so you can see what it looks like, and you’ll see that in some cases it’s better not to set the name.

   commons: {
         	chunks: "initial",
		minChunks: 2,
		maxInitialRequests: 5, // The default limit is too small to showcase the effect
		minSize: 0 ,
		name: "commons"
        },
Copy the code

conclusion

SplitChunk does a pretty good job of automating lazy loading, but in multi-page configurations (with different vendors separated by different pages), it tends to get output that is not what we want because of its optimization strategy. This article is just my initial general knowledge, I haven’t looked at the source code in depth, later may fill in the splitChunk source analysis, then more clear

The source code

The code segment

Lazy code loading

Refer to the article

SplitChunk Chinese version

SplitChunk English

Webpack document

The official demo