金华市文章资讯

webpack5项目之基本配置详解

2026-04-12 06:21:02 浏览次数:0
详细信息
Webpack 5 项目基本配置详解

一、Webpack 核心概念

1.1 Webpack 是什么?

Webpack 是一个静态模块打包器,它将所有资源(JS、CSS、图片等)视为模块,通过依赖关系构建依赖图,最终打包成浏览器可识别的静态资源。

1.2 五个核心概念

二、基础项目配置

2.1 项目初始化

# 创建项目目录
mkdir webpack5-demo
cd webpack5-demo

# 初始化package.json
npm init -y

# 安装Webpack
npm install webpack webpack-cli --save-dev

2.2 目录结构

webpack5-demo/
├── src/
│   ├── index.js          # 入口文件
│   ├── styles/
│   │   └── main.css
│   └── assets/
│       └── images/
├── public/
│   └── index.html
├── dist/                 # 打包输出目录
├── webpack.config.js     # Webpack配置文件
└── package.json

三、基础配置文件详解

3.1 基础配置(webpack.config.js)

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // 1. 入口配置
  entry: {
    main: './src/index.js',
    vendor: './src/vendor.js'  // 多入口示例
  },

  // 2. 输出配置
  output: {
    // 输出目录(绝对路径)
    path: path.resolve(__dirname, 'dist'),
    // 输出文件名,[name]对应入口的key,[contenthash]根据内容生成hash
    filename: '[name].[contenthash].bundle.js',
    // 清理dist目录
    clean: true,
    // 静态资源输出路径
    assetModuleFilename: 'assets/[hash][ext][query]'
  },

  // 3. 模式配置
  mode: 'development', // 'production' | 'development' | 'none'

  // 4. 开发服务器配置
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    // 热更新
    hot: true,
    // 开启gzip压缩
    compress: true,
    port: 8080,
    open: true,
    // 代理配置
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
        changeOrigin: true
      }
    }
  },

  // 5. 模块配置(Loader配置)
  module: {
    rules: [
      // CSS处理
      {
        test: /\.css$/i,
        use: [
          'style-loader',  // 将CSS插入到DOM
          'css-loader'     // 解析CSS文件
        ],
      },

      // SCSS/SASS处理
      {
        test: /\.s[ac]ss$/i,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ],
      },

      // 图片资源处理
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'images/[hash][ext][query]'
        }
      },

      // 字体文件处理
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },

      // Babel配置(JS/JSX转译)
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              '@babel/preset-env',
              '@babel/preset-react'
            ],
            plugins: [
              '@babel/plugin-transform-runtime'
            ]
          }
        }
      },

      // TypeScript处理
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      }
    ],
  },

  // 6. 插件配置
  plugins: [
    // 生成HTML文件
    new HtmlWebpackPlugin({
      title: 'Webpack5 Demo',
      template: './public/index.html',
      filename: 'index.html',
      // 压缩HTML
      minify: {
        collapseWhitespace: true,
        removeComments: true,
        removeRedundantAttributes: true,
        useShortDoctype: true
      }
    }),

    // 复制静态文件(示例)
    // new CopyWebpackPlugin({
    //   patterns: [
    //     { from: 'public/favicon.ico', to: 'favicon.ico' }
    //   ]
    // })
  ],

  // 7. 解析配置
  resolve: {
    // 自动解析扩展名
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
    // 路径别名
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components'),
      '@utils': path.resolve(__dirname, 'src/utils')
    }
  },

  // 8. 优化配置
  optimization: {
    // 代码分割
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        // 第三方模块
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
        // 公共模块
        common: {
          minChunks: 2,
          name: 'common',
          chunks: 'all',
          priority: -10
        }
      }
    },
    // 最小化
    minimizer: [
      // 生产环境自动添加TerserPlugin(压缩JS)
      `...`, // 继承默认的minimizer
    ],
  },

  // 9. 性能提示
  performance: {
    hints: 'warning', // 'error' | 'warning' | false
    maxAssetSize: 200000, // 200kb
    maxEntrypointSize: 400000, // 400kb
  }
};

四、开发环境与生产环境分离配置

4.1 配置文件拆分

创建三个配置文件:

4.2 公共配置文件(webpack.common.js)

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js',
  },

  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
    ],
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],

  resolve: {
    extensions: ['.js', '.jsx'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
  },
};

4.3 开发环境配置(webpack.dev.js)

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'development',

  devtool: 'eval-source-map', // 源码映射

  devServer: {
    static: './dist',
    hot: true,
    port: 8080,
    open: true,
    historyApiFallback: true, // 支持SPA路由
  },

  optimization: {
    minimize: false, // 开发环境不压缩
  },

  // 开发环境性能提示关闭
  performance: {
    hints: false,
  },
});

