在构建公司项目的时候遇到了这样一个问题公司的项目上线之前需要经过测试。这是每个公司都会有的流程。就比如我们公司,项目发布之前要先经过测试环境测试和预发环境测试最后才是生产环境。
环境变量
那么问题就来了,这么多环境每个环境的后台服务器地址是不样的,总不能每发布一个环境就改一次代码吧。
于是就有了环境变量,根据环境变量判断当前所需要部署的环境,输出对应的服务器地址。那么我们该如何设置环境变量呢?我使用的是cross-env能跨平台设置和使用环境变量的脚本。
cross-env
的安装使用
安装
npm install --save cross-env
复制代码
配置
- 打开Vue项目根目录下
package.json
修改scripts
中build
命令,这里我们将环境变量process.env.ENV
设置为dev
(ps:如果有多个环境则需要添加)
"build:dev": "cross-env ENV=dev node build/build.js",
复制代码
- 修改
build/webpack.prod.conf.js
中webpack.DefinePlugin
的配置。我们看webpack.DefinePlugin
原来的配置代码。可以看到他的配置来自变量env
。所以我们只需要更改变量env
的值就可以了。所以我们增加代码env.ENV= `"${process.env.ENV}"`;
。
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
env.ENV= `"${process.env.ENV}"`; //我们增加的代码
//这里我们省略无关的代码只看关键部分
new webpack.DefinePlugin({
'process.env': env //来自上面定义的变量env
})
复制代码
- 修改
build/build.js
(为了build
时输出正确的提示信息)
// const spinner = ora('building for production...') //修改前
const spinner = ora(`building for ${process.env.ENV}...`)//修改后
复制代码
- 完成以上步骤之后我们就可以在代码中通过
process.env.ENV
获取我们定义的环境变量了。
服务器地址及接口信息配置
配置文件目录结构
vue/
└── src/ 项目目录(alias:@)
└── server/ 服务器地址及接口配置目录
├── api/ 接口目录
├── config/ 服务器地址配置目录
├── utils/ 工具类
└── index.js 暴露接口信息
复制代码
目录 utils/
在目录utils/
下新建convertUri.js
var api = {}
/**
* 根据环境变量引入相应的服务器配置文件
*/
console.log('process.env.ENV', process.env.ENV)
if (process.env.ENV === 'prod') {
api = require('../config/api.prod').default
} else {
api = require('../config/api.dev').default
}
/**
* uri转url
*/
export default (url) => {
for (const key in api) {
const reg = new RegExp(`^/?:${key}`)
if (reg.test(url)) {
return url.replace(reg, api[key])
}
}
return url
}
复制代码
在目录utils/
下新建oauthJudge.js
(ps:这是用于部分接口请求头不需要携带token的判断,若你的项目中不需要类似 oauth2.0
权限验证则不需要新建该文件)
/** 不需要 Authorization 的接口列表 */
const apiList = [
/user\/token/,
/user\/register/,
/user\/check_username/,
/captcha/,
/article\/get/,
/sort\/get/,
/label\/get/
]
/** 判断是否需要携带 token */
export default url => {
return apiList.every(item => {
return !item.test(url)
})
}
复制代码
在目录utils/
下新建request.js
import axios from 'axios'
import convertUri from './convertUri'//服务器地址配置,及URI与URL之间的转换
// import { Notification } from 'element-ui'//这是element-ui的通知的方法如果有需要可以安装element-ui后调用
// import store from '@/store'//引入vuex,按需引入
// import router from '@/router'//引入vue-router,按需引入
// import oauthJudge from './oauthJudge'//判断接口是否需要权限验证的方法,按需引入
// 创建axios实例
const service = axios.create({
timeout: 60000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
config => {
// URI与URL之间的转换
config.url = convertUri(config.url)
// let token = store.getters.token || null 从vuex获取token请根据实际情况自行修改
// 请求头带token
// if (token && oauthJudge()) { //判断token是否存在 与 接口是否需要权限验证
// config.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带自定义token 请根据实际情况自行修改
// }
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// respone拦截器
service.interceptors.response.use(
response => {
/**
* code为非200是抛错 可结合自己业务进行修改
*/
const res = response.data
if (response.status !== 200) {
return Promise.reject(res)
} else {
return response.data.data
}
},
/**
* 响应出错的处理
*/
error => {
return Promise.reject(error)
}
)
export default service
复制代码
目录 config/
新建文件api.dev.js
与api.prod.js
文件格式如下
const url = 'http://localhost:3000' //Base_URL
// 服务器链接配置建议按模块划分
export default {
// 用户管理模块
user: `${url}/user`,
// 验证码模块
captcha: `${url}/captcha`,
// 标签模块
label: `${url}/label`,
// 分类模块
sort: `${url}/sort`,
// 评论模块
comment: `${url}/comment`,
// 博文模块
article: `${url}/article`
}
复制代码
目录 api/
建议的文件目录结构按接口模块划分比如:
api/
├── user-controller/ 用户管理模块
├── label-controller/ 标签管理模块
├── comment-controller/ 评论管理模块
├── captcha-controller/ 验证码管理模块
├── article-controller/ 文章管理模块
└── sort-controller/ 分类管理模块
复制代码
user-controller/
目录下新建login.js
与index.js
//login.js
import request from '@/server/utils/request'
/**
* 登陆 获取token
* @param userName 用户名
* @param userPassword 用户密码
*/
export default (userName, userPassword) => {
return request({
url: '/:user/token',
method: 'post',
data: { user_name: userName, user_password: userPassword }
})
}
复制代码
//index.js
import login from './login'
/**
* 用户管理模块接口方法的集合
*/
export default {
login
}
复制代码
暴露接口信息 index.js
import articleController from './api/article-controller'
import captchaController from './api/captcha-controller'
import commentController from './api/comment-controller'
import labelController from './api/label-controller'
import sortController from './api/sort-controller'
import userController from './api/user-controller'
export default {
...articleController,
...captchaController,
...commentController,
...labelController,
...sortController,
...userController
}
复制代码
Vue中的调用
通过上述方法我们将所有的接口方法都定义在了目录server/api/
中那么我们该如何调用呢?
main.js
引入
在main.js
中增加下面两条代码
import api from '@/server'
Vue.prototype.$api = api
复制代码
那么我们就可以直接在Vue组件中通过this.$api.login()
调用login
方法访问接口了。
最后如何build
npm run build:dev
复制代码