预计
希望看完这篇文章后,你在看配置的时候能够在脑海中形成Chunk的生成流程。
块
chunk 与entry、 等概念不同。 它们对应于配置对象中的字段。 Chunk 没有单独的配置字段,但该词出现在(以前的) 和 等名称中。 (之后)。
块是一个我们理解并且必须理解的概念。
这里的Chunk指的是代码块,那么具体是指什么样的代码块呢?
块VS
首先,它可以看作是一个模块打包器。 我们编写的任何文件都是它的模块。 因此,配置文件有一个字段,其下有一个rules字段。 规则下有处理模块的规则,配置哪种类型的模块,交由哪种类型来处理。
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}
]
},
...
]
},
块
Chunk是打包过程中一堆堆的集合。 我们所知道的打包是从一个入口文件开始的,也可以说是一个入口模块。 入口模块引用这些其他模块,模块引用模块。 模块通过引用关系被一一封装,形成一个Chunk。
如果我们有多个入口文件,则可能会生成多个打包路径,一个路径会组成一个Chunk。 退出入口后会生成区块。 还有另外两种方式,下面介绍。
块VS
通常我们会混淆这两个概念,认为Chunk就是我们最终输出的一个或多个打包文件。 确实,大多数时候,一个 Chunk 就会产生一个。 但有时这种关系并不完全是一对一的。 例如,如果我们将其配置为“-map”。 那么入口文件只有一个,没有配置代码分割:
// webpack配置
entry: {
main: __dirname + "/app/main.js",
},
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
},
devtool: 'source-map',
这样的配置会产生一个Chunk,但是会产生两个,如下图
请注意,在 Chunk Names 列中,只有一个类似于 main 的 Chunk。 查看 Asset 列,有两个生成的文件和一个 .map 文件。
这就是Chunk和Chunk的区别。 Chunk是过程中的代码块和结果代码块。
查看源码,找到一个Chunk.js,点击查看:
/**
* A Chunk is a unit of encapsulation for Modules.
* Chunks are "rendered" into bundles that get emitted when the build completes.
*/
class Chunk {
}
里面有一个Chunk类,也就是说该类运行的时候,会生成Chunk对象,同时也可以证明Chunk是进程中的一个代码块。
对Chunk类的两点注释: Chunk是一些模块的封装单元。 块显示为构建完成后的样子。
生成Chunk的三种方式:Entry入口异步加载模块代码分段(代码)入口生成Chunk
配置条目的方法有以下三种:
传递一个字符串
entry: './src/js/main.js',
在这种情况下,只会生成一个 Chunk。 (这里只讨论entry对chunk的影响,不讨论code )
传递数组
entry: ['./src/js/main.js','./src/js/other.js'],
在这种情况下,只会生成一个Chunk。 数组中的源代码最终都会被打包成一个。 原因是只生成了一个Chunk。
传递对象
entry: {
main: './src/js/main.js',
other: './src/js/other.js'
},
output: {
// path: __dirname + "/public",
// filename:'bundle.js'
// 以上2行会报错
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
}
对象中的一个字段会生成一个Chunk,所以如果直接在里面写名字的话会报错。 因为上面的配置,生成了两个Chunk,最终会生成两个。 一个名字肯定是不够的。 您需要使用 [name] 变量来使用条目下的字段名称作为生成的名称。
这里entry的key也作为其对应的Chunk的名称。 有两种方法可以传递字符串或数组。 如果没有key,则生成的Chunk默认使用main的名称。
异步生成Chunk
除了入口文件影响Chunk之外,异步加载的模块也需要生成Chunk。
{
entry: {
"index": "pages/index.jsx"
},
output: {
filename: "[name].min.js",
chunkFilename: "[name].min.js"
}
}
const myModel = r => require.ensure([], () => r(require('./myVue.vue')), 'myModel')
这时候该字段就派上用场了,给异步加载的Chunk命名。
代码分割产生块
我们来分析一下。 下面的代码将生成几个Chunk。 main.js 文件和two.js 文件都引用同一个.js 文件。 main.js 中使用了 React。
module.exports = {
entry: {
main: __dirname + "/app/main.js",
other: __dirname + "/app/two.js",
},
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
chunkFilename: '[name].js',
},
optimization: {
runtimeChunk: "single",
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
},
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
priority: 10,
enforce: true
}
},
}
}
}
答案是 5。两个条目中的每一个都会生成一个。 : "" 会将在浏览器端运行时所需的代码分离到一个文件中。 下面的配置会生成一个Chunk,下面的配置会生成一个Chunk。 如下所示。
结论
这就是今天的研究。
当查看配置时,您可以知道这样的配置可以生成多少个块。 即使你刚刚开始,以后理解其他概念也会容易得多。