webpack的Compilation你了解多少

97 阅读3分钟

在 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 的区别

CompilerCompilation是 Webpack 中的两个核心概念,Compiler代表了整个 Webpack 的编译环境,它在 Webpack 启动时被创建,并且在整个生命周期中只存在一个实例。它主要负责读取配置文件、初始化插件、启动编译过程等。而Compilation代表了一次具体的编译过程,它在每次构建时被创建,可以有多个实例。Compiler负责管理和调度Compilation的创建和执行,而Compilation则负责具体的模块解析、编译和代码生成等工作。