设置环境变量的需求
通过配置环境变量,可以使我们的开发更加高效。最常见的情景是我们的API
请求接口,他常常是分为开发环境,测试环境和生产环境的。如果每一次打包我们都是修改请求接口的地址,那样就显得太愚蠢了。并且如果区分区分环境的地方很多,你可能会有很多疏漏。而通过设置环境变量,统一管理每个环境下的所有变量。
在Vur cli 2.0
的版本中我们是通过在config
文件夹进行配置的,Vue/cli 3.0
相对简单,只需要在项目根目录创建.env
文件即可。
设置环境变量
你可以替换你的项目根目录中的下列文件来指定环境变量:
.env # 在所有的环境中被载入
.env.local # 在所有的环境中被载入,但会被 git 忽略
.env.[mode] # 只在指定的模式中被载入
.env.[mode].local # 只在指定的模式中被载入,但会被 git 忽略
一个环境文件只包含环境变量的“键=值”对,并且必须以VUE_APP_
开始:
FOO=bar //无效
VUE_APP_SECRET=secret
被载入的变量将会对 vue-cli-service
的所有命令、插件和依赖可用。
环境加载属性
为一个特定模式准备的环境文件 (例如
.env.production
) 将会比一般的环境文件 (例如.env
) 拥有更高的优先级。此外,Vue CLI 启动时已经存在的环境变量拥有最高优先级,并不会被
.env
文件覆写。
在客户端侧代码中使用环境变量
只有以 VUE_APP_
开头的变量会被 webpack.DefinePlugin
静态嵌入到客户端侧的包中。你可以在应用的代码中这样访问它们:
console.log(process.env.VUE_APP_SECRET)
在构建过程中,process.env.VUE_APP_SECRET
将会被相应环境设置的变量所取代。
除了 VUE_APP_*
变量之外,在你的应用代码中始终可用的还有两个特殊的变量:
NODE_ENV
- 如果在环境里显式定义的话就会设置生效,如果没有显式设置,默认会是"development"
、"production"
或"test"
中的一个。具体的值取决于应用运行的模式。BASE_URL
- 默认会和vue.config.js
中的publicPath
选项(默认值 '/')一致,即你的应用会部署到的基础路径。如果在环境里显性设置和publicPath
的不一致,就会不生效,即输出发现其值仍然是publicPath
的值。所以简单来说,就是与publicPath
选项一致。
值得注意的是,如果下图右边红框显示设置,那NODE_ENV='qqenv',如果删掉红框,NODE_ENV='development'
所有解析出来的环境变量都可以在 public/index.html
中以 HTML 插值中介绍的方式使用。
模式
模式是 Vue CLI 项目中一个重要的概念。默认情况下,一个 Vue CLI 项目有三个模式:
development
模式用于命令vue-cli-service serve
production
模式用于命令vue-cli-service build
和vue-cli-service test:e2e
test
模式用于命令vue-cli-service test:unit
也就是:执行后边的命令的时候,默认是进入到了前边默认的模式,即使项目中没有显式设置.env.development
等文件,NODE_ENV也会默认为对应模式的名字,BASE_URL也会存在。这两个特殊的环境变量是一定存在的。
可以在 .env.development
文件下修改该模式的 NODE_ENV
。
注意模式不同于 NODE_ENV(这只是一个特殊的环境变量)
,一个模式可以包含多个环境变量。
你可以通过为 .env
文件增加后缀来设置某个模式下特有的环境变量。比如,如果你在项目根目录创建一个名为 .env.development
的文件,写入其他的环境变量,那么在这个文件里声明过的变量就只会在 development 模式下被载入。
你可以通过传递 --mode
选项参数为命令行覆写默认的模式。例如,如果你想要在构建命令中使用开发环境变量,请在你的 package.json
脚本中加入:
"dev-build": "vue-cli-service build --mode development",
如果这三个模式不够用,当然你也可以创建属于自己的模式,也就是自定义模式。例如上图的.env.qq
常规操作
1:在根目录创建 .env.xxx 文件
通过为 .env文件 增加后缀来设置某个模式下的特有环境变量。
三种模式文件配置
.env.development文件
NODE_ENV = 'development'
VUE_APP_ENVIRONMENT = 'development'
VUE_APP_API1='/api1'
VUE_APP_API2='/api2'
.env.test文件(重写了NODE_ENV值)
NODE_ENV = 'production'
VUE_APP_ENVIRONMENT = 'test'
VUE_APP_API1='http://192.168.12.54:8088/api1'
VUE_APP_API2='http://192.168.42.54:8084/api2'
.env.product文件
NODE_ENV = 'production'
VUE_APP_ENVIRONMENT = 'product'
VUE_APP_API1='http://192.168.12.54:8088/api1'
VUE_APP_API2='http://192.168.42.54:8084/api2'
注意:在.env.test和.env.product文件中NODE_ENV都设置成了production,目的是为了打出的包结构相同,而通过VUE_APP_ENVIRONMENT值来区分打包环境。
Tips: 即使不是生产环境,也可以将模式设置为 production ,这样可以获得 webpack 默认的打包优化。
生产和测试的包应该是除了环境变量不同,其他都相同,所以同属production模式。用额外的VUE_APP_ENVIRONMENT来区分production和test环境。
2:在package.json中通过 --mode 选项重写默认的模式
"scripts": {
"serve": "vue-cli-service serve --mode development",
"test": "vue-cli-service build --mode test",
"build": "vue-cli-service build --mode product"
}
注意:–mode后边的名字必须和步骤1中 .env.xxx 的名字保持一致
3:根据不同环境分别进行配置
//main.js
var instance1 = axios.create({
baseURL: process.env.VUE_APP_API1,
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
var instance2 = axios.create({
baseURL: process.env.VUE_APP_API2,
timeout: 2000,
headers: {'X-Custom-Header': 'foobar'}
});
Vue.prototype.$http1=instance1 ;
Vue.prototype.$http2=instance2 ;
开发环境还需要配置devServer的跨域
devServer: {
proxy: {
'/api1': {
target: 'http://127.0.0.1:8888/projectA',
changOrigin: true,
pathRewrite: {
'^/api1': ''
}
},
'/api2': {
target: 'http://127.0.0.1:8889/projectB',
changOrigin: true,
pathRewrite: {
'^/api2': ''
}
}
}
}