vue vue-cli 不同的环境打包不同的接口地址

由于项目需要使用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
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值