在 Webpack 中,Compilation是一个非常重要的概念,它代表了一次资源构建的过程,以下是关于它的详细介绍:
基本概念
Compilation对象是 Webpack 在构建过程中创建的一个实例,用于管理和处理一次完整的构建任务。它包含了本次构建的所有模块、资源、Chunk 等信息,并且负责完成从模块解析、编译到生成最终输出文件的整个过程。在 Webpack 运行期间,可以有多个Compilation实例,比如在开发模式下,每当文件发生变化触发重新构建时,就会创建一个新的Compilation实例。
主要功能
- 模块解析:
Compilation会根据配置中的entry选项,从入口模块开始,递归地解析模块之间的依赖关系,构建出一个依赖图。在解析过程中,它会处理各种模块类型,如 JavaScript 模块、CSS 模块、图片等,并根据相应的加载器对模块进行转换。 - 模块编译:在解析完模块依赖后,
Compilation会使用配置好的加载器对每个模块进行编译。加载器可以将不同类型的资源转换为 Webpack 能够处理的 JavaScript 模块,例如,使用babel-loader将 ES6 + 代码转换为 ES5 代码,使用css-loader处理 CSS 文件等。 - 代码生成:
Compilation会根据模块之间的依赖关系和配置选项,将编译后的模块组合成最终的 Chunk。然后,将 Chunk 中的代码转换为浏览器能够识别的格式,生成最终的输出文件,如 JavaScript 文件、CSS 文件等。 - 插件应用:
Compilation为插件提供了丰富的钩子函数,插件可以通过这些钩子函数在构建过程的不同阶段介入,执行各种自定义的任务。例如,webpack.DefinePlugin可以在编译时定义全局常量,HtmlWebpackPlugin可以根据模板生成 HTML 文件,并将生成的 JavaScript 和 CSS 文件自动注入到 HTML 中。
生命周期钩子
-
初始化阶段:
compilation钩子在Compilation实例创建后立即触发,插件可以在此阶段对Compilation实例进行一些初始化操作。 -
模块处理阶段
buildModule钩子在模块开始构建时触发,插件可以在此对模块进行一些预处理。normalModuleLoader钩子在模块使用加载器进行加载时触发,插件可以干预模块的加载过程。finishModules钩子在所有模块都被处理完成后触发,插件可以在此进行一些与模块处理结果相关的操作。
-
代码生成阶段
seal钩子在Compilation准备生成代码之前触发,插件可以在此对Compilation的内部状态进行最后的修改。emit钩子在生成文件即将输出到磁盘之前触发,插件可以在此阶段对生成的文件内容进行修改、添加或删除文件等操作。done钩子在整个构建过程完成后触发,插件可以在此进行一些清理工作或输出构建结果的相关信息。
与 Compiler 的区别
Compiler和Compilation是 Webpack 中的两个核心概念,Compiler代表了整个 Webpack 的编译环境,它在 Webpack 启动时被创建,并且在整个生命周期中只存在一个实例。它主要负责读取配置文件、初始化插件、启动编译过程等。而Compilation代表了一次具体的编译过程,它在每次构建时被创建,可以有多个实例。Compiler负责管理和调度Compilation的创建和执行,而Compilation则负责具体的模块解析、编译和代码生成等工作。