参考文章: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) { }); });

  1. // Webpack 会根据 Chunk 去生成输出的文件资源,每个 Chunk 都对应一个及其以上的输出文件
  2. // 例如在 Chunk 中包含了 CSS 模块并且使用了 ExtractTextPlugin 时,
  3. // 该 Chunk 就会生成 .js 和 .css 两个文件
  4. chunk.files.forEach(function (filename) {
  5. // compilation.assets 存放当前所有即将输出的资源
  6. // 调用一个输出资源的 source() 方法能获取到输出资源的内容
  7. let source = compilation.assets[filename].source();
  8. });
  9. });
  10. // 这是一个异步事件,要记得调用 callback 通知 Webpack 本次事件监听处理结束。
  11. // 如果忘记了调用 callback,Webpack 将一直卡在这里而不会往后执行。
  12. callback();
  13. })

} ```