当前位置: 首页 > news >正文

为什么需要专门的环境变量解决方案?

类型安全问题:环境变量没有类型检查,容易在运行时出错

验证缺失:无法确保必需的环境变量都已正确配置

客户端/服务端混淆:可能意外将敏感变量暴露到客户端

团队协作困难:新成员不知道需要配置哪些环境变量

T3 Env 正是为了解决这些问题而生,它提供了类型安全的环境变量管理方案。

server variables

client variables

shared variables

非法/缺失

.env

.env.local

src/env.js

createEnv({…})

Zod Schema

校验层

服务端代码

getStaticProps / API Routes …

客户端代码

浏览器 Bundle

两端共享

NODE_ENV …

运行时抛错

构建失败

核心特性

1. 类型安全的环境变量

import { createEnv } from "@t3-oss/env-nextjs";

import { z } from "zod";

const env = createEnv({

server: {

DATABASE_URL: z.string().url(),

API_SECRET: z.string().min(1),

},

client: {

NEXT_PUBLIC_API_URL: z.string().url(),

},

runtimeEnv: {

DATABASE_URL: process.env.DATABASE_URL,

API_SECRET: process.env.API_SECRET,

NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,

},

});

2. 运行时验证

库在应用启动时会自动验证所有环境变量,如果缺少必需变量或类型不匹配,会立即抛出清晰错误,而不是在运行时神秘崩溃。

3. 客户端/服务端自动隔离

通过明确的配置区分,确保服务端敏感变量不会意外泄漏到客户端。

配置指南

基础安装与配置

npm install @t3-oss/env-nextjs zod

注意:T3 Env 提供了多个包, 如 @t3-oss/env-nextjs 和 @t3-oss/env-core,分别用于 Next.js 和普通 Node.js 项目。

创建 env.js 文件:

import { createEnv } from "@t3-oss/env-nextjs";

import { z } from "zod";

export const env = createEnv({

server: {

// 服务端专用环境变量

DATABASE_URL: z.string().url(),

GITHUB_CLIENT_SECRET: z.string().min(1),

NODE_ENV: z.enum(["development", "test", "production"]),

},

client: {

// 客户端可访问的环境变量

NEXT_PUBLIC_API_BASE_URL: z.string().url(),

NEXT_PUBLIC_APP_VERSION: z.string().min(1),

},

// 运行时环境变量映射

runtimeEnv: {

DATABASE_URL: process.env.DATABASE_URL,

GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,

NODE_ENV: process.env.NODE_ENV,

NEXT_PUBLIC_API_BASE_URL: process.env.NEXT_PUBLIC_API_BASE_URL,

NEXT_PUBLIC_APP_VERSION: process.env.NEXT_PUBLIC_APP_VERSION,

},

// 跳过某些环境变量的验证(可选)

skipValidation: !!process.env.SKIP_ENV_VALIDATION,

});

高级验证场景

const env = createEnv({

server: {

// 复杂验证规则

PORT: z.string().regex(/^\d+$/).transform(Number),

FEATURE_FLAGS: z.string().transform((str) => str.split(',')),

MAX_UPLOAD_SIZE: z.string().default('10').transform(Number),

// 条件验证

DATABASE_URL: z.string().url().optional(),

DATABASE_HOST: z.string().min(1).optional(),

}).refine(

(data) => data.DATABASE_URL || data.DATABASE_HOST,

"Either DATABASE_URL or DATABASE_HOST must be provided"

),

});

实际应用

API 路由中的使用

// pages/api/users.ts

import { env } from "../../env";

import { NextApiRequest, NextApiResponse } from "next";

export default async function handler(

req: NextApiRequest,

res: NextApiResponse

) {

// 类型安全的环境变量访问

const databaseUrl = env.DATABASE_URL;

const apiSecret = env.API_SECRET;

// 业务逻辑...

res.status(200).json({ success: true });

}

客户端组件中的使用

// components/UserProfile.tsx

import { env } from "../env";

export function UserProfile() {

// 只能访问客户端环境变量

const apiUrl = env.NEXT_PUBLIC_API_BASE_URL;

return (

<div>

<p>API Base URL: {apiUrl}</p>

</div>

);

}

与 Next.js 配置集成

// next.config.js

const { env } = require("./env");

/** @type {import('next').NextConfig} */

const nextConfig = {

env: {

CUSTOM_KEY: "value",

},

publicRuntimeConfig: {

apiUrl: env.NEXT_PUBLIC_API_BASE_URL,

},

};

module.exports = nextConfig;

真实案例

create-t3-app

