【Webpack系列】配置项类型

104 阅读2分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

通常情况下,我们项目里的webpack配置文件都是都导出一个对象,但其实除了导出对象,还可以有其它的导出方式,列举如下

  • js对象,这也是最常见的方式
  • 函数,在用于获取 命令行参数 的场景下使用
  • promise,存在 异步处理 逻辑时使用
  • 数组,用于 多构建 场景

接下来分别介绍上述的类型

qidai.jpeg

js对象

这是最常见的场景,其实这也是我目前唯一使用过的方式 = =,使用方式很简单,直接导出一个对象就ok了,示例如下

  const path = require('path')

  module.exports = {
    entry: './src/entry.js',
    output: {
      path: path.join(__dirname,'dist'),
      filename: 'output.js'
    }
  }

这种方式没有需要深挖的东西,next!

函数

这种形式的实现方式就是导出一个函数,这个函数接受两个参数

  • 参数一是 环境对象,保存有所有通过 --env 传递的参数的对象,例如 npx webpack --env platform=app --env production # env.platform等于'app' env.production等于true
  • 参数二是保存有所有传递给 webpack-cli 的参数的对象,例如 npx webpack --mode production # argv.mode等于'production',可选的命令行参数列举如下
    • --entry:应用程序的入口文件
    • --config, -c:提供 webpack 配置文件的路径
    • --output-path, -o:webpack 生成文件的输出位置
    • --target, -t:设置要构建的 target
    • --watch, -w:监听文件变化
    • --hot, -h:启用 HMR
    • --mode:定义 webpack 所需的 mode
    • --version, -v:获取当前 cli 版本

示例如下:

  const path = require('path')

  module.exports = function(env, argv) {
    return {
      mode: env.production ? 'production' : 'development',
      devtool: env.production ? 'source-map' : 'eval',
      plugins: [
        new TerserPlugin({
          terserOptions: {
            compress: argv.mode === 'production'
          }
        })
      ]
    };
  };

promise

当需要 异步加载 webpack配置项时,就需要导出一个 promise, 支持使用 Promise.all 导出多个promise,示例如下

  module.exports = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({
          entry: './entry.js'
          /* ... */
        })
      }, 5000)
    })
  }

数组

这种方式在多targets(如 AMD 和 CommonJS)构建 library 时会非常有用,在webpack打包时,每一个配置项都会进行 各自的 打包工作,从而输出 不同的 构建产物,配置示例如下:

  module.exports = [
    {
      output: {
        filename: './dist-amd.js',
        libraryTarget: 'amd'
      },
      name: 'amd',
      entry: './app.js',
      mode: 'production'
    },
    {
      output: {
        filename: './dist-commonjs.js',
        libraryTarget: 'commonjs'
      },
      name: 'commonjs',
      entry: './app.js',
      mode: 'production'
    }
  ]

结语

虽然大多数场景下导出对象就足够用了,但掌握更多类型的使用方式可以满足特定场景下的需求,让我们更加从容面对不同的场景与挑战,这也是与其它人拉开差距的地方,所以,加油把,骚年!