0. 前言

目前项目上领导提出一个需求:前端项目打包的时候,希望项目线上接口地址不要写死。可以根据上线时候的情况去修改接口地址而不需要前端再次打包代码。

根据网上搜索加自己实践得出以下几种方法:

1. 解决方案

我这边是uniapp的项目,在根目录下static文件夹内的内容默认不会压缩(vue中默认public文件夹),那就就在static文件夹内创建一个config.js文件。

1
2
// /static/config.js
httpUrl = 'www.xxx.com/';

1.1 方案一

index.html中新增script标签,window对象上挂载请求路径,后端想要修改地址就在html中修改即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<!--新增,放在上面,避免js执行顺序问题-->
<script>
window.httpurl = "www.xxx.com"
</script>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

request.js

设置请求路径为httpUrl

1
2
3
4
5
6
7
8
// 开发环境就根据配置的环境变量去修改
let baseUrl =
import.meta.env.VITE_APP_API_BASE_URL;

// 生产环境就使用导入地址
if ( process.env.NODE_ENV === 'production' ) {
baseUrl = httpUrl
}

1.2 方案二

index.html中新增<script src="./config.js"></script>,放在html文本之前,避免js执行顺序的问题,vite只会打包**type="module"得script标签**。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
// 新增
<script src="./config.js"></script>
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

request.js

设置请求路径为httpUrl

1
2
3
4
5
6
7
8
// 开发环境就根据配置的环境变量去修改
let baseUrl =
import.meta.env.VITE_APP_API_BASE_URL;

// 生产环境就使用导入地址
if ( process.env.NODE_ENV === 'production' ) {
baseUrl = httpUrl
}

1.3 方案三

第三种方案和第二种是差不多,只不过由config.js变成config.json

1
2
3
4
{
"baseRUL": "www.xxx.com",
"timeout": 10000
}

在main,.js中设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import axios from 'axios';

// 配置axios,如果是生产环境就读配置文件
if(process.env.NODE_ENV === 'production') {
axios.get('/static/config.json').then(res => {
// 基础地址和超时时间
axios.defaults.baseURL = res.data.baseURL;
axios.defaults.timeout = res.data.timeout;*
console.log('基础地址:' + axios.defaults.baseURL)
}).catch(err => {
axios.defaults.baseURL = 'http://localhost:8080';
})
} else {
axios.defaults.baseURL = 'http://........:6060';
console.log(axios.defaults.baseURL)
}

需要注意的得是,这个get任务是异步得,我的做法是封装一个promise

1
2
3
4
5
6
7
8
9
10
11
12
getBaseURL().then(() => {
Vue.prototype.$http = axios;
Vue.config.productionTip = false;
axios.intercepptors.request.use(request => { });
axios.intercepptors.response.use(response => { })

new Vue({
render,
store,
render: h => h(App)
}).$mount('#app')
})

tips:方案三我没有实践过,请自行测试