Skip to content

Webpack 基本配置

webpack-merge

使用 webpack-marge 合并通用配置和特定环境配置。

  • webpack.common.js
js
module.exports = {}
  • webpack.dev.js
js
const { merge } = require('webpack-merge')
const common = require('./webpack.common')

module.exports = merge(common, {})
  • webpack.prod.js
js
const { merge } = require('webpack-merge')
const common = require('./webpack.common')

module.exports = merge(common, {})

entry(入口)

配置模块的入口

webpack 允许一个或多个入口配置

js
module.exports = {
  entry: 'index.js',
}

output(输出)

输出则是用于配置 webpack 构建打包的出口,如打包的位置,打包的文件名等等

  • webpack.dev.js
js
module.exports = merge(common, {
  // 输出
  output: {
    // bundle 文件名称
    filename: '[name].bundle.js',
    // bundle 文件路径
    path: resolveApp('dist'),
    // 编译前清除目录
    clean: true,
  },
})
  • webpack.prod.js
js
module.exports = {
  output: {
    // bundle 文件名称 【只有这里和开发环境不一样】
    filename: '[name].[contenthash].bundle.js',
    // bundle 文件路径
    path: resolveApp('dist'),
    // 编译前清除目录
    clean: true,
  },
}

Module(模块)

配置处理模块的规则

webpack 自带 JavaScript 和 JSON 文件的打包构建能力,无需格外配置。

而其他类型的文件,如 CSS、TypeScript,则需要安装 loader 来进行处理。

js
module.exports = {
  module: {
    rules: [{ test: /.txt$/, use: 'raw-loader' }],
  },
}

plugin(插件)

插件则是用于扩展 webpack 的能力,常见的插件有:

  • ProgressBarPlugin:编译进度条;
  • BundleAnalyzerPlugin:打包体积分析;
  • MiniCssExtractPlugin:提取 CSS 到独立 bundle 文件。
js
const HtmlWebpackPlugin = require('html-webpack-plugin') // 通过 npm 安装

module.exports = {
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
}

mode(模式)

通过 mode 配置选项,告知 webpack 使用相应模式的内置优化。

选项描述
development会将 DefinePluginprocess.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名。
production会将 DefinePluginprocess.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePluginFlagIncludedChunksPluginModuleConcatenationPluginNoEmitOnErrorsPluginTerserPlugin
  • webpack.dev.js
js
module.exports = merge(common, {
  // 开发模式
  mode: 'development',
})
  • webpack.prod.js
js
module.exports = merge(common, {
  // 生产模式
  mode: 'production',
})

resolve(解析)

resolve 用于设置模块如何解析,常用配置如下:

  • alias:配置别名,简化模块引入;
  • extensions:在引入模块时可不带后缀;
  • modules: 指定目录可缩小 webpack 解析范围,加快构建速度;
  • symlinks:用于配置 npm link 是否生效,禁用可提升编译速度。

alias

alias 可以创建 importrequire 的别名,用来简化模块引入

js
module.exports = {
  resolve: {
    alias: {
      '@': paths.appSrc, // @ 代表 src 路径
    },
  },
}

extensions

extensions 表示需要解析的文件类型列表。根据项目中的文件类型,定义 extensions,以覆盖 webpack 默认的 extensions,加快解析 速度。由于 webpack 的解析顺序是从左到右,因此要将使用频率高的文件类型放在左侧,如下我将 tsx 放在最左侧。

js
module.exports = {
  resolve: {
    extensions: ['.tsx', '.js'], // 因为我的项目只有这两种类型的文件,如果有其他类型,需要添加进去。
  },
}

modules

modules 表示 webpack 解析模块时需要解析的目录

js
module.exports = {
  modules: ['node_modules', paths.appSrc],
}

如果项目不使用 symlinks(例如 npm link 或者 yarn link),可以设置 resolve.symlinks: false,减少解析工作量

js
module.exports = {
  resolve: {
    symlinks: false,
  },
}

Source Map

为了更容易地追踪 error 和 warning,JavaScript 提供了 source maps 功能,可以将编译后的代码映射回原始源代码

source map 有许多 可用选项

js
module.exports = merge(common, {
  // 开发工具,开启 source map,编译调试
  devtool: 'eval-cheap-module-source-map',
})

DevServer

webpack-dev-server 提供了一个基本的 web server,并且具有实时重新加载功能

  • webpack.dev.js
js
module.exports = merge(common, {
  mode: 'development',
  devtool: dev.devtool,
  devServer: {
    host: dev.host,
    port: 'auto',
    proxy: dev.proxy,
    client: {
      logging: dev.logging,
      overlay: dev.errorOverlay,
    },
    static: {
      directory: dev.static,
      publicPath: dev.assetsPublicPath,
    },
    open: dev.autoOpenBrowser,
    compress: dev.compress,
    hot: true,
    historyApiFallback: true,
  },
  stats: {
    assets: false,
    chunks: false,
    chunkModules: false,
    modules: false,
  },
})

optimization(优化)

optimization 用于自定义 webpack 的内置优化配置,一般用于生产模式提升性能,常用配置项如下:

  • minimize:是否需要压缩 bundle;
  • minimizer:配置压缩工具,如 TerserPlugin、OptimizeCSSAssetsPlugin;
  • splitChunks:拆分 bundle;
  • runtimeChunk:是否需要将所有生成 chunk 之间共享的运行时文件拆分出来。
js
module.exports = {
  optimization: {
    minimizer: [
      // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
      // `...`,
      new CssMinimizerPlugin(),
    ],
    splitChunks: {
      // include all types of chunks
      chunks: 'all',
      // 重复打包问题
      cacheGroups: {
        vendors: {
          //node_modules里的代码
          test: /[\\/]node_modules[\\/]/,
          chunks: 'all',
          name: 'vendors', //chunks name
          priority: 10, //优先级
          enforce: true,
        },
      },
    },
  },
}

执行命令

通过 cross-env 配置环境变量,区分开发环境和生产环境

package.json

json
{
  "scripts": {
    "dev": "cross-env NODE_ENV=development webpack serve --open --config config/webpack.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js"
  }
}