env 文件的使用注意和 Node.js 原生支持情况

512 阅读4分钟

image.png

.env 文件是一种简单而高效的方式,用于管理项目中的环境变量。通过 dotenv 库加载 .env 文件,可以在开发环境中方便地使用环境变量,同时通过 .gitignore 确保敏感信息的安全性。生产环境中建议直接使用系统环境变量以提高安全性和灵活性。

🤷‍♂️ 什么是配置,为什么要和代码分开存储

何谓配置:随部署环境(开发/测试/预发布staging/发布)变化的任何资源

  • 连接数据库、Memcached和 其他后端服务的任何资源
  • 访问外部服务(如 Amazon S3 或 OpenAI)的凭证
  • 每份部署特有的配置,如域名等

配置不能当做代码常量!须严格和代码隔离

有时,应用会将配置作为代码中的常量存储。这是违反十二要素应用原则的,十二要素要求严格分离配置与代码。配置在不同部署之间变化很大,而代码则不会。

判断应用是否已正确将所有配置从代码中分离出来的试金石是:代码库是否可以在任何时刻开源,而不会泄露任何凭证

需要注意的是,“配置”的定义不包括内部应用配置,如内部代码模块之间的连接方式。这种类型的配置在不同部署之间不会变化,因此最好在代码中完成。

—— The Twelve-Factor App

🔍 设置和读取 env 文件

Node.js 为例。在项目的根目录下创建一个名为 .env 的文件。使用 dotenv 库加载 .env 文件中的环境变量。

.env

NUXT_OPENAI_API_KEY=xxxxxxx
KV_URL=XXXXXXXX
KV_REST_API_URL=XXXXXXXX
KV_REST_API_TOKEN=XXXXXXXX
KV_REST_API_READ_ONLY_TOKEN=XXXXXXXX

读取

require('dotenv').config();

console.log(process.env) // 测试后删除

这样 .env 文件中的变量会被加载到 process.env 对象中。

🔒 保护敏感信息

一般我们会将敏感信息存储在 env 文件内,如何保证不泄露?

原则:切勿在非开发环境中使用 .env 文件。

1 将 .env 文件添加到 .gitignore 中,避免其被提交到版本控制系统:

env 文件被添加到 .gitignore 文件,那代码运行时候比如生产环境下不就拿不到 env 内的配置了吗?

2 在生产环境中,通常不会直接使用 .env 文件。

应该使用系统环境变量或如果使用 CI/CD 工具(如 GitLab CI、Jenkins 等),可以在这些工具的配置中设置环境变量。 这些变量会在部署时自动注入到应用程序中,而无需依赖 .env 文件,详见使用原生平台变量存储

foo=bar npm run build

dotenv 该库保证环境变量优先于 .env 配置,故即使生产环境没有 env 文件,部署后也无需修改代码。

// 该代码无需变化仍然能读取到生产环境的环境变量
require('dotenv').config(); 

3. 为了让开发者可以知道如何配置 env,一般都会存在一份 .env.example

为了兼顾安全和开发体验,一般我们会将一份脱敏的 env 文件放到 git 仓库。

image.png

—— .env.example @github.com next.js create-next-app

开发者将其重命名为 .env 即可使用。

4. env.vault 更安全的 env 文件

这个方案已经被很多语言支持,比如 Python、Rust 以及 Node.js 本身详见 What is a .env.vault file ,此处不表。

🧪 Node.js 原生支持 env 文件,但现仍不是 dotenv 卸甲归田之时

Node.js(2025-3-3)env 开发进展:

  • v20.6.0 实验性支持
  • v20.12.0 值支持多行
  • v23.9.0(最新版本)积极开发中

Node.js@v20.6.0 开始原生支持 env 文件,甚至可指定多个文件:node --env-file=.env --env-file=.development.env app.js,合并策略同对象解构。和 dotenv 同理,环境变量优先于 env 文件。其次默认加载不存在的文件会报错,但可通过 --env-file-if-exists flag 抑制。

相较 dotenv 这个下载量巨大的社区包,Node.js 暂不支持

image.png 来自社区的声音

这些特性也许会是 Node.js 官方未来的 roadmap。

📚 更多阅读