【Webpack】Plugin 的作用以及原理

🔹 1. Plugin 的作用

  • Webpack 的核心是事件流机制(基于 Tapable 库实现的发布订阅)。

  • Loader 主要解决「资源转换」问题,例如把 .ts 转成 .js,把 .scss 转成 .css

  • Plugin 用来扩展 Webpack 的功能,可以在 构建的不同生命周期阶段做额外的事情,比如:

    • 打包优化(压缩、抽离 CSS、代码分割)
    • 自动化任务(生成 HTML、拷贝文件、清理目录)
    • 自定义需求(打包后生成报告、输出额外文件等)

🔹 2. Plugin 的原理

  1. Webpack 内部有一个 Compiler 对象,代表整个编译过程。
  2. 每一次文件编译会生成一个 Compilation 对象,包含了当前构建模块的相关信息。
  3. Plugin 本质上是一个带有 apply 方法的类/函数apply 会在插件安装时被调用。
  4. compiler.hooks.xxx.tap(...) → 注册事件钩子。
  5. 在构建流程某个阶段触发钩子时执行插件逻辑。

👉 换句话说:Plugin 就是订阅 Webpack 生命周期事件,做你想做的事。


🔹 3. 手写一个简单的 Plugin

例子:HelloPlugin,在打包结束后输出一句话。

js 复制代码
class HelloPlugin {
  apply(compiler) {
    // compilation 代表每一次构建
    compiler.hooks.done.tap('HelloPlugin', (stats) => {
      console.log('✨ 打包完成啦!');
    });
  }
}

module.exports = HelloPlugin;

使用方式:

js 复制代码
// webpack.config.js
const HelloPlugin = require('./HelloPlugin');

module.exports = {
  plugins: [
    new HelloPlugin()
  ]
}

运行 webpack 时,打包结束会输出:

复制代码
✨ 打包完成啦!

🔹 4. 面试答法(简洁版)

Plugin 的作用是扩展 Webpack 的功能,它基于 Tapable 的事件流机制 ,通过在编译流程的不同钩子(如 compileemitdone)上挂载逻辑,来实现自动化和构建优化。

Plugin 的本质就是一个带有 apply 方法的类/函数 (接收一个 compiler 参数),apply 会在插件安装时被调用。函数内部通过 compiler.hooks.xxx.tap(...) → 注册事件钩子。

常见的做法有,比如在 emit 阶段把打包的资源输出到额外的目录,或者在 done 阶段输出构建日志。