Node.js:本地小脚本读环境变量,可以先用 `process.env`

25 次浏览4 条回复

有些一次性脚本只是想从环境变量里拿个开关或路径,不一定要先接配置库。Node 自带的 process.env 就能处理很轻的场景。

环境:Node.js 18+。保存成 env-demo.mjs

const name = process.env.APP_NAME ?? 'mesh'
const debug = process.env.DEBUG === '1'
const port = Number(process.env.PORT ?? '3000')

console.log({ name, debug, port })

if (!Number.isInteger(port)) {
  throw new Error('PORT 需要是整数')
}

跑一下:

APP_NAME=dev DEBUG=1 PORT=8080 node env-demo.mjs

这种写法适合本地工具、CI 里的小步骤。变量一多,或者要做更严格的校验和默认值说明,就别一直散着读了,单独收口成一个 config 模块会清楚很多。

这个例子里 Number(process.env.PORT ?? '3000') 挺实用,不过有个小坑:空字符串会变成 0。如果是从 .env 或 CI 里传进来的,可能更想先判断一下:

const rawPort = process.env.PORT
const port = rawPort === undefined || rawPort === '' ? 3000 : Number(rawPort)

if (!Number.isInteger(port) || port <= 0) {
  throw new Error('PORT 需要是正整数')
}

小脚本里多这一点校验,出错时会更像“配置错了”,不至于后面才摸到奇怪问题。

还可以顺手把读取环境变量的地方集中成一个小函数,至少别在业务代码里到处散着写 process.env.X

比如布尔值我一般会显式约定只认 1true,不然 Boolean(process.env.DEBUG) 遇到 DEBUG=0 也会是 true,这个坑挺隐蔽的。

还有个小细节:process.env 读出来永远是字符串或 undefined,所以像数组、JSON 这种配置最好别偷懒直接塞进去用。

真要传复杂点的值,可以单独 JSON.parse,但建议包一层错误提示:

function readJson(name, fallback) {
  const raw = process.env[name]
  if (!raw) return fallback

  try {
    return JSON.parse(raw)
  } catch {
    throw new Error(`${name} 不是合法 JSON`)
  }
}

const flags = readJson('FEATURE_FLAGS', {})

小脚本里这样就够了,项目变大再换 zod / envalid 之类的校验库也不迟。

补个容易忽略的点:环境变量名尽量固定成大写加下划线,比如 APP_PORTFEATURE_FLAGS

在 Windows 上环境变量名基本不区分大小写,Linux/macOS 又区分,混着写 portPORT 这种,脚本换个环境跑就容易懵。小工具里也可以先把允许的名字列清楚,读不到就直接报错,省得默默走默认值。