ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

webpack4之splitChunks.maxAsyncRequests

2020-01-26 15:37:16  阅读:332  来源: 互联网

标签:webpack4 splitChunks default subtract modules bundle js add maxAsyncRequests


概要

这个配置用来控制按需引入的包中的直接引入的包的打包。他表示按需引入的包中并行请求的最大数量。

一开始听起来肯定是大脑一片蒙蒙的感觉,不过其实很简单,可以理解为:当整个项目打包完之后,一个按需加载的包最终被拆分成n个包,maxAsyncRequests就是用来限制n的最大值。

接下来,还是按照老规矩,通过一系列的例子来实践一下。

准备工作

  1. 目录
root
——dist(打包之后的文件夹)
——node_modules(下载的包)
——src(项目脚本目录)
————entry(入口点脚本)
————modules(入口点中引入的模块)
——package.json(包管理文件)
——webpack.config.js(webpack配置文件)
  1. webpack配置
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: {
    entry1: './src/entry/entry1.js',
    entry2: './src/entry/entry2.js'
  },
  plugins: [
    new CleanWebpackPlugin()
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
      maxAsyncRequests: 3,
      minSize: 1,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 1,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
  // default config
  // optimization: {
  //   splitChunks: {
  //     chunks: 'async',
  //     minSize: 30000,
  //     minChunks: 1,
  //     maxAsyncRequests: 5,
  //     maxInitialRequests: 3,
  //     automaticNameDelimiter: '~',
  //     automaticNameMaxLength: 30,
  //     name: true,
  //     cacheGroups: {
  //       vendors: {
  //         test: /[\\/]node_modules[\\/]/,
  //         priority: -10
  //       },
  //       default: {
  //         minChunks: 2,
  //         priority: -20,
  //         reuseExistingChunk: true
  //       }
  //     }
  //   }
  // }
}
  1. package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^3.0.0",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10"
  }
}

案例

接下来,通过几个简单的案例,来分析maxAsyncRequests配置的控制规则。

  1. demo1
################################
webpack.config.js:

splitChunks.maxAsyncRequests设为2

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/mutiply.js

export default function mutiply (a, b) {
  return a * b
}

################################
modules/module.js

import add from './add'
import subtract from './subtract'
import multiply from './multiply'

export default function () {
  console.log(add(3, 4) + subtract(10, 5) + multiply(1, 2))
}

################################
entry/entry1.js:

import('../modules/module').then(f => {
  console.log('index', f())
})

################################
entry/entry2.js:

import add from '../modules/add'
import subtract from '../modules/subtract'
import multiply from '../modules/multiply'

console.log('index', add(1, 2) + subtract(4, 2) + multiply(1, 2))

通过npm run build进行打包,结果如下:

Hash: 699d2402a2a59dfa24c3
Version: webpack 4.41.5
Time: 85ms
Built at: 2020/01/19 上午9:28:13
                   Asset       Size  Chunks             Chunk Names
             0.bundle.js  333 bytes       0  [emitted]  
             5.bundle.js  211 bytes       5  [emitted]  
default~entry1.bundle.js  165 bytes       1  [emitted]  default~entry1
default~entry2.bundle.js  196 bytes       2  [emitted]  default~entry2
        entry1.bundle.js   2.22 KiB       3  [emitted]  entry1
        entry2.bundle.js   1.47 KiB       4  [emitted]  entry2
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = 0.bundle.js default~entry2.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 54 bytes {0} [built]
[1] ./src/modules/subtract.js 59 bytes {0} [built]
[2] ./src/modules/multiply.js 59 bytes {0} [built]
[3] ./src/modules/module.js 183 bytes {5} [built]
[4] ./src/entry/entry1.js 70 bytes {1} [built]
[5] ./src/entry/entry2.js 185 bytes {2} [built]

我们会发现,add.js、subtract.js、multiply.js被打包到0.bundle.js,相当于entry1中按需引入的module/module.js包最终被拆分成0.bundle.js和5.bundle.js,刚刚好等于我们配置的最大上限值2。(这里注意下,webpack发现entry1中引入的module.js和entry2都直接引入了add.js、subtract.js和multiply.js,所以它很只能地将这三个包打包进同一个文件中,而不是分别单独打包。)

  1. demo2.js
################################
webpack.config.js:

splitChunks.maxAsyncRequests设为1

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/mutiply.js

export default function mutiply (a, b) {
  return a * b
}

################################
modules/module.js

