标准答案

  1. Loader 面向单个或一类模块转换,例如把 TypeScript、Sass、图片、Vue SFC 转成可参与依赖图的模块。
  2. Loader 通常以链式方式从右到左执行,上一个 loader 的输出会成为下一个 loader 的输入。
  3. Plugin 面向 Webpack 编译生命周期,可以在编译、优化、生成资源、输出文件等阶段做扩展。
  4. Loader 更像“文件转换器”,Plugin 更像“构建流程扩展点”。
  5. 实际项目中,资源处理优先考虑 loader,构建流程、产物优化、HTML 注入、环境变量注入等通常用 plugin。

题目解析

loader 和 plugin 的边界可以从作用范围理解。loader 处理的是模块进入依赖图前后的转换问题,比如浏览器不认识 Sass,就先转成 CSS;浏览器不直接运行 TS,就先转成 JS。

plugin 的位置更靠近构建系统本身。它不只看某个文件,而是可以拿到 compilation、assets、chunks 等构建上下文,所以适合做 HTML 生成、CSS 抽离、压缩、资源清单、构建分析。

回答时不要只背定义,最好能补一句选择方式:当问题是“这个文件如何被识别和转换”时想 loader;当问题是“构建过程某个阶段要额外做事”时想 plugin。

代码示例

一个典型配置里,loader 处理文件,plugin 处理构建流程。

JavaScript
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ]
}

常见误区

  • 把 loader 和 plugin 都说成“插件”,没有区分文件转换和构建生命周期扩展。
  • 不理解 loader 链的执行顺序,导致样式、Sass、PostCSS 等转换顺序配置错误。
  • 用 plugin 解决简单文件转换问题,或者用 loader 处理需要全局构建上下文的事情。

作者信息