出处:掘金

原作者:前端微白


Loader 与 Plugin 区别

维度LoaderPlugin
工作阶段文件加载时(单文件处理)整个构建周期(全局操作)
功能转换文件内容扩展构建能力
典型场景编译 JSX/SASS资源优化/环境注入
  • Loader 像流水线工人:负责单文件加工
  • Plugin 像监工:协调整个流水线

Loader 核心:文件转换引擎

1. babel-loader:JS 语法兼容

  • 作用:将 ES6+/TypeScript 代码降级为浏览器兼容的 ES5,支持新特性使用
  • 实战场景:在开发跨端项目时,需兼容低版本 iOS 系统
  • 对比方案:直接使用 @babel/core 编译会增加配置复杂度,babel-loader 与 Webpack AST 解析深度集成,可复用解析结果减少重复计算
// webpack.config.js  
module.exports = {  
  module: {  
    rules: [  
      {  
        test: /\.js$/,  
        exclude: /node_modules/, // 关键!避免编译已兼容代码  
        use: {  
          loader: 'babel-loader',  
          options: {  
            presets: [  
              ['@babel/preset-env', { targets: "iOS >= 9, Chrome > 60" }]  
            ]  
          }  
        }  
      }  
    ]  
  }  
}

2. css-loader + style-loader:CSS 模块化处理

  • 作用:
    • css-loader:解析 @importurl() 语句
    • style-loader:将 CSS 动态注入 DOM(<style> 标签)
  • 优化技巧:生产环境推荐使用 mini-css-extract-plugin,避免样式闪烁问题

3. sass-loader:预处理器支持

  • 作用:编译 Sass/SCSS 文件为 CSS,支持变量、嵌套等高级特性

4. thread-loader:并行编译

  • 作用:将耗时的 Loader(如 babel)放在独立线程运行,加速构建
  • 效果:在 8 核机器上,TS 项目构建时间从 45s → 12s
{  
  test: /\.js$/,  
  use: [  
    {  
      loader: 'thread-loader',  
      options: { workers: 4 } // 根据 CPU 核心数配置  
    },  
    'babel-loader' // 后续 loader 在 worker 线程运行  
  ]  
}

Plugin 核心:构建流程扩展

1. HtmlWebpackPlugin:HTML 模板管理

  • 作用:自动生成 HTML 入口文件,注入打包后的资源路径
  • 痛点解决:
    • 手动维护 HTML 中 JS/CSS 路径易出错
    • 多入口场景需重复配置
// 自动注入所有 chunk  
new HtmlWebpackPlugin({  
  template: './src/index.html', // 自定义模板  
  filename: 'home.html',  
  chunks: ['vendors', 'home'] // 仅注入指定 chunk  
})

2. MiniCssExtractPlugin:CSS 文件分离

  • 作用:提取 CSS 到独立文件,避免 JS 加载造成的样式延迟(FOUC 问题)
  • 对比方案:
方案开发环境生产环境特点
style-loader样式内联
MiniCssExtractPlugin独立 CSS 文件
// 替代 style-loader  
const MiniCssExtractPlugin = require('mini-css-extract-plugin');  
module.exports = {  
  plugins: [new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' })],  
  module: {  
    rules: [  
      {  
        test: /\.css$/,  
        use: [MiniCssExtractPlugin.loader, 'css-loader'] // 链式调用  
      }  
    ]  
  }  
};

3. DefinePlugin:环境变量注入

  • 作用:编译时注入全局常量,消除环境配置硬编码
  • 实战场景:区分开发/生产环境 API 地址
  • 安全提示:避免直接注入敏感信息(如密钥),应结合 .gitignore 管理
// webpack.prod.js  
new webpack.DefinePlugin({  
  'process.env.API_BASE': JSON.stringify('https://api.prod.com')  
});
 
// webpack.dev.js  
new webpack.DefinePlugin({  
  'process.env.API_BASE': JSON.stringify('https://api.dev.com')  
});
 
// 代码中使用  
axios.get(`${process.env.API_BASE}/user`);

4. SplitChunksPlugin:代码拆分

  • 作用:智能分离公共依赖(如 react、lodash),提升缓存利用率
  • 缓存收益:用户仅需下载变更的业务代码,公共文件命中缓存
optimization: {  
  splitChunks: {  
    chunks: 'all',  
    cacheGroups: {  
      vendors: {  
        test: /[\\/]node_modules[\\/]/,  
        name: 'vendors',  
      }  
    }  
  }  
}