Vue区分开发环境和生产环境不同的url
假设有一个请求,由base_url和接口路径组成
like this:
http://127.0.0.1:8066/dologin
http://127.0.0.1:8066是base_url
/dologin是接口路径
一般地,在测试环境、开发环境以及生产环境,接口的路径都是一致的,
区别在于base_url的不同。
因此,可以做点手脚,让base_url根据当前所处的环境进行赋不同值。
在nodejs中存在一个对象,名为process,本身process是内置于nodejs中,
webpack对其进行了处理,将这个对象写入到了html的执行环境中,
因此我们可以在js中访问到process对象。
process.env.NODE_ENV 即为我们希望知晓的当前环境
npm run dev ——> process.env.NODE_ENV == "development"
npm run build ——> process.env.NODE_ENV == "production"
Tips:应当注意的是,js中访问的process对象和node中的process对象不是同一个。
js中访问到的process是一个假的process。
基于此,我们创建一个文件config.js
置于assets文件夹中。
/assets/config.js
const _config = {
base_url : "",
}
if(process.env.NODE_ENV == "development"){
_config.base_url = "http://127.0.0.1:8080";
}else if(process.env.NODE_ENV == "production"){
_config.base_url = "http://127.0.0.1:8123";
}
export default {
..._config
}
然后在main.js中引入
main.js
import Vue from "vue";
import App from './App';
import router from './router';
...
import __CONFIG__ from "./assets/config.js";
Vue.prototype.CONFIG = __CONFIG__
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
});
至此便区分了dev环境和prod环境(好像其实没啥大用处);
进一步探讨
刚刚我们区分了npm run dev 和 npm run build 两个场景下的不同的url,
这样处理我们达到了这么一个目的:
在本地开发的时候,调用的接口是测试环境;
当我们build的时候,产生的代码调用的接口则是生产环境。
其实这跟实际的项目开发流程是相违背的,
现实的开发流程是:
1、本地开发调用测试环境的接口;
2、然后本地的代码开发完毕,build的代码部署到测试环境,供测试同事测试;
————此时,本地npm run dev和npm run build,调用的接口其实都是测试接口。
区分开,意义不大。
3、接着,测试环境测试通过后,将测试环境部署到生产环境,也就是上线。
这个时候,就需要将测试环境的url和生产环境的url区分开了。
因此我们的需求应当是这样的:
1、我拥有两种build的方式,一种build后跑在测试环境,一种build后跑在生产环境;
2、通过这两种build,我调用的接口url前缀不同。
再进一步推演,假设我调用了一个接口,
在测试环境接口url为 http://test.xxx.com/dologin
在生产环境接口url为 http://api.xxx.com/dologin
然后一般我们会这样去写url:
var base_url = "http://test.xxx.com";
var url = base_url + "/dologin";
base_url一般我们会另起一个js文件来保存,假设叫做config.js
普通的操作
使用git进行代码版本管理,假设有两个分支,第一个分支叫做dev,代表测试环境;
第二个分支叫做prod,代表生产环境;
每一次上线更新生产环境的版本,由dev环境的代码merge到prod分支;
那么,假设我当前处于dev分支,
1、创建一个config.js在/static文件夹里面,这可使它不会被webpack压缩,
2、/static/config.js中,写入,var url = "http://127.0.0.1:5678";
3、接着,我将dev分支的config.js的改动,merge到prod,
这时候prod也有这个/static/config.js了,
并且里面的内容为 var url = "http://127.0.0.1:5678";
4、接下来开始对两个分支进行区分,
基于prod创建一个prod-config分支,里面对/static/config.js进行改动,
改成var url = "http://127.0.0.1:1234";
提交,将prod-config分支合并到prod。
5、接下来,基于dev进行开发即可,该干嘛干嘛;
只要/static/config.js中的内容不再进行改动,就可以一直维持两个环境的url不同
dev分支的config.js里的url为http://127.0.0.1:5678,
prod分支的config.js里的url为http://127.0.0.1:1234。
两个需要注意的点:
1、config.js在上述过程完成之后,不能再改动,一个空格也不要加。
万一改动了,上面的步骤重走一遍,
dev分支merge到prod,prod分支上改config.js,提交。
2、分支之间的合并,应该严格保证,是由dev ——> prod,而不能相反;
基于dev开发,创建分支,然后开发完成将分支合并到dev,再由dev合并到prod;
这不QingZhen(手动滑稽),有没有自动一点的操作?
当然是改webpack的配置文件。
我们使用cross-env来设置环境变量。
npm i cross-env --save-dev
定义命令:
package.json
{
...,
"scripts":{
...,
"build:prod": "cross-env NODE_ENV=production node build/build.js --env=production",
"build:dev": "cross-env NODE_ENV=development node build/build.js --env=development"
},
...
}
Tips:npm run build:prod,打包prod的代码,NODE_ENV这个变量值为production;
npm run build:dev,打包dev的代码,NODE_ENV这个变量值为development;
/build/build.js
'use strict'
require('./check-versions')()
// process.env.NODE_ENV = 'production' //这一句注释掉,
...
// const webpackConfig = require('./webpack.prod.conf'); // 这句注释掉
var webpackConfig; // webpack config file
if(process.env.NODE_ENV === "production"){
webpackConfig = require("./webpack.build-prod.conf.js");
}else if(process.env.NODE_ENV === "development"){
webpackConfig = require("./webpack.build-dev.conf.js");
}else{
console.log("Cant find process.env.NODE_ENV,please confirm");
return;
}
const spinner = ora('building for '+process.env.NODE_ENV+'...')
spinner.start()
...
/build/webpack.build-prod.conf.js
//webpack.build-prod.conf.js和webpack.build-dev.conf.js,
//由webpack.prod.conf.js复制来就行。
//里面改点东西,改个env就行
...
const env = const env = process.env.NODE_ENV === 'production'
? require('../config/prod.env.js')
: require('../config/dev.env.js');
...
//这里有俩js,prod.env和dev.env,这俩是啥,往下看
/config/prod.env.js和/config/dev.env.js
/config/prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"',
HOST_URL:'"http:127.0.0.1:8765"'
}
/config/dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
HOST_URL:'"http:127.0.0.1:8888"'
})
//很明显,这里的就是我们所知道的,不同环境下不同的参数了。
// 在development环境,将会使用dev.env.js文件,
// 在production环境,将会使用prod.env.js文件,
// 这两个文件里面都有NODE_ENV和HOST_URL两个参数。
Tips:注意,在prod.env.js和dev.env.js里面,他们的值,要包裹两个引号。
一个大的一个小的,或者俩大的,然后用转义符区分。
不这么做会报错。
eg:
HOST_URL:'"http:127.0.0.1:8765"'
HOST_URL:"\"http:127.0.0.1:8765\""
也就是所谓的,命令不一样,但是生成的参数不一样,目的达到。
如果有一些别的参数想加进去,都是可以加的,保证两个文件拥有的属性一致就行。
如何引用?
还是老办法,访问process这个对象就行了。
/src/main.js
//main.js can get info of process.env , test
console.log(process.env.HOST_URL);
console.log(process.env.NODE_ENV);
大功告成
1、引入,我的做法是把prod.env.js/dev.env.js里面的参数写进了Vue的原型里
import Vue from 'vue';
Vue.prototype.CONFIG = {
BASE_URL:process.env.HOST_URL
}
2、使用
在组件中,比如App.vue文件里,
使用 this.CONFIG.HOST_URL 即可访问到我们定义的 url了。
3、最终效果
npm run build:prod
生成的代码在dist文件夹中,代表了production环境,
this.CONFIG.HOST_URL 为 "http:127.0.0.1:8765"
npm run build:dev
生成的代码在dist文件夹中,代表了development环境,
this.CONFIG.HOST_URL 为 "http:127.0.0.1:8888"