import add from './add'
import subtract from './subtract'
import multiply from './multiply'

export default function () {
  console.log(add(3, 4) + subtract(10, 5) + multiply(1, 2))
}

################################
entry/entry1.js:

import('../modules/module').then(f => {
  console.log('index', f())
})

################################
entry/entry2.js:

import add from '../modules/add'
import subtract from '../modules/subtract'
import multiply from '../modules/multiply'

console.log('index', add(1, 2) + subtract(4, 2) + multiply(1, 2))

只是将maxAsyncRequests设为1,然后再次打包,结果如下:

Hash: 752b64e3f762dc224b3b
Version: webpack 4.41.5
Time: 84ms
Built at: 2020/01/19 上午9:38:39
                   Asset       Size  Chunks             Chunk Names
             4.bundle.js  482 bytes       4  [emitted]  
default~entry1.bundle.js  143 bytes       0  [emitted]  default~entry1
default~entry2.bundle.js  469 bytes       1  [emitted]  default~entry2
        entry1.bundle.js   2.22 KiB       2  [emitted]  entry1
        entry2.bundle.js   1.47 KiB       3  [emitted]  entry2
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry2.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 54 bytes {1} {4} [built]
[1] ./src/modules/subtract.js 59 bytes {1} {4} [built]
[2] ./src/modules/multiply.js 59 bytes {1} {4} [built]
[3] ./src/modules/module.js 183 bytes {4} [built]
[4] ./src/entry/entry1.js 70 bytes {0} [built]
[5] ./src/entry/entry2.js 185 bytes {1} [built]

add.js、subtract.js、multiply.js并没有被单独打包出来,分别包含于4.bundle.js和default~entry2.bundle.js中。这恰好对应了我们配置的1,因为最大值为1,如果同demo1一样将add.js、subtract.js和multiply.js单独打包进一个文件中,相当于一个module被拆分成2个文件(即 > 1)。

  1. demo3
################################
webpack.config.js:

splitChunks.maxAsyncRequests设为2

同时entry入口新增entry3.js,如下:

entry: {
    entry1: './src/entry/entry1.js',
    entry2: './src/entry/entry2.js',
    entry3: './src/entry/entry3.js',
}

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/mutiply.js

export default function mutiply (a, b) {
  return a * b
}

################################
modules/module.js

import add from './add'
import subtract from './subtract'
import multiply from './multiply'

export default function () {
  console.log(add(3, 4) + subtract(10, 5) + multiply(1, 2))
}

################################
entry/entry1.js:

import('../modules/module').then(f => {
  console.log('index', f())
})

################################
entry/entry2.js:

import add from '../modules/add'
import subtract from '../modules/subtract'
import multiply from '../modules/multiply'

console.log('index', add(1, 2) + subtract(4, 2) + multiply(1, 2))

################################
entry/entry3.js:

import add from '../modules/add'
import subtract from '../modules/subtract'

console.log('index', add(1, 2) + subtract(4, 2))

npm run build打包后,结果如下:

Hash: fbf4c99a34e2c4080633
Version: webpack 4.41.5
Time: 83ms
Built at: 2020/01/23 上午11:39:36
                   Asset       Size  Chunks             Chunk Names
             0.bundle.js  242 bytes       0  [emitted]  
             7.bundle.js  302 bytes       7  [emitted]  
default~entry1.bundle.js  165 bytes       1  [emitted]  default~entry1
default~entry2.bundle.js  289 bytes       2  [emitted]  default~entry2
default~entry3.bundle.js  172 bytes       3  [emitted]  default~entry3
        entry1.bundle.js   2.22 KiB       4  [emitted]  entry1
        entry2.bundle.js   1.47 KiB       5  [emitted]  entry2
        entry3.bundle.js   1.47 KiB       6  [emitted]  entry3
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = 0.bundle.js default~entry2.bundle.js entry2.bundle.js
Entrypoint entry3 = 0.bundle.js default~entry3.bundle.js entry3.bundle.js
[0] ./src/modules/add.js 54 bytes {0} [built]
[1] ./src/modules/subtract.js 59 bytes {0} [built]
[2] ./src/modules/multiply.js 59 bytes {2} {7} [built]
[3] ./src/modules/module.js 183 bytes {7} [built]
[4] ./src/entry/entry1.js 70 bytes {1} [built]
[5] ./src/entry/entry2.js 185 bytes {2} [built]
[6] ./src/entry/entry3.js 171 bytes {3} [built]