create-t3-app 是一个快速构建全栈 TypeScript 应用的脚手架,集成了 Next.js、tRPC、Prisma、Tailwind CSS 等现代工具。它以“强类型、可扩展、开发体验优先”为核心理念,帮助开发者快速搭建高质量的 Web 应用。

nahida-template

我搭建的 nahida-template,就用到了 @t3-oss/env-core。nahida-template 是基于 Elysia.js、Next.js 16 和 TypeScript 的现代全栈单仓模板,提供高性能与端到端类型安全支持。欢迎 star 和提建议。

import { createEnv } from "@t3-oss/env-core"

import { z } from "zod"

export const env = createEnv({

shared: {

NODE_ENV: z

.enum(["development", "production", "test"])

.default("development"),

PORT: z.number().default(3001),

},

/**

* Specify your server-side environment variables schema here. This way you can ensure the app

* isn't built with invalid env vars.

*/

server: {

NODE_ENV: z

.enum(["development", "test", "production"])

.default("development"),

DATABASE_URL: z.string().url(),

BETTER_AUTH_SECRET: z.string(),

BETTER_AUTH_URL: z.string().url(),

GITHUB_CLIENT_ID: z.string(),

GITHUB_CLIENT_SECRET: z.string(),

},

/**

* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.

* middlewares) or client-side so we need to destruct manually.

*/

runtimeEnv: {

NODE_ENV: process.env.NODE_ENV,

DATABASE_URL: process.env.DATABASE_URL,

BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET,

BETTER_AUTH_URL: process.env.BETTER_AUTH_URL,

GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,

GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,

// NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,

},

/**

* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially

* useful for Docker builds.

*/

skipValidation: !!process.env.SKIP_ENV_VALIDATION,

/**

* Makes it so that empty strings are treated as undefined. `SOME_VAR: z.string()` and

* `SOME_VAR=''` will throw an error.

*/

emptyStringAsUndefined: true,

})

性能与安全考量

性能

环境变量验证只在启动时进行一次

支持设置 skipValidation: true 跳过运行时验证

使用环境变量缓存避免重复初始化

安全最佳实践

永远不要将敏感信息提交到版本控制

使用不同的密钥用于开发、测试和生产环境

定期轮换密钥和密码

使用密钥管理服务(如 AWS Secrets Manager)

总结

http://www.cnnetsun.cn/news/49536.html

相关文章:

  • 14、网络PF配置的日志、监控、统计与优化
  • pvar2连玉君安装包:轻松掌握数据分析利器
  • Python 3.13兼容性终极指南:rembg背景移除工具深度解密
  • 如何快速配置NeverSink过滤器:POE2玩家的终极指南
  • 24、Ubuntu系统的多任务处理与性能优化技巧
  • AI终会替代IT从业者?答案藏在“不可替代的核心价值”里
  • Feather图标库TypeScript转型指南:从无类型到类型安全的优雅升级
  • MotionGPT终极指南:用AI将文本转化为生动人体动作
  • ipympl 终极指南:在 Jupyter 中实现 Matplotlib 交互式绘图
  • raylib实战指南:构建你的第一个跨平台游戏
  • MySQL篇(为啥会有非关系型数据库?MySQL的数据存储一定在磁盘吗?)
  • 7大核心技巧:掌握Seal智能文件命名系统,告别混乱视频管理
  • 基于vue的讲座管理系统设计与实现_1exeip5l_springboot php python nodejs
  • 正点原子IMX6ULL开发板U-Boot编译
  • Neovim代码补全终极指南:极速配置与智能提示
  • 【Kubernetes】使用Helm简化k8s部署、管理
  • 零基础也能搭建企业官网:Halo开源建站工具实战指南
  • Open-SaaS邮件系统性能优化实战:构建高并发异步处理架构
  • 基于vue的考研信息共享平台_a5a399ip_springboot php python nodejs
  • ROAPI零代码API构建完整指南:从入门到实战
  • 基于vue的小明餐厅点餐平台的设计_9yzk5cgp_springboot php python nodejs
  • 35、掌握Bash脚本:提升Linux管理效率的秘诀
  • 软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(13)
  • Proxy Audio Device:macOS虚拟音频驱动器的完整指南
  • 终极PHP调试解决方案:用symfony/debug实现高效错误处理
  • 智慧养老项目:当SpringBoot遇到硬件,如何优雅地处理异常与状态管理?
  • 5步轻松搞定AppSmith实时推送:告别消息延迟的终极指南
  • IOPaint终极指南:AI一键去除水印的完整解决方案
  • Windows更新后RDPWrap失效修复指南:快速恢复多用户远程桌面功能
  • GPU和TPU差异之联网