❯❯ 切換環境不必重新打包!用 Nuxt RuntimeConfig 與單一 Http 出口收斂全站 API 控制點
📍 流水線位置|入口 → flow → 型別 → mock → 測試 → UI → vibe → 【上線】(資料源)

還記得 Day 12 那大刀一揮,96 支 handler 從記憶體陣列全面搬到 PostgreSQL,整個資料持久層都換掉了。然而大功告成後,那顆負責資料源轉向的 變數,居然自始至終連動都沒動過。
整個專案裡,管資料源轉向的變數就只有這一顆,這主要是為了避免多份設定檔各自演進,導致不同環境的設定逐漸走樣。
Day 11 結尾我預告過:從 Mock 切到實體後端,核心只需要調一個環境變數。但實際上連資料庫都換掉的那天,我連這唯一的變數都沒摸到。就是因為前後端邊界切得夠乾淨,後端底層怎麼大改,對前端來說根本完全透明。
這篇就讓我來拆解,這顆「穩如泰山」的變數背後藏著怎樣的設計邏輯。

先看 nuxt.config.ts 裡的設定片段:
// 統一 API domain,可由 NUXT_PUBLIC_API_BASE 覆蓋
// 預設空字串:path_prefix(/api/v1)已內嵌在各 *.api.ts 的路徑字串中
apiBase: '',
這顆變數主要支援兩種配置與運作模式:
1. 預設模式(空字串):
什麼都不必設。前端請求直接打向當前 Node.js server 內建的路由,也就是 Day 11 介紹過,位於 server/api/ 目錄下那些端點。
2. 外部轉向(指定完整 URL):
只要填入外部網址後,所有 API 請求會自動把這個 URL 拼在路徑最前面,將全站請求轉向外部後端服務。這條路正是為了「前後端分離、後端由獨立團隊維護」的情境所預留的(如公司裡這類協同開發專案)。
一顆變數能管完全站,關鍵在於 Day 11 的鐵律:UI 元件禁止私下發 Request。
所有的 API 呼叫都必須統一收在 app/api/ 的 typed client,最終底層統一經由 app/composables/useHttp.ts 發送。
翻開 useHttp.ts,初始化的首要任務就是讀取這顆變數:
const baseURL = useRuntimeConfig().public.apiBase
出口收斂成一個,控制點自然也只需要一顆。

這全靠 Nuxt 框架的 runtimeConfig 覆蓋機制:只要環境變數以 NUXT_PUBLIC_ 開頭,伺服器啟動時就會自動覆蓋 runtimeConfig.public 裡的同名欄位。切換環境只需要一行指令:
# 同一份 build,起 server 時給值,前端就轉向外部後端
NUXT_PUBLIC_API_BASE=https://api.your-backend.com node .output/server/index.mjs
這行指令跟專案 Dockerfile 的結尾 CMD ["node", ".output/server/index.mjs"]完全一致。Container 跑起來後的行為,完全取決於執行環境注入的變數值。
這樣做最大的好處是落實「建置產物一致性(Build Artifact Consistency)」:測試環境與正式環境跑的是完全相同的建置產物,差別只在伺服器啟動時注入的環境變數。過去因為針對不同環境各自打包而造成的「環境設定漂移」,從源頭就被根治了。
雖然在我這個前後端同捆的 Nuxt 婚禮系統裡,這顆變數根本沒派上用場、從頭到尾保持空字串;但它的威力,完全體現在資料庫被整棟拆掉重蓋的那一天。
拉回 Day 12 那次重構,96 支 handler 從記憶體陣列一路切到 PostgreSQL,資料持久層動了大刀,但 NUXT_PUBLIC_API_BASE 卻連一個字元都沒動過。
道理說穿了很簡單:這顆變數只負責「把請求送去對的地方」,至於門後面是記憶體還是 PostgreSQL,那是後端自己的事。
只要 API Contract 沒變,裡面的引擎怎麼換,對外面的人來說就像什麼事都沒發生過一樣。控制點劃得越精準,系統重構時就越不需要動到無關的螺絲。
npm run dev 就能跑好的環境管理,最終落腳點一定是「本機開發的開箱即用(DX)」。這件事其實不需要複雜的 script,直接記在 package.json 就好:
"predev": "docker compose up -d --wait db",
"dev": "nuxt dev"
跑 npm run dev 之前,predev 鉤子會先自動拉起本機的 PostgreSQL Container;加上 --wait 參數後,Docker 會持續進行 Healthcheck(透過 pg_isready 每兩秒探測一次),直到資料庫真的準備就緒,才會放行 Nuxt 開發伺服器。
這樣一來,新夥伴把專案 clone 下來,只需要敲一行 npm run dev,就能拿到包含資料庫的完整運行環境,不用手動裝資料庫、不用配一串環境變數,直接把人為踩坑的機率降到最低。
資料源與環境設定到這裡清理完畢。下一篇,我們來聊自動化守門機制:品質沒達標的 code,到底怎麼確保它絕對進不了 main 分支?
🎒 最小一步|盤點你專案裡的環境設定檔與必要環境變數清單,看看同類型的控制點能不能收斂成一顆環境變數。
📎 本篇證據|nuxt.config.ts 的 apiBase 註解原文・useHttp.ts 的 baseURL 一行・package.json 的 predev script・Dockerfile 的 CMD(皆可在公開 repo 查證)