Nuxt 4 运行时配置:开发与生产环境优雅切换 API
同一套 Nuxt 代码通常要运行在本地、测试和生产环境。最容易留下隐患的做法,是在组件里散落 process.env,或把接口域名直接写死。Nuxt 4 提供的 runtimeConfig 可以把配置集中管理,并明确哪些值能够暴露给浏览器。
先分清 public 与私密配置
| 配置位置 | 服务端可用 | 客户端可用 | 典型用途 |
|---|---|---|---|
runtimeConfig 根级别 |
是 | 否 | API 密钥、内部服务地址 |
runtimeConfig.public |
是 | 是 | 公共 API 地址、站点域名 |
只要放进 public,它就会进入页面 payload,用户能够在浏览器里看到。因此数据库密码、签名密钥和第三方私钥绝不能放在 public。
在 nuxt.config.ts 中声明默认值
export default defineNuxtConfig({
runtimeConfig: {
apiSecret: '',
internalApiBase: 'http://127.0.0.1:48090',
public: {
apiBase: 'http://127.0.0.1:40090/app-api',
siteUrl: 'http://localhost:3000',
},
},
})
声明配置项后,Nuxt 才知道哪些环境变量允许覆盖它们。与其在这里读取名字完全不同的环境变量,更稳妥的方式是使用 Nuxt 约定的变量名。
环境变量命名规则
层级通过下划线连接,并以 NUXT_ 开头:
NUXT_API_SECRET=server-only-secret
NUXT_INTERNAL_API_BASE=http://127.0.0.1:48090
NUXT_PUBLIC_API_BASE=https://www.example.com/app-api
NUXT_PUBLIC_SITE_URL=https://www.example.com
runtimeConfig.public.apiBase 对应 NUXT_PUBLIC_API_BASE。这种命名既能在开发阶段生效,也能在构建后的 Node 服务启动时覆盖配置。
在页面和服务端读取配置
页面、组件和 composable 中:
const config = useRuntimeConfig()
const { data } = await useFetch('/blog/article/page', {
baseURL: config.public.apiBase,
})
Nitro 服务端路由中建议把 event 传给 useRuntimeConfig:
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig(event)
return await $fetch('/internal/statistics', {
baseURL: config.internalApiBase,
headers: {
Authorization: `Bearer ${config.apiSecret}`,
},
})
})
浏览器只能访问 config.public 与 Nuxt 内部的 app 配置,根级别私密配置只存在于服务端。
开发环境与生产环境如何设置
本地开发可以在项目根目录的 .env 中写:
NUXT_PUBLIC_API_BASE=http://127.0.0.1:40090/app-api
NUXT_PUBLIC_SITE_URL=http://localhost:3000
生产环境不要依赖构建目录旁边的 .env。Nuxt 官方文档明确说明:运行构建后的服务时,不会自动读取项目的 .env。应在宝塔、Docker、systemd、PM2 或云平台的环境变量面板中配置,再启动:
NODE_ENV=production \
NUXT_PUBLIC_API_BASE=https://www.example.com/app-api \
NUXT_PUBLIC_SITE_URL=https://www.example.com \
node .output/server/index.mjs
封装统一请求客户端
接口多起来后,可以在插件里集中设置 baseURL:
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
const api = $fetch.create({
baseURL: config.public.apiBase,
timeout: 10_000,
onResponseError({ response }) {
console.error('API 请求失败', response.status)
},
})
return { provide: { api } }
})
使用时通过 useNuxtApp().$api 调用,后续增加请求头、错误提示和登录失效处理都有统一入口。
常见问题
- 修改服务器环境变量后没有重启 Node 进程。
- 配置未先声明在
nuxt.config.ts中。 - 生产运行仍期待 Nuxt 自动读取
.env。 - 把私钥放进
runtimeConfig.public。 - 使用了不符合层级结构的环境变量名。
- 在客户端请求里写服务器内网地址,导致用户浏览器无法访问。
小结
环境配置的核心不是多准备几个文件,而是把公开配置和私密配置划清边界,并使用可以在运行时覆盖的标准变量名。做到这一点,同一份 .output 就能在不同环境部署,而不需要为了更换 API 地址重新修改业务代码。