示例说明
配置错误越早暴露代价越小。很多服务把环境变量直接透传到各模块,直到运行到深处才以 undefined 的形式炸出难查的错。把校验集中到启动阶段:类型转换、枚举约束、默认值一站式完成,问题在第一次部署前就会暴露,且校验后的对象带有明确的类型供全项目复用。
技术要点
- z.coerce 把字符串环境变量转换为数字
- 枚举字段拒绝拼错的部署环境取值
- safeParse 聚合输出全部问题而非首个
代码解读
loadEnv 用 safeParse 得到结果对象,失败分支遍历 error.issues 逐条打印字段路径与原因后 exit(1),运维能一次看到所有缺失配置。成功分支返回带默认值填充的强类型数据,后续代码不再触碰原始 process.env。
使用建议
JWT_SECRET 这类安全项应设最小长度门槛。默认值只用于本地开发,生产环境的关键配置建议显式必填。校验逻辑应放在模块加载即执行的位置,保证最早触发。
代码示例
import { z } from 'zod';
const EnvSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
});
function loadEnv() {
const parsed = EnvSchema.safeParse(process.env);
if (!parsed.success) {
for (const issue of parsed.error.issues) {
console.error('invalid env:', issue.path.join('.'), '-', issue.message);
}
process.exit(1);
}
return parsed.data;
}
export const env = loadEnv();
console.log('listening on port', env.PORT, 'in', env.NODE_ENV);