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魔法注释
module
main.js、test.js、other.js、global.css
都是module
entry-point
main.js、test.js、other.js
chunk
main
other
bundle
main.bundle.js
other.bundle.js
lodash.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