流程
- 初始化:从配置文件或是shell读取与合并参数,得到最终参数,实例化插件new Plugin()
- 开始编译:通过上一步初始化得到的最终参数,初始化一个Compiler对象,加载插件(依次调用插件中的apply方法),通过执行Compiler.run开始编译
- 确定入口:根据配置中entry找出所有入口文件
- 编译模块:从entry出发,调用配置的loader,对模块进行转换,同时找出模块依赖的模块(如何找?见下文),依次递归,直到所有依赖模块完成本步骤处理
- 完成模块编译:这一步已经使用loader对所有模块进行了转换,得到了转换后的新内容以及依赖关系
- 输出资源: 根据入口与模块之间的依赖关系,组装成一个个chunk代码块,并且生成文件输出列表
- 输出成功:根据配置中的输出路径和文件名,将文件写入文件系统,完成构建
编译阶段
- 启动编译,调用 Compiier.run()
- watch-run: 和 run 类似,区别是这个事件可以获取哪些文件发生了变化从而导致新的一次编译
- compile: 告诉插件,一次新的编译即将启动,并且给插件带上 compiler 对象
- compilation: 编译创建之后
- after-compile: 编译完成
- invalid: 编译错误等异常触发该事件
Compilation的事件
- build-moudle: 使用对应的loader去转换一个模块
- normal-module-loader: 在用loader转换一个模块后,生成 AST
- program:从配置的入口开始,分析生成的ast
- seal: 所有模块及其依赖的模块都通过Loader转换完成,根据依赖关系生成chunk
输出阶段
- should-emit 所有需要输出的文件都生成,准备输出,询问哪些文件需要输出,哪些不需要输出
- emit 确定好要输出哪些文件后,并执行文件输出,可以在这里获取和修改输出的内容
- after-emit 文件输出完毕
- done 完成一次完整的编译和输出流程
- failed 编译和输出过程中运到异常,导致webpack退出,会直接到这个步骤,可以在这里获取具体原因