Webpack 插件

Webpack 插件系统是基于 Tapable 库实现的

# 初始化阶段钩子

  • environment: 在 Webpack 环境设置完成时触发。可以用于在开始编译之前设置一些全局变量或进行配置的初始化。

    compiler.hooks.environment.tap('MyPlugin', () => {
      console.log('环境设置完成');
    });
    
  • afterEnvironment: 在环境设置完成之后触发,用于对环境的进一步调整。

    compiler.hooks.afterEnvironment.tap('MyPlugin', () => {
      console.log('环境设置完成后');
    });
    
  • beforeRun: 在 Webpack 编译开始之前触发。可以用于在构建开始前执行一些准备工作。

    compiler.hooks.beforeRun.tapAsync('MyPlugin', (compiler, callback) => {
      console.log('构建即将开始');
      callback();
    });
    
  • run: 在 Webpack 开始编译时触发,主要用于编译开始时的一些自定义逻辑。

    compiler.hooks.run.tapAsync('MyPlugin', (compiler, callback) => {
      console.log('编译开始');
      callback();
    });
    

# 编译阶段钩子

这些钩子在 Webpack 开始编译和解析模块时触发,可以用来控制和修改编译过程。

  • compile: 在创建 Compilation 对象时触发,用于创建新的一轮编译。

    compiler.hooks.compile.tap('MyPlugin', (params) => {
      console.log('开始一次新的编译');
    });
    
  • compilation: 在一次编译创建后触发,可以在这里添加自定义的构建逻辑。

    compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
      console.log('Compilation 对象已创建');
    });
    
  • thisCompilation: 与 compilation 类似,但发生在 compilation 之前,可以在这里访问当前编译的上下文。

    compiler.hooks.thisCompilation.tap('MyPlugin', (compilation) => {
      console.log('当前编译上下文');
    });
    

# 构建模块阶段钩子

这些钩子在 Webpack 构建模块时触发,可以对模块的构建进行控制和修改。

  • normalModuleFactory: 在创建模块工厂时触发,用于自定义模块的创建。

    compiler.hooks.normalModuleFactory.tap('MyPlugin', (factory) => {
      console.log('模块工厂创建');
    });
    
  • contextModuleFactory: 在创建上下文模块工厂时触发,用于处理动态 require 的模块。

    compiler.hooks.contextModuleFactory.tap('MyPlugin', (factory) => {
      console.log('上下文模块工厂创建');
    });
    
  • beforeCompile: 在编译过程正式开始之前触发,通常用于修改编译参数。

    compiler.hooks.beforeCompile.tapAsync('MyPlugin', (params, callback) => {
      console.log('编译前准备');
      callback();
    });
    
  • afterCompile: 在所有模块编译完成后触发,可以在这里获取编译的结果或进行一些收尾工作。

    compiler.hooks.afterCompile.tapAsync('MyPlugin', (compilation, callback) => {
      console.log('所有模块编译完成');
      callback();
    });
    

# 优化阶段钩子

这些钩子在 Webpack 对代码进行优化时触发,用于控制和修改优化过程。

  • optimizeModules: 在模块优化阶段触发,适用于修改优化后的模块。

    compilation.hooks.optimizeModules.tap('MyPlugin', (modules) => {
      console.log('模块优化阶段');
    });
    
  • optimizeChunks: 在代码块优化阶段触发,可以用来优化打包的 chunk。

    compilation.hooks.optimizeChunks.tap('MyPlugin', (chunks) => {
      console.log('代码块优化阶段');
    });
    
  • optimizeAssets: 在资源优化阶段触发,可以在这里进行资源文件(如 JS、CSS 等)的最终优化。

    compilation.hooks.optimizeAssets.tapAsync('MyPlugin', (assets, callback) => {
      console.log('资源优化阶段');
      callback();
    });
    

# 输出阶段钩子

这些钩子在 Webpack 将编译结果输出到文件系统之前触发,用于修改输出内容。

  • emit: 在 Webpack 输出文件到输出目录之前触发,可以用来修改生成的文件或新增文件。

    compilation.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      console.log('文件写入前');
      callback();
    });
    
  • afterEmit: 在 Webpack 输出文件之后触发,适用于在文件写入后进行一些操作。

    compilation.hooks.afterEmit.tapAsync('MyPlugin', (compilation, callback) => {
      console.log('文件写入后');
      callback();
    });
    

# 完成阶段钩子

这些钩子在 Webpack 完成整个编译和打包过程时触发,通常用于收尾工作和资源清理。

  • done: 在 Webpack 编译完成后触发,可以获取整个编译过程的详细信息。

    compiler.hooks.done.tap('MyPlugin', (stats) => {
      console.log('编译完成');
    });
    
  • failed: 在编译失败时触发,可以捕获错误信息并进行相应处理。

    compiler.hooks.failed.tap('MyPlugin', (error) => {
      console.log('编译失败');
    });
    
  • invalid: 在文件变更使得 Webpack 处于无效状态时触发。

    compiler.hooks.invalid.tap('MyPlugin', (fileName, changeTime) => {
      console.log(`文件 ${fileName} 变更于 ${changeTime}`);
    });
    
  • watchRun: 在 Webpack 处于 watch 模式下,检测到文件变更时触发。

    compiler.hooks.watchRun.tapAsync('MyPlugin', (compiler, callback) => {
      console.log('检测到文件变更,重新编译');
      callback();
    });
    

# 高级钩子

这些钩子为开发者提供了更细粒度的控制和扩展能力。

  • beforeCompileafterCompile: 分别在编译之前和之后触发,可以用于自定义编译逻辑。

  • make: 在构建编译时触发,用于异步创建模块和资源。

    compiler.hooks.make.tapAsync('MyPlugin', (compilation, callback) => {
      console.log('构建模块');
      callback();
    });
    
  • seal: 在构建即将完成时触发,可以用来控制构建的最终步骤。

    compilation.hooks.seal.tap('MyPlugin', () => {
      console.log('构建封装阶段');
    });