Skip to content

环境变量 ​

.env 文件 ​

bash
# .env
NUXT_API_SECRET=my-secret-key
NUXT_PUBLIC_API_BASE=https://api.example.com
NUXT_PUBLIC_APP_NAME=MyApp

为什么用 .env 文件?

不同环境(开发/测试/生产)的配置不同(API 地址、密钥等),硬编码到代码中既不安全也不灵活。.env 文件让每个环境使用自己的配置,且不提交到 Git。

映射规则 ​

环境变量名 = NUXT_ + 配置路径(大写,_ 连接)

为什么用 NUXT_ 前缀?

避免与其他系统的环境变量冲突。Nuxt 只读取 NUXT_ 开头的变量。

runtimeConfig 路径环境变量推导过程
apiSecretNUXT_API_SECRETNUXT_ + API_SECRET
public.apiBaseNUXT_PUBLIC_API_BASENUXT_ + PUBLIC_API_BASE
public.appNameNUXT_PUBLIC_APP_NAMENUXT_ + PUBLIC_APP_NAME
database.hostNUXT_DATABASE_HOSTNUXT_ + DATABASE_HOST
database.portNUXT_DATABASE_PORTNUXT_ + DATABASE_PORT

推导规则

将配置路径中的 . 替换为 _,全部大写,加上 NUXT_ 前缀。如 database.host → DATABASE_HOST → NUXT_DATABASE_HOST。

定义运行时配置 ​

ts
// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // 服务端私有(客户端无法访问)
    apiSecret: '',
    dbUrl: '',

    // 公共(客户端可访问)
    public: {
      apiBase: '/api',
      appName: 'MyApp',
    },
  },
})

INFO

️ 为什么默认值设为空字符串? 敏感信息不应硬编码在配置文件中 而是通过环境变量在运行时注入。空字符串表示"此值必须由环境变量提供",如果忘记设置,运行时会是空值而非错误的硬编码值

在代码中使用 ​

ts
// 服务端
const config = useRuntimeConfig()
config.apiSecret         // ✅ 可访问
config.public.apiBase    // ✅ 可访问

// 客户端
const config = useRuntimeConfig()
config.apiSecret         // ❌ undefined(安全特性,非 public 的配置不发送到客户端)
config.public.apiBase    // ✅ 可访问

INFO

️ 最常见的错误: 在 runtimeConfig 中声明了配置项但忘记设置默认值或环境变量 导致运行时为 undefined。必须先在 nuxt.config.ts 中声明键名,环境变量才能生效。

环境文件 ​

Nuxt 支持多个环境文件:

text
.env                 # 默认
.env.development     # 开发环境
.env.production      # 生产环境
.env.staging         # 预发布环境

指定环境文件:

bash
npx nuxt dev --dotenv .env.development

加载优先级

当多个 .env 文件同时存在时,特定环境文件(如 .env.production)会覆盖默认文件(.env)中的同名变量。

安全注意事项 ​

  1. 永远不要提交 .env 文件:添加到 .gitignore
  2. 不要在客户端代码中使用敏感信息
  3. public 下的配置会暴露给客户端——任何人都能在浏览器中看到
  4. 使用平台的环境变量功能:Vercel/Netlify 等平台提供环境变量管理,比 .env 文件更安全

安全示例 ​

ts
// ❌ 危险:把密钥放在 public 中
runtimeConfig: {
  public: {
    apiKey: 'sk-xxx',  // 任何人都能在浏览器中看到!
  },
}

// ✅ 安全:密钥放在服务端,通过 API 代理访问
runtimeConfig: {
  apiKey: '',  // 服务端私有,通过 NUXT_API_KEY 环境变量注入
  public: {
    apiBase: '/api',  // 客户端只知道 API 路径
  },
}

运行时 vs 构建时 ​

配置方式何时生效需要重新构建典型用途
runtimeConfig运行时❌API 密钥、数据库 URL
app.config构建时✅主题色、功能开关
环境变量运行时❌覆盖 runtimeConfig 默认值

选择原则

环境相关且可能变化的(密钥、URL)用 runtimeConfig;UI 相关且固定的(主题、布局)用 app.config。

runtimeConfig 与 app.config 对比 ​

维度runtimeConfigapp.config
安全性服务端私有配置不暴露全部暴露到客户端
响应式非响应式响应式(useAppConfig())
环境变量支持 NUXT_ 前缀覆盖不支持
修改方式useRuntimeConfig()updateAppConfig()
典型用途API 密钥、数据库 URL主题色、功能开关

环境变量验证 ​

为什么要验证?

如果必需的环境变量缺失,应用可能在使用时才报错,很难排查。启动时验证可以立即发现问题。

ts
// server/utils/validateConfig.ts
export default defineEventHandler((event) => {
  const config = useRuntimeConfig()

  // 验证必需的环境变量
  if (!config.apiSecret) {
    throw createError({
      statusCode: 500,
      statusMessage: 'Internal Server Error', message: '缺少必需的环境变量: NUXT_API_SECRET',
    })
  }
})

更推荐使用 Zod 进行结构化验证:

ts
// server/utils/env.ts
import { z } from 'zod'

const envSchema = z.object({
  apiSecret: z.string().min(1, 'NUXT_API_SECRET 不能为空'),
  dbUrl: z.string().min(1, 'NUXT_DB_URL 不能为空'),
})

export default defineEventHandler(() => {
  const config = useRuntimeConfig()
  const result = envSchema.safeParse({
    apiSecret: config.apiSecret,
    dbUrl: config.dbUrl,
  })

  if (!result.success) {
    console.error('环境变量验证失败:', result.error.flatten().fieldErrors)
    throw createError({ statusCode: 500, statusMessage: 'Internal Server Error', message: '环境变量配置错误' })
  }
})

CI/CD 中的环境变量 ​

在 GitHub Actions 中安全地注入环境变量:

yaml
# .github/workflows/deploy.yml
- name: Deploy
  env:
    NUXT_API_SECRET: ${{ secrets.API_SECRET }}
    NUXT_PUBLIC_API_BASE: https://api.example.com
  run: |
    npm run build
    npm run deploy

TIP

敏感信息使用 GitHub Secrets 存储 不要直接写在 YAML 文件中

常见问题 ​

问题原因解决方案
环境变量不生效忘记在 runtimeConfig 中声明必须先在 nuxt.config.ts 中声明键名
修改 .env 后不生效开发服务器需要重启重启 nuxt dev,环境变量只在启动时读取
客户端读取私有配置为 undefined非 public 配置不发送到客户端改用 API 代理或移到 public 下(不敏感的话)
环境变量名拼写错误如 NUXT_API_SECRECT(多了一个字母)仔细检查变量名,使用 Zod 验证
Docker 中环境变量不生效未正确传递在 docker run -e 或 docker-compose.yml 中声明
.env 文件编码问题文件包含 BOM 或非 UTF-8 编码使用 UTF-8 无 BOM 编码保存

基于 Nuxt 4 官方文档整理编写