![]()
起因
最近新启动的一个Vue项目需要配置多个环境,不同的环境需要使用不同的API域名。
在以往的H5项目中,可以通过判断当前域名/域名+端口号(window.location.href)来区分dev、test、prd等不同环境,但这次新启动项目当然不想使用这么low的方式了,于是打算找找有什么好用的方法,还真找到了一种。
环境变量
在vue-cli文档模式和环境变量这一章中,提到了环境文件这个词。(文档传送门)
过去在开发PHP程序时,为了区分不同的开发环境和线上环境的mysql、redis库,会引入一个名为.env环境变量文件。这个文件一般不会随着git提交而同步到代码仓库里,同时(运维人员)也会不同环境下配置各自的.env配置文件。(既能保证代码发布时无需改动就能切换环境,又保证开发不会获取到线上数据的操作权限)
当然了,vue-cli中的环境变量肯定是不一样的啦。文档里提到了默认存在development、test、production三种模式,可以通过vue-cli-service build --mode 模式名来读取并使用对应模式的环境变量文件。通过测试我发现也可以使用自定义的模式名称,比如**test1**、**test2**都是可以的。
模式对应的环境变量文件规则如下:
![]()
那么问题来了,如果在production模式中.env、.env.production同时存在某个环境变量名,最终会使用谁的值呢?
答:无论在任何模式中 .env.[模式名]的优先级都大于.env,所以会使用.env.production的变量值。
定义变量
环境变量的定义可以参考dotenv和dotenv-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的作用其实是使用$进行变量复用,例如:
| 12
 3
 4
 
 | A=HELLOB=WORLD
 
 CONCAT=$A$B
 
 | 
使用变量
假设我们现在需要增加一个test1环境配置,那么我们操作的步骤是这样的:
- 首先,我们添加.env.test1环境文件
- 添加对应的环境变量和值 
- 在首页package.json的scripts属性中新增一行"build-test1": "vue-cli-service build --mode test1"(增加打包命令)
- 在Terminal中执行npm run build-test1(打包)
这样我们就完成了test1环境的配置和打包了。
其他
- 如果在本地开发阶段,如何使用某个模式下的环境变量呢?
有两种方法:
- 修改- package.json中的- serve命令内容,添加- --mode 要使用的环境文件名
 | 12
 3
 4
 5
 6
 7
 8
 
 | {...
 "scripts": {
 "serve": "vue-cli-service serve --mode 模式名",
 ...
 },
 ...
 }
 
 |  
 
- 新增一个- .env.local的环境文件,把那个模式的环境变量拷贝一份到- .env.local中