但愿读过本篇文章,你在看Webpack配置的时候,能在脑中造成Chunk的生成过程。css
Chunk不一样于entry、 output、module这样的概念,它们对应着Webpack配置对象中的一个字段,Chunk没有单独的配置字段,可是这个词出如今CommonsChunkPlugin(Webpack3之前)、optimization.splitChunks(Webpack4之后)这样的名称之中。vue
Chunk是咱们理解Webpack,必须理解的一个概念。node
Chunk在Webpack里指一个代码块,那具体是指什么样的代码块呢?react
首先来讲module,Webpack能够看作是模块打包机,咱们编写的任何文件,对于Webpack来讲,都是一个个模块。因此Webpack的配置文件,有一个module字段,module下有一个rules字段,rules下有就是处理模块的规则,配置哪类的模块,交由哪类loader来处理。webpack
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}
]
},
...
]
},
复制代码
Chunk是Webpack打包过程当中,一堆module的集合。咱们知道Webpack的打包是从一个入口文件开始,也能够说是入口模块,入口模块引用这其余模块,模块再引用模块。Webpack经过引用关系逐个打包模块,这些module就造成了一个Chunk。web
若是咱们有多个入口文件,可能会产出多条打包路径,一条路径就会造成一个Chunk。出了入口entry会产生Chunk,还有两种途径,下面会有介绍。数组
一般咱们会弄混这两个概念,觉得Chunk就是Bundle,Bundle就是咱们最终输出的一个或多个打包文件。确实,大多数状况下,一个Chunk会生产一个Bundle。但有时候也不彻底是一对一的关系,好比咱们把 devtool配置成'source-map'。而后只有一个入口文件,也不配置代码分割:浏览器
// webpack配置
entry: {
main: __dirname + "/app/main.js",
},
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
},
devtool: 'source-map',
复制代码
这样的配置,会产生一个Chunk,可是会产生两个bundle,以下图 bash
这就是Chunk和Bundle的区别,Chunk是过程当中的代码块,Bundle是结果的代码块。app
查看Webpack源码,发现有一个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类,这说明类Webpack在运行中,会生成Chunk对象,也能证实Chunk是过程当中的代码块。
Chunk类上面的两句注释:一个Chunk是一些模块的封装单元。Chunk在构建完成就呈现为bundle。
entry的配置有三种方式:
entry: './src/js/main.js',
复制代码
这种状况只会产生一个Chunk。(这里只说entry对Chunk的影响,不涉及代码分割)
entry: ['./src/js/main.js','./src/js/other.js'],
复制代码
这种状况也只会产生一个Chunk。Webpack会将数组里的源代码,最终都打包到一个Bundle里,缘由就是只生成了一个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,因此在output中filename直接写死名称,会报错。由于上面的配置,产生了两个Chunk,最终会生成两个Bundle,一个名称确定不够用了。须要用[name]变量来利用entry下的字段名称,做为生成Bundle们的名称。
这里面entry的key,也被用来看成它对应的Chunk的名称,上面传递一个字符串和传递数组两种方式,没有key,也会默认给生成的Chunk一个main的名称。
除了入口文件会影响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')
复制代码
这个时候chunkFilename字段就派上用场了,为异步加载的Chunk命名。
咱们来分析一下,下面代码会产生几个Chunk,其中main.js文件和two.js文件,都引用了同一个greeter.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个,两个入口分别产生一个, runtimeChunk: "single"会将Webpack在浏览器端运行时须要的代码单独抽离到一个文件,commons下的配置会产生一个Chunk,vendor下的配置会产生一个Chunk。以下图。
今天的研究就到这里。
可以在看Webpack的配置的时候,分辨出这样的配置能生成几个Chunk,Webpack就算是入门了,后面理解它的其余概念,会容易不少。