brief introduction : Code segmentation is webpack One of the biggest characteristics , Through this feature, you can cut your code into multiple parts bundles inside , So it can be loaded on demand or in parallel , Can achieve smaller bundle And control the priority of resource loading .

Before we talk about code segmentation , Let's start with a few concepts :

1,bundles:bundles It means webpack General name of packaged files , There is only one file packaged from a single entry , picture , Font files and other formats will also be packaged into this file bundle File with base64 The form of existence . But in actual development, we often don't do that , This will pack up a big one js file , Don't talk about the shortcomings , First, all resources will be loaded in the first time , It takes too long to load the white screen for the first time , The second is that we can't make use of browser's parallel loading , Make loading time too long , Third, some resources that may not be used will be loaded , Causing bandwidth waste .

2,chunk:chunk It means code block , One bundle By one or more chunk form , One chunk By one or more module form ,chunk Is the basis of code cutting . about bundle And chunk The relationship between ,webpack The packaged result is split into multiple code blocks , We call it chunk, these chunk yes bundles A member of , So it can also be called bundle, It's like having a bottle of water , Let's pour it into some cups , A bottle of water is the same as here bundles, A glass of water is equivalent to chunk.

3,module: modular , I think this is different from the architecture module in our project ,webpack The module in is the file , Each file is treated as a module . For example , Suppose we have a login module , It contains js,css,img etc. , In abstract concepts , We abstractly refer to these files as a module , Login module , and webpack In my eyes, it's different , It's a file, it's a module , It is divided into modules in the form of physical files . Module is the smallest unit for code segmentation , That is to say , We can't talk to one person moudle More granular segmentation , Even if the file is big . For example , There is now a third-party library , This library has 1M, We can't split this library into two 512KB Of bundle. Of course, it depends on how the library designer designs the packaged files , If this library is packaged as a file , We are indivisible , such as jquery. If it looks like element-ui, The library itself packages each component separately , Not all components are packaged in one file , So we can load on demand . Of course, for some single large file , We have other optimization methods , Like obfuscation compression ,tree-shaking etc .

webpack The way of code division , There are usually three types :

Points: Partition by configuring the entry file , This is the simplest and most direct way , But this method has some disadvantages , It may cause code to be packed repeatedly , This paper discusses another way , This article does not discuss .

2,Prevent Duplication:  use splitChunksPlugin To extract the common code .

3,Dynamic Imports: Split code by dynamic code loading , use import() method .

call import()  Place , It is used as the starting point of separated modules , intend , The requested module and all submodules it references , Will separate into a separate chunk
in .import Method depends on Promise, If you need to use it in a lower version browser , It needs to be done polyfill.

import Use of
//a.js import('./b.js').then(b => { //doSomething })
import  The specification does not allow the name or other properties of the control module , because "chunks" just webpack
A concept in English , But we can receive some special parameters through annotations , Without breaking the rules :

webpackChunkName: Manually specify the name of the module

webpackMode: appoint webpack How to resolve dynamic import

* lazy: Default value , For each import() The imported module generates a delay loadable chunk
lazy-once: generate N Can delay loading chunk, This pattern can only be used in some dynamic statements , such as import(`./util/${tool}.js`),webpack Will be util Each of the following js The files are packaged separately into a single file chunk.
//index.js let util = 'a' import(`./util/${util}.js`).then(res => {})
//util/a.js export function add() { console.log('add') } //util/b.js export
const arr = [1, 2, 3]
The packaged directory structure is as follows

We can see that , In addition to generating a master bundle(index.js), Also generated 1.js and 2.js, Corresponding to a.js and b.js Of chunk.

eager: This pattern does not generate additional information chunk, All modules are currently blocked chunk introduce , There will be no additional network requests . Compared with static import , Before calling the module , The module will not be executed .( Static import the first time to execute module code ,ES
Module It belongs to static import ,commonjs Of require It belongs to dynamic import )
weak: Try to load the module , If the module function is already loaded in another way ( Namely , the other one  chunk  This module has been imported , Or the script containing the module is loaded ). Will still return  Promise, However, only the client already has the service  chunk  The resolution is successful only when the . If the module is not available ,Promise  It will be  rejected  state , And network requests are never executed . When needed  chunks  Always ( Embedded in the page ) Manually provided in initial request , Instead of being triggered by the application navigation in the case of module import that was not initially provided , This is useful for general rendering (SSR) It's very useful .( This one hasn't been used yet )
matters needing attention :

* import() Full dynamic statements are not supported , for example import(util), because webpack
At least some file path information is required , and util It could be any path ,webpack It's impossible to package all the modules into one chunk.
Generally we use import() Dynamic import module , Do not statically introduce this module into other modules , because webpack division chunk Time , The module is packaged and statically imported chunk in , This will make it impossible to separate chunk Or the code is packed repeatedly .
//index.js import('./util/a') import('./util/b') //util/a.js import { arr }
from './b' export function add() { console.log('add' + arr) } //util/b.js
export const arr = [1, 2, 3]
The above code packages the result :

At first glance , It turns out there's no problem , But when we open the packaged file ,b The modules are packaged into 1.js, that is a Module split chunk inside
//1.js ;(window['webpackJsonp'] = window['webpackJsonp'] || []).push([ [1, 2],
[ , function(module, __webpack_exports__, __webpack_require__) { 'use strict'
__webpack_require__.r(__webpack_exports__) /* harmony export (binding) */
__webpack_require__.d(__webpack_exports__, 'arr', function() { return arr })
const arr = [1, 2, 3] }, function(module, __webpack_exports__,
__webpack_require__) { 'use strict' __webpack_require__.r(__webpack_exports__)
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__,
'add', function() { return add }) /* harmony import */ var
_b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1) function add() {
console.log('add' + _b__WEBPACK_IMPORTED_MODULE_0__['arr']) } } ] ])
Then we look at it 2.js
//2.js ;(window['webpackJsonp'] = window['webpackJsonp'] || []).push([ [2], [
, function(module, __webpack_exports__, __webpack_require__) { 'use strict'
__webpack_require__.r(__webpack_exports__) /* harmony export (binding) */
__webpack_require__.d(__webpack_exports__, 'arr', function() { return arr })
const arr = [1, 2, 3] } ] ])
And then we found out 2.js namely b modular , such b The module is packed repeatedly .

Let's look at another situation
//index.js import { add } from './util/a' import { arr } from './util/b' add()
//util/a.js export function add() { console.log('add' + arr) } import('./b')
//util/b.js export const arr = [1, 2, 3]
At this point, the packing result is as follows , No additional chunk.

summary :webpack When processing modules , Start with the entry file , If you encounter statically imported modules , Then package it into the current chunk, If you encounter dynamic import , Then judge the current situation chunk Is this module included , If already included , No additional chunk, If not, a new one is generated chunk. When processing static imports , With or without this module chunk, Will package the dynamic module into the current chunk.

about webpackChunkName, By default, use self growth chunkId, If multiple modules are used import() Introduce this module dynamically , his chunk Name traverses first by depth module Name it , If the deepest layer is not specified , It is the second deepest , And so on , If none is specified, auto increment is used id.