Q5 · Webpack

是否写过 plugin?简单描述一下编写 plugin 的思路?

WebpackpluginTapable

⚡ 速记答案(30 秒)

  • Plugin 通过钩子机制(Tapable)深度参与 Webpack 生命周期
  • 通常写成一个类,提供 apply(compiler) 方法
  • compilercompilation 的钩子上 tap/tapAsync/tapPromise 注册回调
  • 在回调里可以:读取/修改模块、chunk、assets,插入文件、修改输出内容
  • 适合做:自动注入变量、生成额外文件、压缩/上传、打包分析等

📖 详细讲解

Plugin 机制


Webpack 基于 Tapable 实现事件驱动架构:


compiler.hooks.emit.tap('MyPlugin', (compilation) => {
  // 在输出前修改资源
});

常用钩子


钩子时机
beforeRun构建开始前
compile开始编译
emit输出文件前
done构建完成

Plugin 结构


class MyPlugin {
  apply(compiler) {
    compiler.hooks.emit.tap('MyPlugin', (compilation) => {
      // 处理逻辑
    });
  }
}

💻 代码示例

生成版本文件的 Plugin
class VersionPlugin {
  constructor(options = {}) {
    this.filename = options.filename || 'version.json';
  }

  apply(compiler) {
    compiler.hooks.emit.tap('VersionPlugin', (compilation) => {
      const version = {
        version: process.env.VERSION || '1.0.0',
        buildTime: new Date().toISOString(),
        gitHash: process.env.GIT_HASH || 'unknown',
      };

      const content = JSON.stringify(version, null, 2);

      compilation.assets[this.filename] = {
        source: () => content,
        size: () => content.length,
      };
    });
  }
}

module.exports = VersionPlugin;
💡
面试技巧:回答工程化问题时,结合你实际项目中的配置和优化经验,更有说服力。