其中add.js和subtract.js被单独打包进0.bundle.js,保证了module.js被拆分成了2个文件。(我们配置的上限为2)

假设我们没有限制,可以想到的是,add.js和subtract.js被拆分到一个文件中,multiply.js被拆分到一个文件中,所以我们会有这样一个疑惑,就是multiply.js为什么没有被拆出来,而是add.js、subtract.js被拆分出来。个人的猜想有两点:一个是add.js、subtract.js在三个入口点中均引入,而multiply.js在两个入口点中被引入;另外一个是add.js、subtract.js拆分出来的包肯定比单独multiply.js一个文件大。

为了得出webpack相应的打包规则,我们将multiply.js添加很多注释,使得其大小大于add.js和subtract.js大小总和。打包之后我们会发现结果和上面是一样的,所以可以得出:对于可能被打包的两种情况,被引入更多次的那个包会被优先打包出来。

那么引入的次数如果是一样的,那么是不是体积更大的会优先被打包出来呢,我们也可以测试一下。基于刚刚对demo3中multiply.js添加注释的代码,对于entry2.js只引入add.js,对于entry3.js只引入multiply.js,这个时候的打包结果为multiply.js被单独打包出来。

综上,我们得出的结论是:

a. 如果对于单独打包出来的模块有两种可能,被多次引入的那个包会被优先打包出来;
b. 同样的情况,如果两种情况下模块被引用的次数相同,体积大的那个模块或多个模块集会被打包出来;

注:如果两种情况下,情况一只包含一个模块,情况二则包含两个模块,并且两种情况下被引入的次数也是相同的,那么打包规则还是按照上面的b规则。

  1. demo4
################################
webpack.config.js:

在基于demo3的基础上将splitChunks.maxAsyncRequests设为3

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/mutiply.js

export default function mutiply (a, b) {
  return a * b
}

################################
modules/module.js

import add from './add'
import subtract from './subtract'
import multiply from './multiply'

export default function () {
  console.log(add(3, 4) + subtract(10, 5) + multiply(1, 2))
}

################################
entry/entry1.js:

import('../modules/module').then(f => {
  console.log('index', f())
})

################################
entry/entry2.js:

import add from '../modules/add'
import subtract from '../modules/subtract'
import multiply from '../modules/multiply'

console.log('index', add(1, 2) + subtract(4, 2) + multiply(1, 2))

################################
entry/entry3.js:

import add from '../modules/add'
import subtract from '../modules/subtract'

console.log('index', add(1, 2) + subtract(4, 2))

npm run build打包后,结果如下:

Hash: a3554617a9e78396ebfd
Version: webpack 4.41.5
Time: 272ms
Built at: 2020/01/23 上午11:43:49
                   Asset       Size  Chunks             Chunk Names
             0.bundle.js  242 bytes       0  [emitted]  
             1.bundle.js  153 bytes       1  [emitted]  
             7.bundle.js  211 bytes       7  [emitted]  
default~entry1.bundle.js  172 bytes       2  [emitted]  default~entry1
default~entry3.bundle.js  172 bytes       3  [emitted]  default~entry3
        entry1.bundle.js   2.22 KiB       4  [emitted]  entry1
        entry2.bundle.js    1.6 KiB       5  [emitted]  entry2
        entry3.bundle.js   1.47 KiB       6  [emitted]  entry3
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = 0.bundle.js 1.bundle.js entry2.bundle.js
Entrypoint entry3 = 0.bundle.js default~entry3.bundle.js entry3.bundle.js
[0] ./src/modules/add.js 54 bytes {0} [built]
[1] ./src/modules/subtract.js 59 bytes {0} [built]
[2] ./src/modules/multiply.js 59 bytes {1} [built]
[3] ./src/entry/entry2.js 185 bytes {5} [built]
[4] ./src/modules/module.js 183 bytes {7} [built]
[5] ./src/entry/entry1.js 70 bytes {2} [built]
[6] ./src/entry/entry3.js 171 bytes {3} [built]

add.js和subtract.js被单独打包进0.bundle.js,multiply.js被单独打包进1.bundle.js中。

如果继续将maxAsyncRequests配置项继续增大,结果还是一样。

这里将maxAsyncRequests设置为3,也就表示按需引入的module.js最多只能被拆分成三个bundle。

