Skip to content

四.环境配置

前言

前端项目开发中,一般会有几个环境:

  • dev:是程序员们专门用于开发的服务器,配置可以比较随意, 为了开发调试方便,一般打开全部错误xx
  • sit:dev 环境完成需求开发就可以将代码打包到 sit 环境,给测试验证相关功能
  • uat:一般是克隆一份生产环境的配置,sit 测试没有问题就可以将代码打包到 uat 环境,然后由需求提出方验收需求
  • prod:uat 环境完成需求验收就可以将代码部署到正式环境
英文缩写英文中文示例是否必须主要用户
devDevelopment开发环境dev.zhoubichuan.com开发
sitSystem Integrate Test系统集成测试环境(内测)sit.zhoubichuan.com功能测试
uatUser Acceptance Test用户验收测试环境uat.zhoubichuan.com产品
petPerformance Evaluation Test性能评估测试环境(压测)pet.zhoubichuan.com性能测试
simSimulation高仿真环境sim.zhoubichua.com
prodProduction生产环境zhoubichua.com用户

1.vue-cli 2.x 中

1.1 配置环境

  • webpack 通过 DefinePlugin 内置插件将 process.env 注入到客户端代码中。
js
// config/dev.env.js
module.exports = merge(devEnv, {
  NODE_ENV: '"dev"', // 注意value值需要序列化
  BASE_API: '"http://dev.com"',
})
js
//build/webpack.dev.conf.js
const env = require('../config/dev.env')
...
{
  plugins: [
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV: env,
      },
    }),
  ],
}
...
  • 不同的打包/运行命令,打包/运行不同环境代码的同时将环境变量注入到打包/运行后的代码中 package.json
json
...
"scripts":{
  "dev":"vue-cli-service --mode dev",
  "sit":"vue-cli-service --mode sit",
  "build:dev":"vue-cli-service build --mode dev",
  "build:sit":"vue-cli-service build --mode sit"
}
...

1.2 使用环境变量

js
// main.js
console.log("环境变量:" + process.env.NODE_ENV)

2.vue-cli 3.x 中

2.1 配置文件

原理

在根目录下创建以下形式的文件进行不同环境下变量的配置,webpack 内部会按照一定的规则加载这些文件

bash
.env                 #在所有的环境中被载入
.env.local           #在所有的环境中被载入,但会被git忽略
.env.[mode]          #只在指定的模式中被载入,如.env.sit
.env.[mode].local    #只在指定的模式中被载入,但会被git忽略,如.env.sit.local
  • 1.配置命令

    json
    // package.json
    "scripts":{
      "serve:dev":"vue-cli-service serve --mode dev", //npm run serve:dev,dev运行命令,默认环境 development
      "build:dev":"vue-cli-service build --mode dev" //npm run build:dev,dev打包命令,默认环境 production
    }
  • 2.配置相关环境变量

    js
    // env.dev
    NODE_ENV=dev
    VUE_APP_BASE_URL=http://dev.com
    VUE_APP_TITLE=宇宙管理系统

    注意

    配置的变量需要以VUE_APP_开头,而NODE_ENVBASE_URL这两个特殊变量除外

  • 3.使用相关环境变量

    js
    //vue.config.js
    console.log(process.env.NODE_ENV) //dev
    js
    //src/utils/http.js
    axios.create({
      baseURL: process.env.VUE_APP_BASE_URL, // http://dev.com
      timeout: 500,
    })
  • 4.配置文件的权重

    由配置公共配置案例,可以得出结论,相同配置项的权重:
    • 全局公共配置

      js
      // .env
      NODE_ENV = development;
      VUE_APP_BASE_URL=http://base.com
      VUE_APP_TITLE=地球管理系统

      使用后可以得到:http://dev.com

    • 本地公共配置

      js
      // .env.local
      NODE_ENV = development;
      VUE_APP_BASE_URL=http://localhost.com
      VUE_APP_TITLE=abc管理系统

      使用后可以得到:http://localhost.com

    bash
    .env.[mode].local > .env.[mode] > .env.local > .env # 相同配置项权重大的覆盖小的,不同配置项它们会进行合并操作
  • 5.配置文件的局限性

    只能配置静态变量

    veu-cli3.x 封装的 webpack 中已经完成了这个功能,但是仅支持以VUE_APP_开头的变量(NODE_ENVBASE_URL除外)

    js
    NODE_ENV=stage2
    VUE_APP_TITLE=stage mode2
    NAME=vue

    然后我们尝试在 vue.config.js 中打印process.env终端输出:

    js
    {
      ...
      npm_config_ignore_scripts: '',
      npm_config_version_git_sign: '',
      npm_config_ignore_optional: '',
      npm_config_init_version: '1.0.0',
      npm_package_dependencies_vue_router: '^3.0.1',
      npm_config_version_tag_prefix: 'v',
      npm_node_execpath: '/usr/local/bin/node',
      NODE_ENV: 'stage2',
      VUE_APP_TITLE: 'stage mode2',
      NAME: 'vue',
      BABEL_ENV: 'development',
      ...
    }

    可以看到输出内容除了我们环境配置中的变量外还包含了很多 npm 的信息,但是我们在入口文件 main.js 中打印会发现输出:

    json
    {
      "BASE_URL": "/vue/",
      "NODE_ENV": "stage2",
      "VUE_APP_TITLE": "stage mode2"
    }

    可见注入时过滤了非VUE_APP_开头的变量,其中多出的BASE_URL为你在 vue.config.js 设置的值,默认为/,其在环境配置文件中设置无效。

