环境变量文件
自动环境变量文件加载——文件集合、APP_ENV 模式、优先级、变量展开、测试环境下的跳过、用 --env-file 加载显式文件,以及用 --no-env-file 禁用所有加载。
Nub 在 Node 启动前读取你的 .env* 文件并注入到环境中——不需要 dotenv 导入,不需要 --env-file 标志。加载从最近的有 package.json 的目录发生(从你的 cwd 向上遍历),与 Vite 的单目录模型一致。在 Nub 支持的每个 Node 版本(18.19+)上工作。
nub server.ts # 项目根目录中的 .env* 自动加载文件优先级
四个文件名被加载,最高优先级在前。Shell 环境始终优先于所有文件——进程环境中已设置的值从不被覆盖。
.env.[mode].local.env.local.env.[mode].env
[mode] 槽仅在设置了模式时存在;下面的示例在 production 下解析它们。在 .env* 文件中,第一个定义键的文件获胜(先写者赢);shell 环境位于所有文件之上。
# 读取 .env.production.local, .env.local, .env.production, .env
APP_ENV=production nub server.ts选择模式
模式填充上面的 [mode] 槽。它来自 APP_ENV——设置为非空值,匹配的 .env.[mode] 文件加载。当 APP_ENV 未设置时没有模式,所以只有 .env.local 和 .env 加载。
APP_ENV=production nub server.ts # 读取 .env.production*
APP_ENV=staging nub server.ts # 读取 .env.staging*APP_ENV 是框架中性的选择器:它驱动加载哪些 .env 文件,同时不翻转 NODE_ENV——许多工具读取 NODE_ENV 来切换开发和生产行为。要加载特定文件而非模式,用 --env-file(下方)命名。
模式仅在包含字母、数字、_、. 和 - 时用于构建文件名。带路径分隔符的值(如 APP_ENV=../other)被忽略——[mode] 文件被跳过,.env 和 .env.local 仍加载,且不报错。
NODE_ENV
Nub 将 NODE_ENV 视为你应用的变量:它从不设置它,从不读取它来选择 env 文件,也不允许 env 文件更改它。它不是模式来源——设置 APP_ENV 来选择加载哪些 .env.[mode] 文件。
赋值 NODE_ENV 的 .env 文件在加载时忽略该键——与 dotenv、Next.js 和 Vite 一致——Nub 会警告。否则,固定 NODE_ENV=development 的 .env 会泄漏到生产工具中:例如 next build 随后以开发模式运行其预渲染 worker 来处理生产编译的输出。
测试环境
当模式为 test(来自 APP_ENV=test)时,.env.local 槽被跳过——只有 .env.test.local、.env.test 和 .env 加载。这使开发机器上的 .env.local 密钥不进入测试环境。
变量展开
值支持 ${VAR} 和 $VAR 引用。引用先解析其他已加载的值,然后是 shell 环境;未定义的引用解析为空字符串。展开是多遍的,所以一个值可以引用另一个本身引用第三个的值。
# .env
HOST=localhost
PORT=5432
# 两种形式都有效;$HOST 等价于 ${HOST}
DATABASE_URL=postgres://${HOST}:${PORT}/app用 \$ 转义字面美元符号。注意经典的陷阱:像 PASSWORD=foo$bar 的值在 bar 未设置时截断为 foo,因为 $bar 展开为空字符串——引用并转义为 PASSWORD="foo\$bar"。
显式文件
传递 --env-file=<path> 完全禁用自动 .env* 发现——只有命名的文件加载。Nub 通过与自动文件相同的解析器和相同的 ${VAR} 展开读取它,且 shell 环境仍优先于它。这与 Bun 一致:按名称请求文件,Nub 停止猜测你想要哪些文件。
# 只有 .env.ci 加载;自动 .env* 发现被跳过;shell 环境仍优先
nub --env-file=.env.ci server.ts多次传递 --env-file 按顺序加载多个文件。后面的文件覆盖前面文件设置的键——与 Node 一致——且 shell 环境仍优先于所有文件。
# 两者都加载;.env.production 赢得与 .env 共享的任何键
nub --env-file=.env --env-file=.env.production server.ts缺失的文件是错误。要仅在存在时加载文件并在不存在时静默跳过,使用 --env-file-if-exists——Node v22 的变体。它在所有其他方面与 --env-file 行为一致。
# 如果存在则加载 .env.local;不存在则无错误
nub --env-file-if-exists=.env.local server.ts不加载任何文件
传递 --no-env-file 加载零个 env 文件:自动 .env* 发现被抑制,任何 --env-file 或 --env-file-if-exists 被忽略。Nub 的其他一切——TypeScript、JSX、模块钩子——保持开启。当环境已在其他地方管理(CI、密钥管理器、direnv)且你希望 Nub 不插手时使用它。
# 无 .env* 自动发现,且 --env-file 被忽略——子进程看不到任何一个
nub --no-env-file --env-file=.env.ci server.ts它在每个接口上都优先于 --env-file 和 --env-file-if-exists——文件运行、nub run、nubx 和 nub watch(其中不向监听的 Node 传递 .env* 文件)。对于同时禁用 Nub 其余增强的持久、全树退出,改用 --node 或 NODE_COMPAT=1。