webpack详细打包配置,包含性能优化、资源处理...

以下是一个详细的 Webpack 5 配置示例,包含常见资源处理和性能优化方案:

javascript 复制代码
const path = require('path');
const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';

  return {
    entry: './src/index.js',
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: isProduction 
        ? 'js/[name].[contenthash:8].js' 
        : 'js/[name].js',
      chunkFilename: isProduction
        ? 'js/[name].[contenthash:8].chunk.js'
        : 'js/[name].chunk.js',
      assetModuleFilename: 'assets/[hash][ext][query]',
      clean: true,
    },
    mode: isProduction ? 'production' : 'development',
    devtool: isProduction ? 'source-map' : 'eval-cheap-module-source-map',
    resolve: {
      extensions: ['.js', '.jsx', '.json'],
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
      modules: ['node_modules', path.resolve(__dirname, 'src')],
    },
    module: {
      rules: [
        // JavaScript/JSX 处理
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
            }
          }
        },
        // CSS 处理
        {
          test: /\.css$/,
          use: [
            isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
            {
              loader: 'css-loader',
              options: {
                importLoaders: 1,
                modules: {
                  auto: true,
                  localIdentName: isProduction
                    ? '[hash:base64]'
                    : '[path][name]__[local]',
                },
              },
            },
            'postcss-loader',
          ]
        },
        // 图片处理
        {
          test: /\.(png|jpe?g|gif|webp|svg)$/,
          type: 'asset',
          parser: {
            dataUrlCondition: {
              maxSize: 10 * 1024, // 10kb 以下转 base64
            }
          }
        },
        // 字体处理
        {
          test: /\.(woff2?|eot|ttf|otf)$/,
          type: 'asset/resource',
        },
      ]
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './public/index.html',
        minify: isProduction,
      }),
      isProduction && new MiniCssExtractPlugin({
        filename: 'css/[name].[contenthash:8].css',
        chunkFilename: 'css/[name].[contenthash:8].chunk.css',
      }),
      new webpack.ProgressPlugin(),
      new BundleAnalyzerPlugin({
        analyzerMode: 'disabled', // 不自动打开
        generateStatsFile: true, // 生成 stats.json
      }),
    ].filter(Boolean),
    optimization: {
      minimize: isProduction,
      minimizer: [
        new TerserPlugin({
          parallel: true,
          extractComments: false,
          terserOptions: {
            compress: {
              drop_console: true,
            }
          }
        }),
        new CssMinimizerPlugin(),
      ],
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            chunks: 'all',
          },
          common: {
            minChunks: 2,
            name: 'common',
            chunks: 'all',
            priority: 10,
            reuseExistingChunk: true,
          }
        }
      },
      runtimeChunk: {
        name: entrypoint => `runtime-${entrypoint.name}`,
      },
    },
    performance: {
      maxEntrypointSize: 512 * 1024, // 512kb
      maxAssetSize: 512 * 1024,
      hints: isProduction ? 'warning' : false,
    },
    devServer: {
      static: {
        directory: path.join(__dirname, 'public'),
      },
      compress: true,
      port: 3000,
      hot: true,
      historyApiFallback: true,
      client: {
        overlay: {
          errors: true,
          warnings: false,
        },
      },
    },
  };
};

主要优化配置解析:

  1. 代码分割 (Code Splitting)

    • 通过 splitChunks 配置自动拆分第三方库(vendor)和公共代码
    • 单独提取 runtime 代码
    • 动态导入实现按需加载
  2. 缓存策略

    • 输出文件名使用 [contenthash]
    • 使用 babel-loadercacheDirectory
    • 使用 HardSourceWebpackPlugin (需单独安装)
  3. 资源优化

    • 图片小于 10KB 转为 base64
    • 自动压缩 CSS 和 JS
    • 移除 console 语句
    • Tree Shaking (生产模式自动启用)
  4. 构建性能优化

    • 使用 thread-loader 并行处理(需单独添加)
    • 缩小 loader 作用范围(exclude: /node_modules/)
    • 使用更快的 swc-loader 替代 babel(实验性)
  5. 开发体验优化

    • 热模块替换(HMR)
    • 更快的 source-map 策略
    • 进度显示
  6. 分析工具

    • 生成构建分析报告(stats.json)
    • 使用 webpack-bundle-analyzer

扩展优化建议:

  1. PWA 支持

    javascript 复制代码
    const WorkboxPlugin = require('workbox-webpack-plugin');
    // 添加 plugins
    new WorkboxPlugin.GenerateSW({
      clientsClaim: true,
      skipWaiting: true,
    })
  2. 预加载关键资源

    javascript 复制代码
    new HtmlWebpackPlugin({
      // ...
      preload: 'initial',
      prefetch: ['asyncChunk'],
    })
  3. CDN 加速

    javascript 复制代码
    output: {
      publicPath: 'https://cdn.example.com/',
    }
  4. DLL 加速构建

    javascript 复制代码
    new webpack.DllReferencePlugin({
      manifest: require('./dll/vendor-manifest.json')
    })
  5. 多线程处理

    javascript 复制代码
    {
      test: /\.js$/,
      use: [
        'thread-loader',
        'babel-loader'
      ]
    }

根据项目实际需求选择优化策略,建议通过以下命令分析构建结果:

bash 复制代码
npx webpack --profile --json > stats.json

然后使用 Webpack Analysewebpack-bundle-analyzer 分析打包结果。

相关推荐
恋猫de小郭5 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅11 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606112 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了12 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅12 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅13 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅13 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅13 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊13 小时前
jwt介绍
前端