第三方配置工具

webpack-merge

webpack-mergeopen in new window提供一个merge函数去联结数组和合并对象,以创建一个新的对象。

  • merge(...configuration | [...configuration]),合并配置对象
  • mergeWithCustomize({ customizeArray, customizeObject })(...configuration | [...configuration]),自定义策略来合并配置对象
    • customizeArray,自定义合并数组类型的配置项
    • customizeObject,自定义合并对象类型的配置项
    • unique(<field>, <fields>, field => field),强制使某个配置项具有唯一性,最常用于插件,可确保某个插件只有一个实例。
  • mergeWithRules,主要用于合并rules

webpack-chain

vue.config.js

参考文档:

vue-cli工具的配置文件vue.config.js里既可以通过webpack-merge也可以通过webpack-chain来新增/修改 Webpack 的配置项。

configureWebpack

configureWebpack配置项支持两种配置方式,

  1. 提供一个对象,该对象将会被webpack-merge合并入最终的 webpack 配置。
  2. 提供一个函数,函数的第一个参数是已经解析好的配置(包含了内置的配置和调用chainWebpack获得的配置)。在函数内,你可以直接修改配置,或者返回一个将会被合并的对象。

chainWebpack

配置合并优先级

configureWebpack > chainWebpack > vue-cli内置配置

这个结论是学习vue-cli的源码里的Service.initopen in new window方法和Service.resolveWebpackConfigopen in new window方法得出的:

  • Service.init方法里,会将vue.config.js里的configureWebpack选项pushservice.webpackRawConfigFns数组,chainWebpack选项pushservice.webpackChainFns数组
  • Service.resolveWebpackConfig方法里,在解析 Webpack 配置时,会先执行service.webpackChainFns数组里的所有函数,再执行service.webpackRawConfigFns数组里的所有函数

因此configureWebpack的优先级高于chainWebpack

注意

在合并configureWebpack选项的配置对象之前(无论选项的值是个配置对象,还是个返回配置对象的函数),都会先将内置的webpack-chainconfig对象(可能经过chainWebpack选项做了修改)转换为 Webpack 原生的配置对象,代码详见https://github.com/vuejs/vue-cli/blob/7f3d51133635114528848b29e27084ee89d53e1c/packages/%40vue/cli-service/lib/Service.js#L261open in new window

因此,configureWebpack选项(值为函数时)的参数configchainWebpack选项的参数config不是同一类对象。

  • chainWebpack: config => { ... }: config参数是由webpack-chain里通过new Config()产生的实例对象
  • configureWebpack: config => { ... }: config参数是由webpack-chainconfig实例经过config.toConfig()产生的 Webpack 原生配置对象

常用配置说明

// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
    // ...
    chainWebpack: config => {
        // 注意,这里的 config 参数是 webpack-chain 里通过 new Config() 获取来的,
        // 与 configureWebpack 配置项(值为函数时)的 config 参数不一样

        // 可视化依赖分析
        config.plugin('bundle-analyzer').use(BundleAnalyzerPlugin, [
            {
                generateStatsFile: true
            }
        ]);

        // 关闭代码压缩(方式一),可在追查 bug 时关闭,详见 https://webpack.js.org/configuration/optimization/#optimizationminimize
        config.optimization.minimize(false);

        // 删除 ts 规则上的 cache-loader。
        // BTW,vue-cli 默认会给 .vue/.ts/.tsx 添加 cache-loader
        config.module.rule('ts').uses.delete('cache-loader');
    },

    configureWebpack: config => {
        // 注意,这里的 config 参数是个 webpack raw object,与 chainWebpack 里拿到的 config 不一样
        // 可参考 关闭代码压缩 的两种方式,比较这两个 config 的区别

        // 设置 devtool
        if (p rocess.env.NODE_ENV === 'production') {
            config.devtool = 'source-map';
            config.output.sourceMapFilename =
                '../' + process.env.UNI_PLATFORM + '/[name].js.map';
        }

        // 关闭代码压缩(方式二)
        config.optimization.minimize = false;
    },

    // 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。
    // https://cli.vuejs.org/zh/config/#transpiledependencies
    transpileDependencies: [
        'vue' // 仅示例,实际上引用 vue 之前其已经编译过
    ],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44