vue vue-cli 不同的环境打包不同的接口地址
由于项目需要使用webpack构建的工程,在开发过程中不同环境的配置不同,在各种环境的打包切换过程中需要手动修改相关配置达到预期目的。比较麻烦,所以借鉴别人方法写了不同环境打包分类配置。打包配置文件基本就是这样一个项目的开发调试过程肯定不止开发环境和生产环境,由于缺少环境常量,开发人员常常需要手动修改请求Api域名,进而导致如果项目存在多个环境时,多出的环境没办法自动化构建。...
由于项目需要使用webpack构建的工程,在开发过程中不同环境的配置不同,在各种环境的打包切换过程中需要手动修改相关配置达到预期目的。比较麻烦,所以借鉴别人方法写了不同环境打包分类配置。
打包配置文件基本就是这样
一个项目的开发调试过程肯定不止开发环境和生产环境,由于缺少环境常量,开发人员常常需要手动修改请求Api域名,进而导致如果项目存在多个环境时,多出的环境没办法自动化构建。
第一步、
新建一个env-config.js在build文件中
/*
使用方法示例:
打包:
打包dev环境:npm run build --dev
打包test环境:npm run build --test
打包pro环境:npm run build --pro
本地运行:
本地运行dev环境:npm run dev --dev
本地运行test环境:npm run dev --test
无【--xxx】参数,则默认为dev环境:npm run dev
*/
'use strict'
const chalk = require('chalk')
const path = require('path')
/*
* 环境列表,第一个环境为默认环境
* envName: 指明现在使用的环境
* dirName: 打包的路径,只在build的时候有用
* baseUrl: 这个环境下面的api 请求的域名
* assetsPublicPath: 静态资源存放的域名,未指定则使用相对路径
* */
const ENV_LIST = [
{
//开发环境
envName: 'dev',
dirName: 'dev',
baseUrl: 'http://192.168.x.x:1111',
assetsPublicPath:'/'
},
{
//测试环境
envName: 'test',
dirName: path.resolve(__dirname, '../wechain'),
baseUrl: 'http://47.104.xx.xx:2222',
assetsPublicPath: '/'
},
{
//生产环境(命令行参数(process.arg)中prod是保留字,所以使用pro)
envName: 'pro',
dirName: path.resolve(__dirname, '../wechain'),
baseUrl: 'http://47.104.xxx.xxx:3333',
assetsPublicPath:'/'
},
]
console.log("process.env.assetsPublicPath="+process.env.assetsPublicPath)
//获取命令行参数 http://nodejs.cn/api/process.html#process_process_argv
const argv = JSON.parse(process.env.npm_config_argv).original || process.argv
const HOST_ENV = argv[2] ? argv[2].replace(/[^a-z]+/ig,"") : ''
//没有设置环境,则默认为第一个
const HOST_CONF = HOST_ENV ? ENV_LIST.find(item => item.envName === HOST_ENV) : ENV_LIST[0]
// 把环境常量挂载到process.env.HOST_ENV方便客户端使用
process.env.BASE_URL = HOST_CONF.baseUrl
// process.env.ENV_NAME = HOST_CONF.envName
// log选中的变量
console.log(chalk.green('当前环境:'))
console.log(HOST_ENV)
console.log(chalk.green('当前环境对应的常量:'))
console.log(HOST_CONF)
module.exports.HOST_CONF = HOST_CONF
module.exports.ENV_LIST = ENV_LIST
第二步、
修改 build下webpack.base.config.js 引入公用的env-config.js
require('./env-config.js');
第三步、
修改 build下webpack.dev.config.js的代码
//找到plugins,在这里面添加如下代码
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env'),
//添加下面代码
'process.env.BASE_URL': '\"' + process.env.BASE_URL + '\"'
}),
]
第四步、
修改 build下webpack.prod.config.js的代码
//找到plugins,在这里面添加如下代码
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
//添加下面代码
'process.env.BASE_URL': '\"' + process.env.BASE_URL + '\"'
}),
}
以上配置已经完成
打包dev环境:npm run build --dev
打包test环境:npm run build --test
打包pro环境:npm run build --pro
本地运行:
本地运行dev环境:npm run dev --dev
本地运行test环境:npm run dev --test
无【--xxx】参数,则默认为dev环境:npm run dev
直接在页面调用 process.env.BASE_URL 就可以拿到配置的域名/ip
另外:
如果需要配置更多变量,如测试和生产的私钥可以在env-config.js进行添加
//找到 ENV_LIST 在这里修改
const ENV_LIST = [
{
//开发环境
envName: 'dev',
dirName: 'dev',
baseUrl: 'http://192.168.x.x:3333',
assetsPublicPath:'/',
privateKey:'devprivateKey',//后添加的私钥
},
{
//测试环境
envName: 'test',
dirName: path.resolve(__dirname, '../wechain'),
baseUrl: 'http://47.104.xx.xx:2222',
assetsPublicPath: '/',
privateKey:'testprivateKey',//后添加的私钥
},
{
//生产环境(命令行参数(process.arg)中prod是保留字,所以使用pro)
envName: 'pro',
dirName: path.resolve(__dirname, '../wechain'),
baseUrl: 'http://47.104.xxx.xxx:3333',
assetsPublicPath:'/',
privateKey:'proprivateKey',//后添加的私钥
},
]
// 找到process.env.BASE_URL = HOST_CONF.baseUrl这段代码,在下面添加
process.env.BASE_URL = HOST_CONF.baseUrl;
process.env.privateKey= HOST_CONF.privateKey; //添加的私钥
然后我们需要在webpack.dev.config.js和webpack.prod.config.js里面把如下代码修改
new webpack.DefinePlugin({
'process.env.BASE_URL': '\"' + process.env.BASE_URL + '\"',
'process.env.privateKey': '\"' + process.env.privateKey+ '\"',//后加的私钥
}),
以后需要更多配置变量可以按照以上方式添加。
使用这个配置后,如何配置代理呢?
继续往下看
修改config/index.js
const proUrl = require('../build/env-config');
const ENV_LIST = proUrl.ENV_LIST;
const argv = JSON.parse(process.env.npm_config_argv).original || process.argv;
const HOST_ENV = argv[2] ? argv[2].replace(/[^a-z]+/ig,"") : '';
const HOST_CONF = HOST_ENV ? ENV_LIST.find(item => item.envName === HOST_ENV) : ENV_LIST[0];
module.exports = {
dev: {
...
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
"/requestApi": { // requestApi相当于一个别名,代指 target
"target": HOST_CONF.baseUrl,
"changeOrigin": true,
"pathRewrite": {
"^/requestApi": ""
}
}
},
...
}
}
这里需要做一个区分,什么情况下需要用到代理,什么情况下不用使用代理。所以就在接口调用页面,判断当前运行的环境是开发、测试还是生产的。
下面修改自己api.js(这个文件是自己新建的,主要是统一管理请求api),以下就是判断如果是test环境还有dev环境的情况下 使用代理解决跨域问题
const apiUrl = process.env.HOST_ENVNAME == 'test' || process.env.HOST_ENVNAME == 'dev' ? "/requestApi/":process.env.BASE_URL;
const webUrl = process.env.HOST_ENVNAME == 'test' || process.env.HOST_ENVNAME == 'dev' ? "/requestApi/":process.env.BASE_URL;
const api = {
//获取验证图片
getCodeFun(dataModel){
// requestAll.downLoadRequest 是自己封装的一个方法,实质就是替换成你们自己的封装的一个request就好了
return requestAll.downLoadRequest(apiUrl + 'api/v1/user/getVerifyCode',dataModel);
},
...
}
下面再给大家多放一个封装好的request.js的例子,如果有需要可以拿来用。
// request.js
import axios from 'axios';
//将JSON数据改为为form类型
import qs from 'qs';
import Vue from 'vue';
let Vues = new Vue();
import Cookies from 'js-cookie';
axios.defaults.timeout = 200000; //响应时间
axios.interceptors.response.use((config) => {
// console.log(config)
if (config.data.code != "000000" && config.config.responseType !== "blob" && config.request.responseURL.indexOf('yunyao') === -1) {
Vues.$message({
message: config.data.data || config.data.mesg,
type: "warning"
});
}
if (config.data.code === "-1" && config.data.mesg === "登录失效") {
setTimeout(() => {
Cookies.remove('token');
Cookies.remove('userInfo');
Cookies.remove('userRole');
window.location.reload()
}, 2000);
}
return config;
}, error => { // for debug
let msgText = JSON.stringify(error).includes('404')
? 'API Not Found'
: JSON.stringify(error).includes('401')
? '无访问权限, 请联系管理员!'
: 'Internal Server Error';
Vues.$message({
message: msgText,
type: "error"
});
if (JSON.stringify(error).includes('401')) {
setTimeout(() => {
Cookies.remove('token');
Cookies.remove('userInfo');
Cookies.remove('userRole');
window.location.reload()
}, 1500);
}
return Promise.reject(error) //接口500抛出异常(不走页面逻辑)
});
// get请求
function getRequest(url, data = {}, method = 'get') {
return new Promise((resolve, reject) => {
let loading = "";
//如果 不匹配就出现loading
if ( !url.includes('admin/v1/region/province')) {
//加载
loading = Vues.$loading({
lock: true,
text: '加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
//请求头
let header = {};
//登录接口不用传token
if(url.includes('api/v1/user/signIn')){
header = {
'content-type': 'application/json',
'terminal':'PC'
}
}else{
header = {
'content-type': 'application/json',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
}
//如果 匹配 就换content-type 类型
if (url.includes('TestApi/v1/user/signIn')) {
header['content-type'] = 'application/x-www-form-urlencoded';
header['Authorization'] = 'Bearer '+ Cookies.get('token');
header['terminal'] = 'PC';
}
/**x添加终端类型 1:PC 2:诊所端*/
if(data.terminalType == undefined){
data.terminalType = 2;
}
axios({
url: url,
method: method,
headers: header,
data: data
})
.then(res => {
//成功
resolve(res.data)
//如果 不匹配就出现loading
if ( !url.includes('admin/v1/region/province') && !url.includes('admin/v1/region/city') && !url.includes('admin/v1/region/area')) {
setTimeout(() => { loading.close(); }, 500);
}
})
.catch(res => {
//失败
reject(res);
//如果 不匹配就出现loading
if ( !url.includes('admin/v1/region/province') && !url.includes('admin/v1/region/city') && !url.includes('admin/v1/region/area')) {
setTimeout(() => { loading.close(); }, 500);
}
})
})
}
// post请求
function postRequest(url, data = {}, method = 'post', loadMask = true) {
return new Promise((resolve, reject) => {
let loading
if (loadMask) {
//加载
loading = Vues.$loading({
lock: true,
text: '加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
//请求头
let header = {};
//登录接口不用传token
if(url.includes('api/v1/user/signIn')){
header = {
'content-type': 'application/json',
'terminal':'PC'
}
}else if(url.includes('admin/v1/upload')){
header = {
'content-type': 'multipart/form-data',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
}
else if (url.includes('TestApi/v1/user/signIn')) {
header['content-type'] = 'application/x-www-form-urlencoded';
header['Authorization'] = 'Bearer '+ Cookies.get('token');
header['terminal'] = 'PC';
method = "POST";
}
else{
header = {
'content-type': 'application/json',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
}
/**x添加终端类型 1:PC 2:诊所端*/
if(data.terminalType == undefined){
data.terminalType = 2;
}
// XWWW 转换 POST data数据处理
if (method === 'XWWW') {
data = qs.stringify(data);
header = {
'content-type': 'application/x-www-form-urlencoded',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
method = 'POST'
}
axios({
url: url,
method: method,
headers: header,
// data: qs.stringify(data)
data:data
})
.then(res => {
//成功
resolve(res.data)
if (loadMask) {
setTimeout(() => { loading.close(); }, 500);
}
})
.catch(error => {
//报错就提示网络不佳
let sign = {
mesg:'网络不佳,请稍后重试!'
}
//失败
resolve(sign)
//失败
// reject(error)
if (loadMask) {
setTimeout(() => { loading.close(); }, 500);
}
})
})
}
// put请求
function putRequest(url, data = {}, method = 'put') {
return new Promise((resolve, reject) => {
//加载
const loading = Vues.$loading({
lock: true,
text: '加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
//请求头
let header = {};
//登录接口不用传token
if(url.includes('api/v1/user/signIn')){
header = {
'content-type': 'application/json',
'terminal':'PC'
}
}else{
header = {
'content-type': 'application/json',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
}
//如果 匹配 就换content-type 类型
if (url.includes('TestApi/v1/user/signIn')) {
header['content-type'] = 'application/x-www-form-urlencoded';
header['terminal'] = 'PC';
}
/**x添加终端类型 1:PC 2:诊所端*/
if(data.terminalType == undefined){
data.terminalType = 2;
}
// XWWW 转换 POST data数据处理
if (method === 'XWWW') {
data = qs.stringify(data);
header = {
'content-type': 'application/x-www-form-urlencoded',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
method = 'PUT'
}
axios({
url: url,
method: method,
headers: header,
// data: qs.stringify(data)
data:data
})
.then(res => {
//成功
resolve(res.data)
setTimeout(() => { loading.close(); }, 500);
})
.catch(res => {
//报错就提示网络不佳
let sign = {
mesg:'网络不佳,请稍后重试!'
}
//失败
resolve(sign)
// reject(res)
setTimeout(() => { loading.close(); }, 500);
})
})
}
// delete请求
function deleteRequest(url, data = {}, method = 'delete') {
return new Promise((resolve, reject) => {
//加载
const loading = Vues.$loading({
lock: true,
text: '加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
//请求头
let header = {};
//登录接口不用传token
if(url.includes('api/v1/user/signIn')){
header = {
'content-type': 'application/json',
'terminal':'PC'
}
}else{
header = {
'content-type': 'application/json',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
}
//如果 匹配 就换content-type 类型
if (url.includes('TestApi/v1/user/signIn')) {
header['content-type'] = 'application/x-www-form-urlencoded';
header['terminal'] = 'PC';
}
/**x添加终端类型 1:PC 2:诊所端*/
if(data.terminalType == undefined){
data.terminalType = 2;
}
axios({
url: url,
method: method,
headers: header,
// data: qs.stringify(data)
data:data
})
.then(res => {
//成功
resolve(res.data)
setTimeout(() => { loading.close(); }, 500);
})
.catch(res => {
//报错就提示网络不佳
let sign = {
mesg:'网络不佳,请稍后重试!'
}
//失败
resolve(sign)
// reject(res)
setTimeout(() => { loading.close(); }, 500);
})
})
}
//下载文件
function downLoadRequest(url, data = {}, method = 'get') {
return new Promise((resolve, reject) => {
let loading = '';
if(!url.includes('api/v1/user/getVerifyCode')){
//加载
loading = Vues.$loading({
lock: true,
text: '加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
let header = {
'content-type': 'application/json',
'Authorization':'Bearer '+ Cookies.get('token'),
'terminal':'PC'
}
if(url.includes('admin/v1/agent/export') || url.includes('admin/v1/shop/export') || url.includes('admin/v1/reportCenter/exportRewards') || url.includes('admin/v1/reportCenter/exportOrderCoupunDetial') ){
method = 'post';
}
// if(url.includes('api/v1/user/getVerifyCode')){
// header['content-type'] = 'multipart/form-data';
// }
let subObj = {};
//get方式
if(method == 'get'){
subObj={
url: url,
method: method,
headers: header,
params:data,
responseType: 'blob',
};
}
//post方式
else{
subObj={
url: url,
method: method,
headers: header,
data:data,
responseType: 'blob',
};
}
axios(subObj)
.then(res => {
//成功
resolve(res.data)
if(!url.includes('api/v1/user/getVerifyCode')){
setTimeout(() => { loading.close(); }, 500);
}
})
.catch(res => {
//失败
reject(res)
if(!url.includes('api/v1/user/getVerifyCode')){
setTimeout(() => { loading.close(); }, 500);
}
})
})
}
axios.jsonp = (url) => {
if(!url){
console.error('Axios.JSONP 至少需要一个url参数!')
return;
}
return new Promise((resolve, reject) => {
window.jsonCallBack =(result) => { resolve(result) }
var JSONP = document.createElement("script");
JSONP.type="text/javascript";
JSONP.src=`${url}&callback=jsonCallBack`;
document.getElementsByTagName("body")[0].appendChild(JSONP);
setTimeout(() => {
document.getElementsByTagName("body")[0].removeChild(JSONP);
},500)
})
}
// JSONP请求
function jsonpRequest(url) {
return new Promise((resolve, reject) => {
axios.jsonp(url)
.then(res => { resolve(res) })
.catch(error => { reject(error) })
})
}
export default {
postRequest: postRequest,
getRequest:getRequest,
putRequest:putRequest,
deleteRequest:deleteRequest,
downLoadRequest:downLoadRequest,
jsonpRequest: jsonpRequest
}
更多推荐
所有评论(0)