Skip to content

webpack 配置文件(webpack.config.js)

Webpack 的配置文件是一个 Node.js 模块,它导出一个对象。这个对象告诉 Webpack 如何处理你的项目,从哪里开始、如何处理不同类型的文件、以及最终输出到哪里。

核心模块

shell
入口 (Entry)
输出 (Output)
模块 (Module)
插件 (Plugins)
模式 (Mode)
解析 (Resolve)
开发工具 (Devtool)
开发服务器 (DevServer) (用于开发环境)
优化 (Optimization)

配置选项

1、入口 (Entry)

entry 用来指定 Webpack 打包的起始文件。Webpack 会从这个文件开始,递归地查找所有依赖的模块。

shell
# 单入口
module.exports = {
  entry: './src/index.js'
};

# 多入口
module.exports = {
  entry: {
    app: './src/app.js',
    vendor: './src/vendor.js'
  }
};

2、输出 (Output)

output 配置项用来告诉 Webpack 打包后的文件应该输出到哪里,以及如何命名。

js
const path = require('path'); // Node.js 的 path 模块

module.exports = {
  // ...
  output: {
    filename: 'bundle.js', // 单入口时的文件名
    // 多入口时,可以使用占位符 [name]
    // filename: '[name].[contenthash].js', // [name] 会被替换为 entry 的键名, [contenthash] 是文件内容的哈希值,用于缓存控制
    path: path.resolve(__dirname, 'dist'), // 将打包后的文件输出到项目根目录下的 dist 文件夹
  },
};

3、模块 (Module)

Webpack 本身只能处理 JavaScript 和 JSON 文件。对于其他类型的文件(如 CSS, 图片,TypeScript 等),我们需要使用 Loader 来将它们转换为 Webpack 可以处理的模块。

js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i, // 匹配所有 .css 结尾的文件
        use: ['style-loader', 'css-loader'], // 自右向左执行:先 css-loader 再 style-loader,最终注入页面
        // 执行顺序(链上):css-loader → style-loader
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i, // 匹配图片文件
        type: 'asset/resource', // Webpack 5 新增的 Asset Modules,替代了 file-loader
        // 会将文件输出到 output.path 目录,并返回一个 URL。
      },
      {
        test: /\.m?js$/, // 匹配 JS 文件
        exclude: /node_modules/, // 排除 node_modules 目录
        use: {
          loader: 'babel-loader', // 使用 babel-loader 转译 JS,通常配合 @babel/preset-env 的 targets 指定语法目标
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  },
};

4、插件 (Plugins)

Loader 用于转换特定类型的文件,而 Plugin 则可以执行更广泛的任务,比如:打包优化、资源管理、注入环境变量、生成 HTML 文件等。

js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 生成 HTML 文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 将 CSS 提取到单独的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 亦可使用 output.clean: true(Webpack 5 内置)替代

module.exports = {
  // ...
  plugins: [
    new CleanWebpackPlugin(), // 在每次构建前清理 dist 文件夹
    new HtmlWebpackPlugin({
      template: './src/index.html', // 使用模板
      title: 'My App',
      minify: {
        // 压缩 HTML
        removeComments: true,
        collapseWhitespace: true,
      },
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css', // 提取后的 CSS 文件名
    }),
  ],
};

5、模式 (Mode)

mode 配置项可以启用 Webpack 内置的优化,它有三个可选值:development、production 或 none。

js
module.exports = {
  mode: 'development',
};

6、解析 (Resolve)

resolve 配置项用于设置模块如何被解析,比如如何查找模块文件、文件后缀名等。

js
const path = require('path');

module.exports = {
  // ...
  resolve: {
    extensions: ['.js', '.json', '.jsx', '.css'], // 尝试按这些后缀名查找文件
    alias: {
      '@': path.resolve(__dirname, 'src/'), // 将 @ 指向 src 目录
      components: path.resolve(__dirname, 'src/components/'),
    },
  },
};
// 使用时:import Header from '@/components/Header';

7、开发工具 (Devtool)

devtool 控制 Source Map 的生成方式与精度,便于调试;不同取值在「构建速度 / 产物体积 / 映射准确度」之间权衡。常用:eval-cheap-module-source-map(开发)、source-map(需完整映射时)、生产环境常关闭或仅用隐藏 Source Map。

js
module.exports = {
  devtool: 'eval-cheap-module-source-map',
};

8、开发服务器 (DevServer)

webpack-dev-server 是一个用于开发的小型 HTTP 服务器,它提供了实时重新加载(live reloading) 和 热模块替换(Hot Module Replacement, HMR) 功能。

js
module.exports = {
  // ...
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'), // Webpack 5 中 contentBase 被 static 取代
    },
    port: 9000,
    open: true,
    hot: true,
    compress: true,
    proxy: {
      '/api': {
        target: 'http://localhost:3000', // 后端 API 服务器地址
        pathRewrite: { '^/api': '' }, // 重写路径
      },
    },
  },
};

9、优化 (Optimization)

optimization 配置项用于自定义 Webpack 的优化策略。

js
module.exports = {
  // ...
  optimization: {
    splitChunks: {
      chunks: 'all', // 对所有类型的 chunks 进行分割(包括异步和同步)
      cacheGroups: {
        vendor: {
          // 提取第三方库
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      },
    },
  },
};

webpack 常见配置

js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/', // 配置公共路径,用于CDN或本地开发
  },
  devtool: 'eval-cheap-module-source-map',
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    port: 8080,
    open: true,
    hot: true,
    historyApiFallback: true, // 用于单页应用路由
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /\.css$/,
        use: [
          process.env.NODE_ENV === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
          'css-loader',
        ],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
  resolve: {
    extensions: ['.js', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src/'),
    },
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
};