各位大大好:
公司採用 Vue-cli 4 開發,
目前有個需求是要在 build 後的 dist 中,修改一個 config 檔,
可以動態修改 axios 的 baseURL,而不用重新 build 一次。
目前資料夾規劃如下
api 資料夾會統一管理所有 API function,例如:
// api/aPage.js
import request from '@/utils/request';
export function getData() {
return request({
url: '/data',
method: 'get'
})
}
export function delData(id) {
return request({
url: '/del',
method: 'delete',
data: id
})
}
...
utils 資料夾下的 request.js 會封裝一個 axios,例如:
// utils/request.js
import axios from 'axios';
import { dev, prod } from 'public/apiPath.json';
const service = axios.create({
baseURL: process.env.NODE_ENV === 'production' ? prod : dev,
withCredentials: true,
timeout: 1000 * 10,
});
service.interceptors.request.use(
(config) => config,
(error) => Promise.reject(error),
);
service.interceptors.response.use(
(response) => response.data,
(error) => Promise.reject(error),
);
export default service;
request.js 會取得放置在 public 的 apiPath.json,apiPath.json 會寫上所有 API 路徑 (放在 public 也是希望可以在 Vue-cli 打包後,仍然可以修改這個 json)
但目前修改 dist 的 apiPath.json,仍然無法動態修改網站的 API 路徑,即使將伺服器關掉重啟也沒有用,刪掉 apiPath.json 也對專案沒有影響,所以猜測 Vue-cli 已經將 apiPath.json 的值打包進去了。
嘗試很久,還是沒有找到解法,想請問有什麼方向給可以解決呢,感謝!
將json檔案放在public,並透過<script src> 掛在 public/index.html,
使用window.xxx存取那個json檔的變數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<script src="<%= BASE_URL %>abc.json" /></script>
<title>test</title>
</head>
<body>
<noscript>
<strong>We're sorry but codesandbox doesn't work properly without JavaScript
enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
var abcConfig = {
api: "http://example.com.tw/api"
};
<template>
<div id="app">
{{this.api}}
</div>
</template>
<script>
export default {
name: "App",
computed: {
api () {
return window.abcConfig.api
}
},
mounted() {
console.log(window.abcConfig);
},
};
</script>
<style>
</style>
這之前我也挑戰過。
任何方法都想過了。
也曾經考量動態式的編譯方式。
但太操效能了宣告失敗。
目前的做法是採用一支env來處理,區分開發跟正式。
env這支就是設定為主路由的地方。
並不列入git處理。
一但有增加新的路由,還是會跑一次編譯。
不過我有用pm2來處理。所以它會在編譯完後,自動重啟運行。
對user來說還算是無感更換。
我曾經有參考過用外部呼叫的方式。也就是另外規劃一個不列入編譯處理。
但程式碼會對其載入運行。
不過在編譯上會報錯。
再用另外一招,用遠端載入呼叫設定的方式來處理。
但運行中不太穩定,也是宣告失敗。
感謝回答,終於找到同胞了><
我後來寫成,在每個 API function 中,都要重新取得一次 API 路徑,這樣似乎可以動態改變 API 路徑了。
變成以下:
// api/init.js
// 封裝一個取得路徑的 function
import axios from "axios";
export async function init() {
const { data } = await axios.get("apiPath.json");
const { dev, prod } = data
return process.env.NODE_ENV === "production" ? prod : dev;
}
// api/aPage.js
import request from "@/utils/request";
import { init } from "@/api/init";
export async function getData(param) {
// 每個 API function 都要加上這一段,重新取得路徑
const domain = await init()
// 直接將 API 路徑寫在這裡
return request({
url: `${domain}/todos/${param}`,
method: "get",
});
}
// utils/request.js
import axios from "axios";
// import { dev, prod } from "/public/apiPath.json";
const service = axios.create({
// 這裡就不寫 baseURL 了,直接把路徑寫在每個 API function
// baseURL: process.env.NODE_ENV === "production" ? prod : dev,
withCredentials: true,
timeout: 1000 * 10,
});
service.interceptors.request.use(
(config) => config,
(error) => Promise.reject(error)
);
service.interceptors.response.use(
(response) => response.data,
(error) => Promise.reject(error)
);
export default service;
每個 API function 皆改為 async function,並且多出一行 code 每執行一次就重新取得路徑,不知道這樣寫是否有問題 ...
你是可以試試,其實我現在的做法跟你大同小異。
本來以為是可以解決的。
但還是會在一些地方讀到舊路由。
也不知道是我沒寫好還是怎麼樣。
現在其實是用了上架系統。每一次更新上架都會重新build。
倒也已經不會再理會這個問題了。
不過因為我是同程式多個站。
所以還是得搭配一下env的機制。