vue多环境不同配置的正确打包方式

起因

最近新启动的一个Vue项目需要配置多个环境,不同的环境需要使用不同的API域名。

在以往的H5项目中,可以通过判断当前域名/域名+端口号(window.location.href)来区分devtestprd等不同环境,但这次新启动项目当然不想使用这么low的方式了,于是打算找找有什么好用的方法,还真找到了一种。

环境变量

在vue-cli文档模式和环境变量这一章中,提到了环境文件这个词。(文档传送门

过去在开发PHP程序时,为了区分不同的开发环境和线上环境的mysql、redis库,会引入一个名为.env环境变量文件。这个文件一般不会随着git提交而同步到代码仓库里,同时(运维人员)也会不同环境下配置各自的.env配置文件。(既能保证代码发布时无需改动就能切换环境,又保证开发不会获取到线上数据的操作权限)

当然了,vue-cli中的环境变量肯定是不一样的啦。文档里提到了默认存在developmenttestproduction三种模式,可以通过vue-cli-service build --mode 模式名来读取并使用对应模式的环境变量文件。通过测试我发现也可以使用自定义的模式名称,比如**test1****test2**都是可以的。

模式对应的环境变量文件规则如下:

那么问题来了,如果在production模式中.env.env.production同时存在某个环境变量名,最终会使用谁的值呢?

答:无论在任何模式中 .env.[模式名]的优先级都大于.env,所以会使用.env.production的变量值。

定义变量

环境变量的定义可以参考dotenvdotenv-expand,大致规则如下:

  • BASIC=basic 将变成{BASIC: 'basic'}
  • 空行将被跳过
  • 以#开头的行将被认为是注释
  • 空值将变成空字符串(如EMPTY= 变成 {EMPTY: ''}
  • 值内部的引号将被保留(JSON={"foo": "bar"}变成{JSON:"{\"foo\": \"bar\"}"
  • 未加引号的值两端的空格将被删除(FOO= some value变成{FOO: 'some value'}
  • 单引号值将被转义成双引号值(SINGLE_QUOTE='quoted'变成{SINGLE_QUOTE: "quoted"}
  • 单引号和双引号值将保持两端的空格(FOO=" some value "变成{FOO: ' some value '}
  • 双引号值内部的\n将变成换行

dotenv-expand的作用其实是使用$进行变量复用,例如:

1
2
3
4
A=HELLO
B=WORLD

CONCAT=$A$B # CONCAT=HELLOWORLD

使用变量

假设我们现在需要增加一个test1环境配置,那么我们操作的步骤是这样的:

  1. 首先,我们添加.env.test1环境文件
  2. 添加对应的环境变量和值
  3. 在首页package.jsonscripts属性中新增一行"build-test1": "vue-cli-service build --mode test1"(增加打包命令)
  4. Terminal中执行npm run build-test1(打包)

这样我们就完成了test1环境的配置和打包了。

其他

  • 如果在本地开发阶段,如何使用某个模式下的环境变量呢?

有两种方法:

  1. 修改package.json中的serve命令内容,添加--mode 要使用的环境文件名

    1
    2
    3
    4
    5
    6
    7
    8
    {
    ...
    "scripts": {
    "serve": "vue-cli-service serve --mode 模式名",
    ...
    },
    ...
    }
  2. 新增一个.env.local的环境文件,把那个模式的环境变量拷贝一份到.env.local


评论区