注:上面的打包结果我们会发现和之前的有些不一样,default.entry2.bundle.js没有被打包出来,这里主要是跟maxInitialRequests这个配置有关,该配置默认为3,这就表示单个入口点最多能被拆分的数量,上面这种情况,已经被拆分出0.bundle.js、1.bundle.js和entry2.js,数目已经达到3,default.entry2.bundle.js自然不会被打包出来。

  1. demo5
################################
webpack.config.js:

splitChunks.maxAsyncRequests设为2

基于demo3新增一个入口点,例如:

entry: {
    entry1: './src/entry/entry1.js',
    entry2: './src/entry/entry2.js',
    entry3: './src/entry/entry3.js',
    entry4: './src/entry/entry4.js',
}

################################
modules/add.js:

export default function add (a, b) {
  return a + b
}

################################
modules/subtract.js

export default function subtract (a, b) {
  return a - b
}

################################
modules/mutiply.js

export default function mutiply (a, b) {
  return a * b
}

################################
modules/module.js

import add from './add'
import subtract from './subtract'
import multiply from './multiply'

export default function () {
  console.log(add(3, 4) + subtract(10, 5) + multiply(1, 2))
}

################################
entry/entry1.js:

import('../modules/module').then(f => {
  console.log('index', f())
})

################################
entry/entry2.js:

import add from '../modules/add'
import subtract from '../modules/subtract'
import multiply from '../modules/multiply'

console.log('index', add(1, 2) + subtract(4, 2) + multiply(1, 2))

################################
entry/entry3.js:

import add from '../modules/add'
import subtract from '../modules/subtract'

console.log('index', add(1, 2) + subtract(4, 2))

################################
entry/entry4.js:

import add from '../modules/add'
import subtract from '../modules/subtract'

console.log('index', add(1, 2) + subtract(4, 2))

打包后,结果如下:

Hash: 0edbe3d934d97c0d8908
Version: webpack 4.41.5
Time: 95ms
Built at: 2020/01/23 下午1:58:34
                   Asset       Size  Chunks             Chunk Names
             0.bundle.js  242 bytes       0  [emitted]  
             9.bundle.js  302 bytes       9  [emitted]  
default~entry1.bundle.js  165 bytes       1  [emitted]  default~entry1
default~entry2.bundle.js  289 bytes       2  [emitted]  default~entry2
default~entry3.bundle.js  172 bytes       3  [emitted]  default~entry3
default~entry4.bundle.js  172 bytes       4  [emitted]  default~entry4
        entry1.bundle.js   2.22 KiB       5  [emitted]  entry1
        entry2.bundle.js   1.47 KiB       6  [emitted]  entry2
        entry3.bundle.js   1.47 KiB       7  [emitted]  entry3
        entry4.bundle.js   1.47 KiB       8  [emitted]  entry4
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = 0.bundle.js default~entry2.bundle.js entry2.bundle.js
Entrypoint entry3 = 0.bundle.js default~entry3.bundle.js entry3.bundle.js
Entrypoint entry4 = 0.bundle.js default~entry4.bundle.js entry4.bundle.js
[0] ./src/modules/add.js 54 bytes {0} [built]
[1] ./src/modules/subtract.js 59 bytes {0} [built]
[2] ./src/modules/multiply.js 59 bytes {2} {9} [built]
[3] ./src/modules/module.js 183 bytes {9} [built]
[4] ./src/entry/entry1.js 70 bytes {1} [built]
[5] ./src/entry/entry2.js 185 bytes {2} [built]
[6] ./src/entry/entry3.js 171 bytes {3} [built]
[7] ./src/entry/entry4.js 171 bytes {4} [built]

其实就和demo3一样,add.js和subtract.js被单独打包到0.bundle.js,假如将maxAsyncRequests设置为3,效果和demo4一样。

上面的demo我们都是建立在chunks设置成all的情况下,如果设置成async,maxAsyncRequests配置还有效吗?当然是有效的。

总结

  • maxAsyncRequests用来表示按需加载的模块其能拆分的最大数量;
  • 如果对于单独打包出来的模块有两种可能,被多次引入的那个包会被优先打包出来;
  • 同样的情况,如果两种情况下模块被引用的次数相同,体积大的那个模块或多个模块集会被打包出来;
  • 该配置对于chunks为async和all情况下均可行,对于initial无效;
YaoDeBiAn 发布了71 篇原创文章 · 获赞 91 · 访问量 14万+ 私信 关注

标签:webpack4,splitChunks,default,subtract,modules,bundle,js,add,maxAsyncRequests
来源: https://blog.csdn.net/YaoDeBiAn/article/details/104036432

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有