Nuxt 3 如何在 nuxt.config 中配置环境变量区分开发生产?

文章导读
接到这类问题时,我的习惯是先确认对方在哪个环节发现了环境变量不生效。多数时候,问题出在 nuxt.config 里直接写了 if (process.env.NODE_ENV === 'development'),然后在生产构建后执行 nuxt start,发现条件逻辑没按预期走。这里需要解释为什么:
📋 目录
  1. 先看现象:构建后的环境变量和你以为的不一样
  2. 容易误判的两种写法
  3. 稳妥处理顺序:用 runtimeConfig 兜底
  4. 验证方法:前后端分开打印
  5. 回滚与风险:公共变量的泄露边界
  6. 后续维护:保持配置与部署环境同步
A A

先看现象:构建后的环境变量和你以为的不一样

接到这类问题时,我的习惯是先确认对方在哪个环节发现了环境变量不生效。多数时候,问题出在 nuxt.config 里直接写了 if (process.env.NODE_ENV === 'development'),然后在生产构建后执行 nuxt start,发现条件逻辑没按预期走。这里需要解释为什么:

在 Nuxt 3 中,区分开发与生产环境最直接的方式是依赖 `process.env.NODE_ENV`。在 `nuxt.config` 中,你可以通过 `process.env.NODE_ENV === 'development'` 或 `'production'` 来编写条件逻辑。但注意,这个变量在构建时被静态替换,如果你在构建后动态运行服务器,其值可能不准确。例如,使用 `nuxt dev` 时 `NODE_ENV` 为 `development`,而 `nuxt build` 后 `nuxt start` 时则为 `production`。

推荐在 `nuxt.config` 中使用 `runtimeConfig` 来暴露环境变量,而非直接引用 `process.env`。你可以在配置中定义 `publicRuntimeConfig` 和 `privateRuntimeConfig`,并通过 `process.env` 赋值默认值。例如:`publicRuntimeConfig: { apiBase: process.env.NUXT_API_BASE || 'http://localhost:3000' }`。然后在组件中通过 `useRuntimeConfig()` 获取,自动区分环境。

在 Nuxt 3 中,区分开发与生产环境最直接的方式是依赖 process.env.NODE_ENV。在 nuxt.config 中,你可以通过 process.env.NODE_ENV === 'development''production' 来编写条件逻辑。但注意,这个变量在构建时被静态替换,如果你在构建后动态运行服务器,其值可能不准确。例如,使用 nuxt devNODE_ENVdevelopment,而 nuxt buildnuxt start 时则为 production
也就是说,构建阶段就已经决定了 NODE_ENV 的值,运行时不会重新读取。如果你在构建后改了环境变量(比如在启动脚本中重新设置了 NODE_ENV),nuxt.config 里已经硬编码了构建时的值。

容易误判的两种写法

不少人会把 process.env 直接写在 nuxt.config 顶层,以为每次请求都会重新计算。但实际上 nuxt.config 只执行一次——在构建阶段。以下两种写法都有隐患:

Nuxt 3 如何在 nuxt.config 中配置环境变量区分开发生产?
  • 在配置顶层用 process.env 做条件判断:比如 export default defineNuxtConfig({ css: process.env.NODE_ENV === 'development' ? ['dev.css'] : [] }),这个条件只会在构建时生效,运行时不会变化。
  • 在配置里引用 process.env 作为默认值:比如 publicRuntimeConfig: { apiBase: process.env.API_BASE },如果构建时没有设置 API_BASE,它就变成 undefined,且不会在运行时被覆盖(因为 publicRuntimeConfig 的值在构建时就被内联到客户端代码中)。

一个常见错误是在 nuxt.config 顶层直接使用 process.env 并认为运行时仍能动态变化。实际上,nuxt.config 在构建阶段执行,所有 process.env 引用都会被替换为当时的值。若需要在运行时动态区分环境,应使用 runtimeConfig 或通过 nitro 配置中的 env 选项。另外,切勿在客户端代码中暴露私密变量,即使通过 privateRuntimeConfig 也不行。

稳妥处理顺序:用 runtimeConfig 兜底

推荐在 nuxt.config 中使用 runtimeConfig 来暴露环境变量,而非直接引用 process.env。你可以在配置中定义 publicRuntimeConfigprivateRuntimeConfig,并通过 process.env 赋值默认值。例如:publicRuntimeConfig: { apiBase: process.env.NUXT_API_BASE || 'http://localhost:3000' }。然后在组件中通过 useRuntimeConfig() 获取,自动区分环境。

