首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用 webpack-merge 合并 webpack 配置

使用 webpack-merge 合并 webpack 配置

原创
作者头像
除除
发布2025-11-24 14:30:17
发布2025-11-24 14:30:17
40
举报
文章被收录于专栏:除除的专栏除除的专栏
使用 webpack-merge 合并 webpack 配置
使用 webpack-merge 合并 webpack 配置

内容声明

本文仅用于技术分享和学习交流,内容不包含任何广告、推广、引流、付费课程或外链信息。所有示例和配置均为技术实践,欢迎参考和自定义。


使用 webpack 搭建项目时会配置开发、测试、预发布、生产环境,这里面充斥着大量重复的配置,例如: 入口、加载器等。webpack-merge 作为 webpack 的配置合并工具,功能类似于 JavaScript 的 Object.assign()

快速安装:

代码语言:bash
复制
npm install -D webpack webpack-cli webpack-dev-server webpack-merge html-webpack-plugin clean-webpack-plugin mini-css-extract-plugin css-loader postcss-loader postcss postcss-preset-env sass sass-loader esbuild-loader

示例:

utils.js

代码语言:javascript
复制
const path = require('path');

const resolve = (...segments) => path.resolve(__dirname, ...segments);

module.exports = { resolve };

webpack.common.js

代码语言:javascript
复制
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { resolve } = require('./utils');

module.exports = {
  entry: {
    index: resolve('src/index.tsx')
  },
  output: {
    path: resolve('dist'),
    filename: '[name].js',
    assetModuleFilename: 'assets/[hash][ext][query]'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.json'],
    alias: {
      '@': resolve('src')
    }
  },
  module: {
    rules: [
      // 用 esbuild-loader 当作快速 TS/JS 转译器
      {
        test: /\.[jt]sx?$/,
        exclude: /node_modules/,
        loader: 'esbuild-loader',
        options: {
          loader: 'tsx', // 或 'ts' / 'jsx' / 'js'
          target: 'es2017'
        }
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024 // 小于 8kb 内联
          }
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)$/,
        type: 'asset/resource'
      }
      // 注意: 样式 loader 在各环境中不同 (见下面 dev/prod)
    ]
  },
  plugins: [
    new CleanWebpackPlugin(), // webpack 5 推荐简单用法
    new HtmlWebpackPlugin({
      template: resolve('src/index.html'),
      inject: 'body'
    })
  ],
  // 打开持久化缓存,在大多数场景下能显著加快二次构建
  cache: {
    type: 'filesystem'
  },
  stats: 'minimal'
};

webpack.dev.js

代码语言:javascript
复制
const { merge } = require('webpack-merge');
const common = require('./webpack.common');
const { resolve } = require('./utils');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'eval-cheap-module-source-map',
  output: {
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.s?css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: { sourceMap: true, importLoaders: 1 }
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [['postcss-preset-env', { stage: 3 }]]
              }
            }
          },
          'sass-loader'
        ]
      }
    ]
  },
  devServer: {
    static: { directory: resolve('dist') },
    hot: true,
    port: 3000,
    open: true,
    historyApiFallback: true
  }
});

webpack.prod.js

代码语言:javascript
复制
const { mergeWithRules } = require('webpack-merge');
const common = require('./webpack.common');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const prodConfig = {
  mode: 'production',
  devtool: 'source-map',
  output: {
    filename: '[name].[contenthash:8].js',
    clean: true // webpack 5 output.clean 可替代 CleanWebpackPlugin,在简单场景下更方便
  },
  module: {
    rules: [
      // 这里仅声明 test,实际 loader 通过 mergeWithRules 替换
      {
        test: /\.s?css$/
      }
    ]
  },
  optimization: {
    moduleIds: 'deterministic',
    runtimeChunk: 'single',
    splitChunks: {
      chunks: 'all',
      maxInitialRequests: 25,
      maxAsyncRequests: 50,
      // 缓存组配置可在此处展开
    }
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash:8].css'
    })
  ]
};

// 使用 mergeWithRules 将样式 loader 在生产环境里替换为 MiniCssExtractPlugin.loader + css + postcss + sass
const merged = mergeWithRules({
  module: {
    rules: {
      test: 'match',
      // use 数组用 replace (生产直接替换掉开发用的 style-loader)
      use: 'replace'
    }
  }
})(common, prodConfig);

// 供外部 require
module.exports = merged;

更新记录

本文首次编辑于 2020-08-28,最近更新于 2025-11-22。

版权声明

本文为原创文章,作者保留版权。转载请保留本文完整内容,并以超链接形式注明作者及原文出处。

作者: 除除

原文: http://blog.mazey.net/1724.html

(完)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档