环境变量与配置
本教程共 42 篇 · 第 23 篇 · 更新于 2026-07-30 · 约 6 分钟阅读
23. 环境变量与配置
本节目标:理解 Next.js 环境变量的加载顺序与安全边界,掌握服务端变量和客户端变量的区别,学会在不同环境中管理配置。
环境变量基础
Next.js 内置支持从 .env 文件加载环境变量到 process.env,无需额外安装 dotenv 等工具。
环境变量文件
Next.js 支持以下环境变量文件,按优先级从高到低:
| 文件 | 用途 | 是否提交 Git |
|---|---|---|
.env | 默认变量,所有环境共享 | 可以 |
.env.local | 本地覆盖,不提交 Git | 禁止 |
.env.development | 开发环境变量(next dev) | 可以 |
.env.production | 生产环境变量(next build/start) | 可以 |
.env.test | 测试环境变量 | 可以 |
.env.development.local | 开发环境本地覆盖 | 禁止 |
.env.production.local | 生产环境本地覆盖 | 禁止 |
安全第一
create-next-app模板会自动将所有.env*文件加入.gitignore。永远不要将包含敏感信息的.env.local提交到代码仓库。
基本用法
# .env.local
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
在 Route Handler 或 Server Component 中使用:
// app/api/data/route.ts
export async function GET() {
const db = await connect({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
NEXT_PUBLIC_ 前缀
环境变量分为两类:服务端变量和客户端变量。
服务端变量(默认)
不以 NEXT_PUBLIC_ 开头的变量仅在服务端可用,不会暴露给浏览器:
# .env
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
API_SECRET_KEY=sk-xxxxxxxxxxxx
这些变量只能在 Server Components、Route Handlers、Server Actions 和 Proxy 中使用。
客户端变量(NEXT_PUBLIC_ 前缀)
以 NEXT_PUBLIC_ 开头的变量会被内联到 JavaScript 包中,在浏览器端也可访问:
# .env
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
// 客户端组件中可以直接使用
'use client'
export function Analytics() {
const gaId = process.env.NEXT_PUBLIC_GA_ID
// gaId 在浏览器中可用
}
构建时内联
NEXT_PUBLIC_变量在next build时被替换为实际值,构建完成后无法更改。这意味着同一个构建产物在不同环境中这些值是固定的。
变量引用
Next.js 支持在 .env 文件中引用其他变量:
# .env
BASE_URL=https://example.com
API_URL=$BASE_URL/api
# process.env.API_URL → https://example.com/api
如果值中包含 $ 字符,需要转义:\$。
多行变量
Next.js 支持多行环境变量值:
# .env
# 方式一:使用换行
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
Kh9NV...
...
-----END RSA PRIVATE KEY-----"
# 方式二:使用 \n
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END RSA PRIVATE KEY-----"
环境变量加载顺序
当同一个变量在多个文件中定义时,按以下顺序查找,找到即停止:
process.env(系统环境变量).env.{NODE_ENV}.local.env.local(NODE_ENV=test时不加载).env.{NODE_ENV}.env
例如,当 NODE_ENV=development 时,.env.development.local 中的值会覆盖 .env.development 和 .env 中的同名变量。
运行时环境变量
默认情况下,NEXT_PUBLIC_ 变量在构建时被内联。如果你需要在运行时读取环境变量(例如同一个 Docker 镜像部署到多个环境),可以在服务端组件中这样做:
// app/page.tsx
import { connection } from 'next/server'
export default async function Page() {
await connection() // 触发动态渲染
// 在动态渲染模式下,环境变量在运行时读取
const value = process.env.MY_RUNTIME_VALUE
return <div>{value}</div>
}
仅服务端可用
运行时环境变量仍然只在服务端可用。客户端组件无法在运行时读取新的环境变量值。
在 Next.js 配置中使用环境变量
next.config.ts 在模块加载时执行,此时 .env 文件还未加载。如果需要在配置中使用环境变量,使用 @next/env:
// envConfig.ts
import { loadEnvConfig } from '@next/env'
const projectDir = process.cwd()
loadEnvConfig(projectDir)
// next.config.ts
import './envConfig'
const nextConfig = {
env: {
customKey: process.env.CUSTOM_KEY || 'default',
},
}
export default nextConfig
测试环境变量
测试环境(NODE_ENV=test)有一些特殊行为:
- 不加载
.env.local:确保测试结果可复现 - 加载
.env.test:可以定义测试专用变量 - 加载
.env.test.local:测试环境的本地覆盖
# .env.test
DATABASE_URL=postgresql://test:test@localhost:5432/testdb
在测试中加载环境变量:
// jest.setup.ts
import { loadEnvConfig } from '@next/env'
export default async () => {
loadEnvConfig(process.cwd())
}
安全最佳实践
- 敏感信息只放服务端变量:API 密钥、数据库密码等永远不加
NEXT_PUBLIC_前缀 .env.local加入.gitignore:防止敏感信息泄露- 生产环境使用平台的环境变量管理:Vercel、Railway 等平台提供加密的环境变量存储
- 定期轮换密钥:API 密钥和数据库密码应定期更换
- 最小权限原则:不同环境使用不同的密钥,避免开发环境密钥用于生产
小结
- 服务端变量:默认行为,仅在服务端可用,安全
- 客户端变量:
NEXT_PUBLIC_前缀,构建时内联到 JS 包 - 加载顺序:
.env.{NODE_ENV}.local>.env.local>.env.{NODE_ENV}>.env - 运行时变量:服务端动态渲染模式下可读取运行时环境变量
- 安全原则:敏感信息永远不加
NEXT_PUBLIC_前缀