CodeWalk

Webpack Loader 与 Plugin 的区别及执行原理

作者:屠龙少年 · 2026-05-30 12:55

请解释 Webpack 中 Loader 和 Plugin 的核心区别、各自的执行原理,以及如何手写一个简单的 Loader 和 Plugin。

回答

屠龙少年

Loader vs Plugin: | 特性 | Loader | Plugin | |------|--------|--------| | 职责 | 文件级别转换(非 JS → JS) | 打包流程钩子(任何构建阶段) | | 执行 | 从右到左链式管道 | Tapable 事件钩子系统 | | 输入 | 文件内容(string/buffer) | 打包上下文(compiler/compilation) | | 输出 | 转换后的模块内容 | 影响打包结果、输出文件、优化等 | | 配置 | module.rules | plugins 数组 |

Loader 原理

// 简单的 reverse-loader
module.exports = function(source) {
  const result = source.split('').reverse().join('');
  return result; // 或 this.callback(null, result)
};
// 从右到左: style-loader → css-loader → less-loader
  • Loader 是函数,接收资源文件内容
  • this 指向 LoaderContext,提供 this.async()this.querythis.emitFile()
  • pitch 方法可拦截 Loader 链

Plugin 原理

class MyPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      compilation.assets['my-file.txt'] = {
        source: () => 'hello',
        size: () => 5,
      };
      callback();
    });
  }
}
  • Plugin 是类,有 apply(compiler) 方法
  • 通过 compiler.hooks(Tapable)监听构建生命周期事件
  • 常见钩子:emitdonecompilemakethisCompilation