关于 infra-config-setup-env
为开发者提供环境变量管理指南,涵盖按应用配置、启动时使用 Zod 校验及密钥保护,适用于 Next.js、Vite 和 monorepo 项目。
主要功能
- 01按应用划分 .env 文件
- 02启动时用 Zod 校验环境变量
- 03遵循框架客户端变量前缀
- 04维护 .env.example 模板
- 05安全管理密钥与功能标志
适用场景
- 01为 Next.js 或 Vite 项目配置类型安全环境变量
- 02在 monorepo 中隔离各应用配置
- 03防止密钥提交到版本控制
- 04通过环境变量控制简单功能标志
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agents-inc/ skills --skill infra-config-setup-env安装后在 Claude Code 中输入/infra-config-setup-env确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.yamlreference.mdexamples/core.mdfeature-flags-and-config.mdnaming-and-templates.mdsecurity-and-secrets.mdt3-env.md详细介绍
环境管理
快速指南: 使用每个应用各自的 .env 文件。使用框架特定的前缀(Next.js 使用
NEXT_PUBLIC_*,Vite 使用VITE_*)。在启动时通过 Zod 验证。维护.env.example模板。绝不提交密钥(.gitignore)。使用基于环境的功能开关。
<critical_requirements>
重要:使用此技能前
所有代码都必须遵循项目在 CLAUDE.md 中的约定(kebab-case、命名导出、导入顺序、
import type、命名常量)
(必须在应用启动时使用 Zod 验证所有环境变量)
(客户端变量必须使用框架特定的前缀——Next.js 使用 NEXT_PUBLIC_*,Vite 使用 VITE_*)
(必须维护 .env.example 模板,并记录所有必需变量)
(绝不将密钥提交到版本控制中——使用 .env.local 和 CI 密钥)
(必须为每个应用使用各自的 .env 文件——不得使用根目录级别的 .env 文件)
</critical_requirements>
自动检测: 环境变量、.env 文件、Zod 验证、t3-env、@t3-oss/env、密钥管理、NEXT_PUBLIC_ 前缀、VITE_ 前缀、功能开关、z.stringbool
适用场景:
- 设置 Zod 验证,在启动时对环境变量进行类型安全检查
- 使用框架特定的前缀管理每个应用各自的 .env 文件
- 保护密钥(绝不提交,使用
.env.local和 CI 密钥) - 实现基于环境的功能开关
不适用场景:
- 运行时配置变更(使用外部功能开关服务)
- 特定用户的设置(使用数据库或用户偏好设置)
- 频繁变更的值(使用配置 API 或数据库)
- 带渐进式发布的复杂 A/B 测试(使用专用功能开关服务)
涵盖的关键模式:
- 每个应用各自的 .env 文件(而非根目录级别的文件,以避免冲突)
- 在启动时使用 Zod 验证,确保类型安全并尽早失败
- 用于 Next.js/Vite 项目的 T3 Env 模式(推荐)
- 框架特定的前缀(客户端使用
NEXT_PUBLIC_*,Vite 客户端使用VITE_*) - 用于文档说明和新成员上手的
.env.example模板
详细资源:
- 代码示例请参阅 examples/ 文件夹:
- examples/core.md - 基本模式(每个应用各自的 .env、Zod 验证)
- examples/t3-env.md - Next.js/Vite 的 T3 Env 模式(推荐)
- examples/naming-and-templates.md - 框架前缀、.env.example
- examples/security-and-secrets.md - 密钥管理
- examples/feature-flags-and-config.md - 功能开关、集中式配置
- 决策框架和反模式请参阅 reference.md
理念
环境管理遵循配置即代码的原则——配置应经过验证、具备类型信息并纳入版本管理。系统使用每个应用各自的 .env 文件和框架特定的前缀,在启动时通过 Zod 验证,并采用严格的安全实践以防止密钥泄露。
核心模式
模式 1:每个应用各自的环境文件
每个应用/包都有自己的 .env 文件,以避免冲突并明确归属。
文件结构
apps/
├── client-next/
│ ├── .env # Local development (NEXT_PUBLIC_API_URL)
│ └── .env.production # Production overrides
├── client-react/
│ ├── .env # Local development
│ └── .env.production # Production overrides
└── server/
├── .env # Local server config
├── .env.example # Template for new developers
└── .env.local.example # Local overrides template
packages/
├── api/
│ └── .env # API package config
└── api-mocks/
└── .env # Mock server config
文件类型及用途
.env- 默认开发值(应用的文件会提交;敏感包的文件会加入 gitignore).env.example- 文档模板(会提交,展示所有必需变量).env.local- 本地开发者覆盖值(加入 gitignore,优先级高于.env).env.production- 生产环境配置(提交或存放在 CI 密钥中).env.local.example- 本地覆盖值模板(会提交)
加载顺序和优先级
Next.js 加载顺序(从高到低):
process.env(已在环境中设置).env.$(NODE_ENV).local(例如,.env.production.local).env.local(NODE_ENV=test时不会加载).env.$(NODE_ENV)(例如,.env.production).env
Vite 加载顺序:
.env.[mode].local(例如,.env.production.local).env.[mode](例如,.env.production).env.local.env
**例外:**可在构建工具的环境配置中放置共享变量,以便进行缓存失效处理
完整代码示例请参见 examples/core.md。
模式 2:使用 Zod 实现类型安全的环境变量
使用 Zod schema 在应用启动时验证环境变量。定义 schema,在启动时解析,并导出类型化的 env 对象。
// lib/env.ts
const envSchema = z.object({
VITE_API_URL: z.string().url(),
VITE_API_TIMEOUT: z.coerce.number().default(DEFAULT_API_TIMEOUT_MS),
VITE_ENABLE_ANALYTICS: z.stringbool().default(false), // Zod 4+ (NOT z.coerce.boolean())
});
export const env = envSchema.parse(import.meta.env);
需要注意的要点:
z.coerce.boolean()会将"false"转换为true(字符串会被视为真值)——请始终改用z.stringbool()- Zod 4 错误处理请使用
error.issues(而非error.errors)
**注意:**对于 Next.js/Vite 项目,可考虑使用 T3 Env(
@t3-oss/env-nextjs或@t3-oss/env-core),以分离客户端/服务端变量并进行构建时验证。请参见 examples/t3-env.md。
完整的优劣对比请参见 examples/core.md。
模式 3:框架专属命名约定
客户端变量使用框架专属前缀,所有环境变量使用 SCREAMING_SNAKE_CASE。
强制约定
- SCREAMING_SNAKE_CASE —— 所有环境变量均使用大写字母和下划线
- 描述性名称 —— 变量名称应清楚表明其用途
- 框架前缀 —— 客户端变量使用
NEXT_PUBLIC_*(Next.js)或VITE_*(Vite)
框架前缀
Next.js:
NEXT_PUBLIC_*—— 客户端可访问(嵌入到打包文件中)——用于 API URL、公开密钥、功能标志- 无前缀 —— 仅服务端可用(数据库 URL、密钥、API 令牌)
Vite:
VITE_*—— 客户端可访问(嵌入到打包文件中)——用于 API URL、公开配置- 无前缀 —— 仅构建时可用(不会暴露给客户端)
Node.js/服务端:
NODE_ENV—— 标准环境(development、production、test)PORT—— 服务端端口号- 无前缀 —— 所有变量均可在服务端使用
完整代码示例及优劣对比请参见 examples/naming-and-templates.md。
集成指南
核心依赖:
- Zod(v4+):用于环境变量的运行时验证和类型推断
- T3 Env(
@t3-oss/env-nextjs、@t3-oss/env-core):推荐用于分离客户端/服务端的封装库
框架支持:
- Next.js:自动加载 .env 文件,客户端变量使用
NEXT_PUBLIC_*前缀 - Vite:自动加载 .env 文件,客户端变量使用
VITE_*前缀
Monorepo 注意事项:
- 在构建工具的环境配置中声明共享环境变量,以便进行缓存失效处理
- 即使在 Monorepo 中也应使用各应用专属的 .env 文件,以避免冲突
替代 / 冲突项:
- 硬编码的配置值(改用环境变量)
- 用于简单布尔标志的运行时功能标志服务(优先使用环境变量,需要逐步发布时再升级)
<decision_framework>
决策框架
完整的决策框架(包括环境配置和功能标志决策)请参见 reference.md。
</decision_framework>
<red_flags>
危险信号
高优先级问题:
- 将密钥提交到版本控制中(包含真实凭据的 .env 文件)
- 直接使用环境变量而不通过 Zod 验证(会导致运行时错误)
- 为密钥使用
NEXT_PUBLIC_*或VITE_*前缀(会将密钥嵌入客户端打包文件)
中优先级问题:
- 缺少 .env.example 文档(导致上手体验不佳)
- 在开发环境中使用生产密钥(存在安全风险)
- 在 monorepo 根目录放置 .env 文件(会导致冲突)
注意事项:
- Next.js/Vite 会在构建时而非运行时嵌入带前缀的变量——修改后需要重新构建
- 环境变量都是字符串——数字请使用
z.coerce.number(),布尔值请使用z.stringbool()(Zod 4+) - 重要:
z.coerce.boolean()会将 "false" 转换为true(字符串会被视为真值)——请改用z.stringbool()(Zod 4+) - 空字符串环境变量并非
undefined——请使用 T3 Env 的emptyStringAsUndefined: true选项 - 除非在构建工具的环境变量配置中声明,否则 monorepo 构建工具的缓存可能不会因环境变量变更而失效
完整的危险信号、反模式和检查清单,请参阅 reference.md。
</red_flags>
<critical_reminders>
重要提醒
所有代码都必须遵循 CLAUDE.md 中的项目规范
(必须在应用启动时使用 Zod 验证所有环境变量)
(客户端变量必须使用特定于框架的前缀——Next.js 使用 NEXT_PUBLIC_*,Vite 使用 VITE_*)
(必须维护 .env.example 模板,并记录所有必需变量)
(绝不能将密钥提交到版本控制中——请使用 .env.local 和 CI 密钥)
(必须为每个应用使用独立的 .env 文件——不得使用根目录级别的 .env 文件)
不遵循这些规则会导致运行时错误、安全漏洞和配置混乱。
</critical_reminders>