这里的关键在于:runtimeConfig 的值在构建时会被序列化并合并到 Nitro 的运行时配置中。对于 publicRuntimeConfig,所有客户端代码都能拿到(因为会内联到 JS bundle);而 privateRuntimeConfig 仅在服务端渲染阶段可用。所以处理顺序建议是:

  1. 先确定变量是否需要在客户端公开(比如 API 基础路径、CDN URL),放在 publicRuntimeConfig 中。
  2. 对于仅服务端使用的密钥(如数据库密码、私密 token),放在 privateRuntimeConfig 中。
  3. nuxt.config 中统一为这些变量设置默认值,默认值可以在开发时用 .env 文件覆盖,生产环境通过系统环境变量传入。

注意:runtimeConfig 中的 process.env 引用也只在构建时求值,但比直接把逻辑写在顶层更灵活,因为 runtimeConfig 的值可以在构建后通过 Nitro 运行时配置覆盖(需要配合 NITRO_ENV 或部署平台的环境变量机制)。

Nuxt 3 如何在 nuxt.config 中配置环境变量区分开发生产?

验证方法:前后端分开打印

为了验证环境变量是否按预期生效,可以在开发模式和生产模式下分别打印 useRuntimeConfig() 的内容。在 app.vue 或任意页面中插入 {{ useRuntimeConfig() }},然后对比 nuxt devnuxt build && nuxt start 的输出。注意生产模式下 publicRuntimeConfig 会内联到客户端代码,而 privateRuntimeConfig 仅服务端可用。

具体操作:

  • 开发模式:执行 nuxt dev,打开浏览器查看页面渲染的 JSON 对象。确认 publicRuntimeConfig 中的值正确。
  • 生产模式:先执行 nuxt build,再 nuxt start。查看浏览器端打印的内容,对比 publicRuntimeConfig 是否与构建时环境变量一致。如果使用了 privateRuntimeConfig,可以写一个简单的 server API(比如 server/api/config.ts)返回 useRuntimeConfig(),通过 curl 或浏览器访问确认服务端值。

如果发现值不对,检查三点:

Nuxt 3 如何在 nuxt.config 中配置环境变量区分开发生产?
  1. 构建时是否设置了对应的环境变量(比如 NUXT_API_BASE)。
  2. .env 文件是否放在了项目根目录(仅开发时自动加载,生产构建不会读取 .env,需手动设置系统环境变量)。
  3. 是否在 nuxt.config 中错误地覆盖了 runtimeConfig 的默认值。

回滚与风险:公共变量的泄露边界

使用 runtimeConfig 时,publicRuntimeConfig 中定义的所有变量都会打包到客户端 bundle 中,因此仅适合存放非敏感的公共配置(如 API 基础路径)。私有变量(如 API Key)必须放在 privateRuntimeConfig 中,并确保只在服务端代码(如 server/api 或 middleware)中调用。同时,注意 .env 文件的优先级:根目录下的 .env 文件会被自动加载,但 nuxt.config 中直接定义的默认值不会覆盖环境变量。

如果误将敏感变量放入了 publicRuntimeConfig,回滚方法很简单:重新构建前将其移到 privateRuntimeConfig,并检查客户端代码中是否有任何引用。另外,生产环境中如果发现 runtimeConfig 的值不对,可以临时通过系统环境变量覆盖(比如设置 NUXT_PUBLIC_API_BASENUXT_API_BASE 取决于命名规则),但注意这需要重新构建或重启服务(取决于部署平台对 Nitro 运行时配置的支持程度)。

后续维护:保持配置与部署环境同步

项目稳定后,建议把 runtimeConfig 的默认值写清楚,并维护一份 .env.example 文件列出所有需要的变量及其用途。在 CI/CD 流程中,构建阶段注入环境变量时,确保 publicRuntimeConfig 对应的变量名与 nuxt.config 中引用的 process.env 名称一致(大小写敏感)。另外,如果需求是在运行时动态切换环境(比如多租户),单靠 runtimeConfig 不够,需要结合 Nitro 的 middleware 或自定义插件,这已经超出本次排查范围。

总结一句:先把 nuxt.config 中的条件判断和 process.env 引用替换成 runtimeConfig,然后分别验证开发和生产两种模式下的打印结果,最后确认敏感变量没有被泄露。这套流程能覆盖 90% 的环境变量配置问题。