前端工程(vue)多环境配置方案

8,528 阅读2分钟

前言

一个前端工程从开发到上线务必会运行在多种环境中,同时会对环境变量进行相应的配置,如果使用人力去对这些变量进行维护,那么必然会出现错误,所以这个功能交给 webpack 去做最为合适。

webpack相关功能简介

webpack配置项中有一个mode选项,可配置的有 production development 两个选项,标识这次打包是用于什么模式,在项目代码中可使用如下代码进行读取:

if (process.env.NODE_ENV === 'production') {
    BASE_URL = 'https://host/production/api'
} else if (process.env.NODE_ENV === 'development') {
    BASE_URL = 'https://host/development/api'
}

使用此方式,可以分别对生产和开发模式的api分别进行配置,而不需要每次打包都进行修改,如果需要向进程中添加其它的变量,那么可以使用 webpack.DefinePlugin 来进行个性化定制,使用方式如下:

// webpack.base.js
const webpack = require('webpack')
webpackConfig = {
    plugins: [
        new webpack.DefinePlugin({
            SOME_CONFIG: `"localhost"`
        })
    ]
}

其中需要注意的一点是 '"localhost"', 如果是定义一个字符串,那么需要双重引号包裹。

vue工程的环境变量配置

如果使用vue cli3进行项目初始化,也可以很方便的进行环境配置,具体说明请看官方说明cli.vuejs.org/zh/guide/mo…

但是这种配置具有一定的局限性,按照文档来看最多只能支持到三种环境,一旦工程超出三种运行环境,那么 vue cli 就无法支持到了,所以自定义一套环境配置方案更利于扩展。

后续更新

经评论的同学提示,再仔细看了看官方文档,貌似是可以支持超过三种环境配置的,囧,不过这个配置思路是可以运用到其它工程中,所以还是保留文章。

webpack-chain

因为 vue cli3 对 webpack 进行了高度的封装,所以没办法像 vue cli2 一样随意的修改源配置文件,但是 cli3 抛出了 webpack-chain 来对默认配置进行个性化定制,用法示例如下:

// vue.config.js
chainWebpack: config => {
    config.module
        .rule('js')
        .exclude
        .add(/\.min\.js$/)
        .end()

    config
        .output
        .set('filename', `js/[name].[hash:8]-v${__VERSION__}.js`)
        .set('chunkFilename', `js/[id].[hash:8]-v${__VERSION__}.js`)
}

在进行配置之前,先看看 vue cli 对于环境变量这一块是如何配置的, 在工程根目录运行:

vue inspect > output.js

会生成一个output.js文件,打开后滚动到最底部,在1080行左右可以看到这样一个配置:

/* config.plugin('define') */
new DefinePlugin({
    'process.env': {
        NODE_ENV: '"development"'
    }
})

修改这个配置,就能向进程中添加其它的环境变量。

egg.js的环境变量配置

最近在使用 egg.js 时感受到了 egg 环境变量配置带来的便利,具体看这里,于是决定模仿egg的做法,将此方案集成到 vue cli3 中。

环境的区分

对于配置的修改后面再进行讲解,先讲解如何区分不同的环境。对于环境的区分,可以在运行打包命令时预先设定一个标签,这里可以使用 cross-env 来进行设置 vue cli 的环境变量,代码示例如下:

{
    "scripts": {
        "serve": "cross-env run_server=development vue-cli-service serve -mode development",
        "build": "npm run build:dll && cross-env run_server=production vue-cli-service build --no-clean",
        "build:UAT": "npm run build:dll && cross-env run_server=uat vue-cli-service build --no-clean",
    }
}

这里为 run_server 定义了三种不同的值 developmentproductionuat,分别对应不同的服务环境,那么在打包时,只要运行不同的 script 脚本就能获取到相关的环境变量并添加到构建进程中。

环境变量的配置

在工程根目录建立如下文件:

image

简单的配置示例:

// development_server.json
{
    "VUE_APP_RUN_ENV": "DevelopmentServer",
    "SERVER_IP": "/api",
    "DEV_PORT": 80,
    "SERVER_DOMAIN": "www.google.com",
    "PROXY_TARGET_IP": "http://192.168.2.236:8989"
}

在 vue.config.js 中添加如下代码

const RUN_SERVER = process.env.run_server || 'development'
const DefaultENVConfig = require('./env_config/default.json')
const serverEnvConfig = Object.assign({}, DefaultENVConfig, require('./env_config/' + RUN_SERVER + '_server.json'))

通过传入的目标环境,获取到对应的配置文件。同时使用 Object.assign 函数,将目标环境配置与默认环境配置合并得到最终的环境变量配置,再使用 webpack-chain 将之写入webpack打包配置:

// vue.config.js
module.exports = {
    chainWebpack: config => {
        config.plugin('define').tap(args => {
            for (let i in serverEnvConfig) {
                args[0]['process.env'][i] = `"${serverEnvConfig[i]}"`
            }
            return args
        })
    }
}

就这样,很简单的代码实现了多环境配置,如果需要添加一个全新的环境,那么只需要添加一个配置文件,同时将配置文件名设置到打包命令中就行了。