2.2 环境注入

原理

webpack 通过 DefinePlugin 内置插件将 process.env 注入到客户端代码中。

js
//vue.config.js
{
  ...
  plugins:[
    new webpack.DefinePlugin({
      'process.env':{
        NODE_ENV:JSON.stringify(process.env.NODE_ENV)
      }
    })
  ]
  ...
}
  • 1.配置环境变量

    .env 这样的配置文件无法使用动态参数,这时候我们可以在根目录下新建 config 文件夹用于存放一些额外的配置文件。
    js
    // envConfig.js
    const com = {
      $Time: new Date().toLocaleString(), //注入项目打包时间信息,可以在页面加载时挂载到window上,方便查看更新时间
    }
    let config = {
      // 开发环境
      dev: {
        NODE_ENV: "dev",
        ...com,
      },
      //测试环境
      sit: {
        NODE_ENV: "sit",
        ...com,
      },
      //客户体验环境
      uat: {
        NODE_ENV: "uat",
        ...com,
      },
      // 生产环境
      prod: {
        NODE_ENV: "prod",
        ...com,
      },
    }
    Object.keys(config).forEach((item) => {
      Object.keys(config[item]).forEach((key) => {
        config[item][key] = JSON.stringify(config[item][key])
      })
    })
    module.exports = config
  • 2.注入环境变量

    js
    // vue.config.js
    const envConfig = require("./envConfig")
    const merge = require("webpack-merge")
    module.exports ={
      ...
      chainWebpack:config = {
        config.plugin('define')
        .tap(args => {
          let name = 'process.env'
          let env = process.argv[process.argv.length - 1]
          args[0][name] = merge(args[0][name],envConfig[env])
          return args
        })
      }
      ...
    }
  • 3.使用环境变量

    js
    {
      "NODE_ENV":"dev",
      "VUE_APP_TITLE":"stage mode2",
      "BASE_URL":"/vue/",
      "$Time":"xxx"
    }

3.场景应用

  • 接口调试

    有些项目比较复杂,接口 a 依赖接口 b,接口 b 依赖接口 c,中间还有很多页面流程需要走;如果在 postman 中调试接口很麻烦,有很多页面生成的数据要自己造,可以借用线上的前端开发环境,页面接口用本地的接口(直接优先使用在浏览器 localStorage 中的变量)

    js
    // commonUrl.js
    const url = "www.xxx.com"
    if (process.env.NODE_ENV !== "production") {
      url = localStorage.url || url
    }

总结

在 vue-cli2.x 和 3.x 中都可以利用 DefinePlugin 来配置环境变量,这种方式的优点在于更加灵活,而在 vue-cli3.x 中还支持配置静态文件类型的配置文件(.env 文件)这种方式配置更加直观。