module、chunk、bundle
module
- 对于
webpack来说,所有的资源(.js、.css、.png)都是module .js文件webpack原生可以处理,其他类型文件,需要通过loader进行转换,然后交给webpack处理webpack配置中,可以通过module字段,对不同module使用不同的rule处理1
2
3
4
5
6
7
8
9
10
11module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
}, ...
]
},
entry-point
- 生成依赖图(
dependency graph)的入口; webpack只能以.js文件做为生成依赖图的入口;parcel能使用其他模块(.html)做为入口,生成依赖图
chunk
- 是
webpack内部处理时的概念; - 一个
chunk是对依赖图的部分(子图)进行封装的结果Chunk the class is the encapsulation for parts of your dependency graph - 可以说一个
chunk是一堆module的集合 - 可以通过多个
entry-point来生成一个chunk
chunk分类
entry chunk- 包含webpack
runtime code并且是最先执行的chunk
- 包含webpack
initial chunk- 包含
同步加载进来的module且不包含runtime code的chunk - 在
entry chunk执行后再执行
- 包含
normal chunk- 使用
require.ensure、System.import、import()异步加载进来的module,会被放到normal chunk中 - 一般
normal chunk(异步chunk),会单独生成一个bundle,其名称一般通过webpackChunkName魔法注释和output.chunkFilename来指定- 在
webpackChunkName魔法注释中指定的name可以在output.chunkFilename中使用[name]取到
- 在
- 使用
bundle
- 最终输出的
chunk在用户端,被称之为bundle; - 正常情况下,可以将
chunk和bundle当成一个概念,只不过是不同时间的同一个东西chunk和bundle的区别,可以理解为chunk是过程中的代码块(给webpack处理的),bundle是结果的代码块(展现给用户的)
- 一般一个
chunk对应一个bundle,只有在配置了sourcemap时,才会出现一个chunk对应多个bundle的情况;
例子
1 | // other.js |
main.js中引入了gloabl.css;other.js中异步导入了lodash并使用了webpackChunkName魔法注释modulemain.js、test.js、other.js、global.css都是module
entry-pointmain.js、test.js、other.js
chunkmainother
bundlemain.bundle.jsother.bundle.jslodash.async.bundle.js
entry的两个key指定了两个chunk(bundle),名称分别为mian、other,最终会输出两个bundle;main.js、test.js、other.js都是entry-point- 因为没有抽取
css,所以没单独生成一个css文件,global.css的内容是内联在main.bundle.js中的
loader
webpack loader是webpack为了处理各种类型文件的一个中间层,webpack本质上就是一个node 模块,它不能处理js以外的文件,那么loader就帮助webpack做了一层转换,将所有文件都转成字符串,你可以对字符串进行任意操作/修改,然后返回给webpack一个包含这个字符串的对象,让webpack进行后面的处理。如果把webpack当成一个垃圾工厂的话,那么loader就是这个工厂的垃圾分类
plugin
- 如果把
webpack当成一个垃圾工厂,loader就是垃圾分类,将所有垃圾整理好交给webpack。plugin就是如何去处理这些垃圾。
核心流程
webpack启动后会从entry-point开始递归解析entry-point依赖的所有module。- 每找到一个
module, 就会根据配置的loader去找出对应的转换规则,对module进行转换后,再解析出当前module 依赖的 module。 - 这些模块会以
entry字段配置的key(chunk name)为单位进行分组,一个entry 和其所有依赖的 module被分到一个组也就是一个chunk。 - 最后
webpack会把所有 chunk转换成文件输出为bundle; - 在整个流程中
webpack会在恰当的时机执行plugin里定义的逻辑,在plugin执行逻辑中,可能会再抽取其他bundle(例如从js bundle中再单独抽取出一个css bundle文件),但这不属于webpack主逻辑,属于plugin附加的能力 - 正常情况下,
webpack是一个js entry-point对应一个js chunk对应生成一个js bundle(除非配置了sourcemap,会单独再生成一个sourcemap bundle); plugin属于增强webpack功能,loader给webpack提供非js文件的转换能力;
相关项目
参考
https://github.com/webpack/webpack.js.org/issues/970
https://juejin.im/post/5cede821f265da1bbd4b5630
https://juejin.im/post/5d2b300de51d45775b419c76