问题测验
讲解开始之前,大家先看一个问题。如果你已经知道问题的答案,而且明白为什么,就不必往下阅读了。如果不知道答案或者知道答案,但不知道原因。那么,强烈建议阅读本文。
// webpack.config.js const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: { app: "./src/index.js" }, output: { filename: "[name].js", path: path.resolve(__dirname, "dist") }, optimization: { splitChunks: { chunks: "all" } }, plugins: [ new HtmlWebpackPlugin() ] };
// index.js import "vue" import(/*webpackChunkName: 'a' */ "./a"); import(/*webpackChunkName: 'b' */ "./b");
// a.js import "vue-router"; import "./someModule"; // 模块大小大于30kb
// b.js import "vuex"; import "./someModule"; // 模块大小大于30kb
// someModule.js // 该模块大小超过30kb // ...
代码分割的三种方式
webpack 中以下三种常见的代码分割方式:
- 入口起点:使用
entry
配置手动地分离代码。
- 动态导入:通过模块的内联函数调用来分离代码。
- 防止重复:使用
splitChunks
去重和分离 chunk。 第一种方式,很简单,只需要在entry
里配置多个入口即可:
entry: { app: "./index.js", app1: "./index1.js" }
第二种方式,就是在代码中自动将使用 import()
加载的模块分离成独立的包:
//... import("./a"); //...
第三种方式,是使用 splitChunks
插件,配置分离规则,然后 webpack
自动将满足规则的 chunk
分离。一切都是自动完成的。
前两种拆分方式,很容易理解。本文主要针对第三种方式进行讨论。
splitChunks 代码拆分
splitChunks
默认配置
splitChunks: { // 表示选择哪些 chunks 进行分割,可选值有:async,initial和all chunks: "async", // 表示新分离出的chunk必须大于等于minSize,默认为30000,约30kb。 minSize: 30000, // 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。 minChunks: 1, // 表示按需加载文件时,并行请求的最大数目。默认为5。 maxAsyncRequests: 5, // 表示加载入口文件时,并行请求的最大数目。默认为3。 maxInitialRequests: 3, // 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js automaticNameDelimiter: '~', // 设置chunk的文件名。默认为true。当为true时,splitChunks基于chunk和cacheGroups的key自动命名。 name: true, // cacheGroups 下可以可以配置多个组,每个组根据test设置条件,符合test条件的模块,就分配到该组。模块可以被多个组引用,但最终会根据priority来决定打包到哪个组中。默认将所有来自 node_modules目录的模块打包至vendors组,将两个以上的chunk所共享的模块打包至default组。 cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, // default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } }
以上配置,概括如下4个条件:
- 模块在代码中被复用或者来自
node_modules
文件夹
- 模块的体积大于等于30kb(压缩之前)
- 当按需加载 chunks 时,并行请求的最大数量不能超过5
- 初始页面加载时,并行请求的最大数量不能超过将3
// index.js import("./a"); // ...
// a.js import "vue"; // ...
以上代码,在默认配置下的构建结果如下: