环境变量
.env 文件
# .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 路径 | 环境变量 | 推导过程 |
|---|---|---|
apiSecret | NUXT_API_SECRET | NUXT_ + API_SECRET |
public.apiBase | NUXT_PUBLIC_API_BASE | NUXT_ + PUBLIC_API_BASE |
public.appName | NUXT_PUBLIC_APP_NAME | NUXT_ + PUBLIC_APP_NAME |
database.host | NUXT_DATABASE_HOST | NUXT_ + DATABASE_HOST |
database.port | NUXT_DATABASE_PORT | NUXT_ + DATABASE_PORT |
推导规则
将配置路径中的 . 替换为 _,全部大写,加上 NUXT_ 前缀。如 database.host → DATABASE_HOST → NUXT_DATABASE_HOST。
定义运行时配置
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// 服务端私有(客户端无法访问)
apiSecret: '',
dbUrl: '',
// 公共(客户端可访问)
public: {
apiBase: '/api',
appName: 'MyApp',
},
},
})INFO
️ 为什么默认值设为空字符串? 敏感信息不应硬编码在配置文件中 而是通过环境变量在运行时注入。空字符串表示"此值必须由环境变量提供",如果忘记设置,运行时会是空值而非错误的硬编码值
在代码中使用
// 服务端
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 支持多个环境文件:
.env # 默认
.env.development # 开发环境
.env.production # 生产环境
.env.staging # 预发布环境指定环境文件:
npx nuxt dev --dotenv .env.development加载优先级
当多个 .env 文件同时存在时,特定环境文件(如 .env.production)会覆盖默认文件(.env)中的同名变量。
安全注意事项
- 永远不要提交
.env文件:添加到.gitignore - 不要在客户端代码中使用敏感信息
public下的配置会暴露给客户端——任何人都能在浏览器中看到- 使用平台的环境变量功能:Vercel/Netlify 等平台提供环境变量管理,比
.env文件更安全
安全示例
// ❌ 危险:把密钥放在 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 对比
| 维度 | runtimeConfig | app.config |
|---|---|---|
| 安全性 | 服务端私有配置不暴露 | 全部暴露到客户端 |
| 响应式 | 非响应式 | 响应式(useAppConfig()) |
| 环境变量 | 支持 NUXT_ 前缀覆盖 | 不支持 |
| 修改方式 | useRuntimeConfig() | updateAppConfig() |
| 典型用途 | API 密钥、数据库 URL | 主题色、功能开关 |
环境变量验证
为什么要验证?
如果必需的环境变量缺失,应用可能在使用时才报错,很难排查。启动时验证可以立即发现问题。
// 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 进行结构化验证:
// 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 中安全地注入环境变量:
# .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 deployTIP
敏感信息使用 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 编码保存 |