参考文章:https://blog.csdn.net/frontend_frank/article/details/106205260
Webpack构建流程
- 校验配置文件:读取命令行传入或者webpack.config.js配置,初始化本次构建的参数
- 生成complier对象:执行配置文件中的实例化,为webpack事件流挂上自定义hooks
- 进入entryOptions阶段:webpack开始读取配置的entries,递归遍历所有入口文件
- run/watch:如果运行再watch模式,则执行watch方法,否则执行run方法
- compilation:创建compliation对象回调的hooks,依次进入每一个入口文件,使用loader对文件进行编译。通过compilation读取module的resourse,loader等信息。再将编译好的文件内容使用acorn解析成AST静态语法树。然后递归、重复执行这个过程,所有模块和依赖分析完成后,执行compilation的seal方法对每个chunk进行整理优化,封装webpack_require来模拟模块化操作
- emit:所有文件的编译及转化都已经完成,包含了最终的输出资源,我们可以通过compilation.assets上拿到所需数据
- afterEmit:文件已经写入磁盘完成
- doen: 完成编译
Compiler
- compiler包含了当前webpack运行配置,包含entry,output,loaders等配置,这个对象再启动wenpack被实例化,而且是全局唯一的。
- Plugin可以通过compiler对象获取webpack的配置信息
Compilation
- Compilation对象代表了一次资源版本构建。当运行webpack开发环境中间件钟,每当检测到一个文件变化,就会创建一个鑫的compilation,从而生成一组新的编辑资源。
- 一个Compilation对象表现了当前的资源模块,编译生成资源、变化的文件,以及被跟踪依赖的状态信息。简单来说就是把本次打包编译的内容存到内存
- Compilation也提供hooks功能
Compiler和Compilation区别
- Compiler代表了整个Webpacl从启动到关闭的生命周期
- Compilation代表了一次新的编译,只要文件有改动,compilation就会重新被创建 ```javascript
class Plugin { apply(compiler) { compiler.plugin(‘emit’, function (compilation, callback) { // compilation.chunks 存放所有代码块,是一个数组 compilation.chunks.forEach(function (chunk) { // chunk 代表一个代码块 // 代码块由多个模块组成,通过 chunk.forEachModule 能读取组成代码块的每个模块 chunk.forEachModule(function (module) { // module 代表一个模块 // module.fileDependencies 存放当前模块的所有依赖的文件路径,是一个数组 module.fileDependencies.forEach(function (filepath) { }); });
// Webpack 会根据 Chunk 去生成输出的文件资源,每个 Chunk 都对应一个及其以上的输出文件
// 例如在 Chunk 中包含了 CSS 模块并且使用了 ExtractTextPlugin 时,
// 该 Chunk 就会生成 .js 和 .css 两个文件
chunk.files.forEach(function (filename) {
// compilation.assets 存放当前所有即将输出的资源
// 调用一个输出资源的 source() 方法能获取到输出资源的内容
let source = compilation.assets[filename].source();
});
});
// 这是一个异步事件,要记得调用 callback 通知 Webpack 本次事件监听处理结束。
// 如果忘记了调用 callback,Webpack 将一直卡在这里而不会往后执行。
callback();
})
} ```