Node.js 读取环境变量有哪几种方法:3 种写法一次讲清

编程狮(w3cschool.cn) 2026-10-03 07:02:25 浏览数 (17)
反馈

Node.js 读取环境变量有几种?

读 Node.js 环境变量最稳的做法就一句:线上直接读 process.env,本地开发用 dotenv 加载 .env,跨平台脚本交给 cross-env 注入。你在本地能跑通、上线却读不到配置,十有八九是变量没读对——明明代码没改,换台机器就报 undefined,问题多半出在变量从哪来、又该怎么读。本文基于 Node.js 18 LTS 验证,把这三种做法从最小示例讲到边界,并附横向对比与踩坑清单,帮你一次把读取姿势搞对。今天这篇文章,编程狮就把这块讲透。

先看结论

场景 推荐做法 说明
读系统或容器注入的变量 直接 process.env 零依赖,运行时即用
本地开发区分多套配置 dotenv 加载 .env 配置不进代码,方便切换
一条命令跨 Windows/macOS 注入 cross-env 避免平台命令差异报错

一句话:线上用原生的 process.env,开发用 dotenv,脚本用 cross-env,三者不冲突。

一、最基础:直接用 process.env 读运行时变量

process.env 是 Node.js 启动时从操作系统继承来的环境变量对象,任何字符串键都能直接读取,常用键名记不住时可翻 Node.js 速查手册。它不需要安装任何包,服务部署到容器或云函数后,运维注入的变量都会自动出现在这里,无需你在代码里再注册一遍。读取前最好先用 typeof 确认值的类型,避免把 undefined 误当成空字符串继续往下走。

// 读取名为 API_KEY 的环境变量,注意它永远是字符串或 undefined
const apiKey = process.env.API_KEY;
if (!apiKey) {
  console.error("缺少环境变量 API_KEY");  // 检查:缺失时立刻报错而不是静默继续
  process.exit(1);
}
console.log("已读取到 API_KEY,长度:", apiKey.length);

上面这段先做检查:如果 process.env.API_KEY 为空就报错退出,避免后面逻辑拿到 undefined。预期结果是缺失时打印提示并退出;正常配置后打印密钥长度。实际输出取决于你的环境,未在本机执行,请以你方环境实测为准。

1.1 值是字符串,记得转换类型

环境变量在网络协议里永远是字符串,process.env.PORT 拿到的是 "3000" 而不是数字 3000。用到端口、超时、开关时,要用 Number() 或 === "true" 显式转换,否则 if (process.env.DEBUG) 这类判断会被非空字符串误判为真。

1.2 给缺失的变量一个兜底默认值

上线环境有时某个变量没配齐,与其让程序在中间崩掉,不如读到 undefined 时给一个安全的默认值。超时时间可以这么写:const timeout = Number(process.env.TIMEOUT) || 3000;。这里用 ||,当值为空字符串或 0 时都会回退到 3000;若业务里 0 是合法值,就要改用 ?? 做空值判断。验证默认值是否生效,可以先临时 unset 掉变量再启动一次,确认程序没有因为缺配置而直接崩溃。

process.env 读取流程与类型转换示意图

二、开发常用:用 dotenv 加载 .env 文件

本地开发不想把密钥写死在代码里,就把它放进项目根目录的 .env,再用 dotenv 在入口处加载。dotenv 会把 .env 里的 KEY=VALUE 逐行写进 process.env,之后读取方式和原生完全一致。

// 在应用最入口处加载 .env,务必放在读取环境变量之前
require("dotenv").config();
const dbUrl = process.env.DATABASE_URL;  // 现在能读到 .env 里的值
console.log("数据库地址已就绪:", Boolean(dbUrl));

这段先配置再读取,顺序是重点。预期结果是控制台打印数据库地址是否已就绪;若 .env 不存在,dotenv 不会报错,只是变量依旧为空,需要你自行检查文件位置。.env 必须加进 .gitignore,否则密钥会随代码一起提交,造成泄露。

⚠️ 注意:.env 只用于本地与测试,生产环境应由部署平台注入真实变量,不要把同一份文件推到线上。

三、跨平台:用 cross-env 在命令里注入

在 package.json 里写 NODE_ENV=production node app.js,在 macOS 和 Linux 上能跑,到了 Windows 的命令提示符就会因为语法不同报错。cross-env 把赋值语法统一掉,一条脚本三端通用。

{
  "scripts": {
    "start:dev": "cross-env NODE_ENV=development PORT=3000 node app.js",
    "start:prod": "cross-env NODE_ENV=production PORT=8080 node app.js"
  }
}

这段给 npm run start:dev 注入了 NODE_ENV 和 PORT 两个变量。运行后应用会按对应环境启动;如果没装 cross-env,命令在 Windows 上会直接失败,需要先安装依赖再重试。npm 脚本的更多写法可参考 npm 教程。

💡 小提示:cross-env 只解决“命令注入”这一步,真正读取仍然走 process.env,两者是互补关系,不是替代。

四、横向对比与踩坑清单

三种做法的取舍很清晰:原生 process.env 零依赖但只认已存在变量;dotenv 解决“本地文件配置”却依赖加载顺序;cross-env 只管命令注入、不碰文件。

做法 适用场景 优点 代价
process.env 线上/容器注入 零依赖、最快 变量必须已存在
dotenv 本地多套配置 配置不进代码 需最早加载、易被误提交
cross-env 跨平台 npm 脚本 一条脚本三端通用 仅命令注入,仍需 process.env 读取

三种读取环境变量方式的选择决策图

常见失败有三个,对应修复也很直接:第一,dotenv 在读取之后才 config(),导致变量为空,修复是把 require("dotenv").config() 提到所有 process.env 读取之前;第二,把 .env 提交进仓库引发密钥泄露,修复是立刻加 .gitignore 并从提交历史里清理敏感文件;第三,误以为 process.env 返回数字,端口拼接时出现 3000undefined 这类拼接错误,修复是统一用 Number() 转换。排错时先打印一次 process.env 里相关键名,确认值真的进来了,再去看下游逻辑,往往能省掉大半排查时间。

总结

Node.js 读取环境变量最稳的是原生 process.env:线上直接读、开发用 dotenv 加载 .env、跨平台脚本用 cross-env 注入,三者按场景组合即可。要点带走:

  • process.env 永远是字符串,用前先检查再转换类型;
  • dotenv 必须在读取变量之前 config(),且 .env 要进 .gitignore;
  • 跨平台脚本靠 cross-env 统一注入语法,读取仍走 process.env。

把 Node.js 读取环境变量这套读法练熟,配置类问题会少踩很多坑。

下一步想补 Node.js 基础,可以先过一遍 Node.js 教程打底。

延伸学习

想把这块知识系统补齐,可以按这个顺序来:

  1. 先过一遍 Node.js 教程,把模块与运行时基础铺平;
  2. 想看更多实战写法,Node.js 指南 覆盖了不少工程细节;
  3. 之前那篇 Node 实战笔记 从另一个角度讲了落地经验,适合延伸阅读。

常见问题

Q:为什么我设了环境变量,代码里却读到 undefined?

A:最常见是 dotenv 在读取之后才加载,或变量名拼错。先检查 config() 是否在所有读取之前,再核对大小写与键名是否完全一致。

Q:.env 文件能直接提交到 Git 吗?

A:不能。里面往往放密钥,必须写进 .gitignore,只在本地保留,线上由部署平台注入真实值。

Q:process.env 读到的是数字还是字符串?

A:永远是字符串。端口、开关等用到数值时要手动 Number() 或字符串比较转换,否则会出拼接或判断错误。

0 人点赞