构建流程
参数初始化
编译
开始编译,
- 初始化 Compiler 对象,加载插件
- 实例compiler后会根据options的watch判断是否启动了watch
- 如果启动watch了就调用compiler.watch来监控构建文件
- 否则启动compiler.run来构建文件。
确定入口
根据entry
编译模块
- 从入口出发
- 调用loader
- 找出依赖
- 递归
完成编译
得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
输出资源
- 组装成一个个包含多个模块的 Chunk,
- 每个 Chunk 转换成一个单独的文件
- 得到输出列表
- 修改输出的最后机会
输出
写入文件
插件原理
- Tapable
- 事件流机制保证了插件的有序性
- 使得整个系统扩展性良好
- 类似于 Node.js 的 EventEmitter 的库
- 控制钩子函数的发布与订阅
Compiler 和 Compilation
解析
- compiler
- 代表了完整的 webpack 环境配置。
- 可以使用它来访问 webpack 的主环境
- 这个对象在启动 webpack 时被一次性建立
- 包括 options,loader 和 plugin。
- 当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。
- 可以使用它来访问 webpack 的主环境
- 插件最后都会变成compiler对象上的实例。
- 代表了完整的 webpack 环境配置。
- compilation
- 对象代表了一次资源版本构建。
- 每当检测到一个文件变化,就会创建一个新的 compilation
- 传给每个插件的 compiler 和 compilation对象都是同一个引用
- 若在一个插件中修改了它们身上的属性,会影响后面的插件
区别
- Compiler暴露了和 Webpack 整个生命周期相关的钩子
- compilation 暴露了与模块和依赖有关的粒度更小的事件钩子