4.4 生产环境配置(webpack.prod.js)

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',

  devtool: 'source-map', // 生产环境源码映射

  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          MiniCssExtractPlugin.loader, // 提取CSS为单独文件
          'css-loader',
        ],
      },
    ],
  },

  plugins: [
    // 提取CSS到单独文件
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
      chunkFilename: '[id].[contenthash].css',
    }),
  ],

  optimization: {
    minimizer: [
      new TerserPlugin(), // 压缩JS
      new CssMinimizerPlugin(), // 压缩CSS
    ],

    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      },
    },

    runtimeChunk: 'single', // 运行时代码单独打包
  },

  performance: {
    hints: 'warning',
    maxEntrypointSize: 512000,
    maxAssetSize: 512000,
  },
});

4.5 package.json脚本配置

{
  "scripts": {
    "start": "webpack serve --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js",
    "build:analyze": "webpack --config webpack.prod.js --profile --json > stats.json",
    "dev": "webpack serve --config webpack.dev.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

五、常用Loader和插件详解

5.1 常用Loader

Loader 作用 安装命令
babel-loader 转译ES6+代码 npm install -D babel-loader @babel/core @babel/preset-env
css-loader 解析CSS文件 npm install -D css-loader
style-loader 将CSS注入DOM npm install -D style-loader
sass-loader 编译Sass/SCSS npm install -D sass-loader sass
less-loader 编译Less npm install -D less-loader less
postcss-loader 处理CSS兼容性 npm install -D postcss-loader postcss autoprefixer
file-loader 处理文件资源 npm install -D file-loader
url-loader 小文件转base64 npm install -D url-loader
ts-loader 编译TypeScript npm install -D ts-loader typescript

5.2 常用插件

插件 作用 安装命令
HtmlWebpackPlugin 生成HTML文件 npm install -D html-webpack-plugin
MiniCssExtractPlugin 提取CSS为单独文件 npm install -D mini-css-extract-plugin
CleanWebpackPlugin 清理输出目录 npm install -D clean-webpack-plugin
CopyWebpackPlugin 复制静态文件 npm install -D copy-webpack-plugin
DefinePlugin 定义环境变量 Webpack内置
ProvidePlugin 自动加载模块 Webpack内置
BundleAnalyzerPlugin 分析包大小 npm install -D webpack-bundle-analyzer

六、高级配置技巧

6.1 环境变量配置

// webpack.config.js
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
      'process.env.API_URL': JSON.stringify(process.env.API_URL),
    }),
  ],
};

6.2 缓存配置

module.exports = {
  cache: {
    type: 'filesystem', // 使用文件系统缓存
    cacheDirectory: path.resolve(__dirname, '.temp_cache'),
    buildDependencies: {
      config: [__filename], // 当配置文件改变时,使缓存失效
    },
  },

  output: {
    filename: '[name].[contenthash].js', // 内容hash
  },
};

6.3 排除外部依赖

module.exports = {
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
    lodash: '_',
    jquery: 'jQuery',
  },
};

七、最佳实践建议

7.1 性能优化

使用多线程/多进程构建

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true, // 开启多线程
      }),
    ],
  },
};

合理配置splitChunks

optimization: {
  splitChunks: {
    chunks: 'all',
    minSize: 20000, // 最小20kb
    maxSize: 0,
    minChunks: 1,
    maxAsyncRequests: 30,
    maxInitialRequests: 30,
    automaticNameDelimiter: '~',
    cacheGroups: {
      defaultVendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
        reuseExistingChunk: true,
      },
      default: {
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true,
      },
    },
  },
}

7.2 开发体验优化

配置source map

// 开发环境
devtool: 'cheap-module-source-map',

// 生产环境
devtool: 'source-map',

配置热更新

devServer: {
  hot: true,
  liveReload: false,
},

八、完整示例配置

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

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

  return {
    entry: './src/index.js',

    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: isProduction 
        ? '[name].[contenthash].js' 
        : '[name].bundle.js',
      chunkFilename: isProduction 
        ? '[name].[contenthash].chunk.js' 
        : '[name].chunk.js',
    },

    mode: isProduction ? 'production' : 'development',

    devtool: isProduction ? 'source-map' : 'eval-source-map',

    devServer: {
      static: './dist',
      hot: true,
      port: 3000,
      open: true,
      historyApiFallback: true,
    },

    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: 'babel-loader',
        },
        {
          test: /\.css$/,
          use: [
            isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
            'css-loader',
            'postcss-loader',
          ],
        },
        {
          test: /\.(png|jpg|gif|svg)$/,
          type: 'asset/resource',
        },
      ],
    },

    plugins: [
      new HtmlWebpackPlugin({
        template: './public/index.html',
      }),
      ...(isProduction 
        ? [new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css',
          })]
        : []
      ),
    ],

    optimization: {
      splitChunks: {
        chunks: 'all',
      },
    },
  };
};

总结

Webpack 5 的配置虽然复杂,但理解其核心概念和配置项后,可以根据项目需求灵活配置。建议:

从简单配置开始,逐步添加功能 分离开发和生产环境,使用webpack-merge 合理使用缓存,提升构建速度 定期分析打包结果,优化打包体积 保持Webpack和相关依赖更新

通过合理配置Webpack,可以显著提升开发效率和项目性能。

相关推荐