npm package: @lingxiteam/env
Description: Executes a command using the environment variables in an env file
Latest version: 1.0.2

# @lingxiteam/env

一个简单的 Node 工具，用于从 env 文件加载环境变量并执行命令。
基于 [env-cmd](https://github.com/toddbluhm/env-cmd)

## 💾 安装

`npm install @lingxiteam/env` 或 `npm install -g @lingxiteam/env`

## ⌨️ 基本用法

**环境文件 `./.env`**

```text
# 这是注释
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH
```

**Package.json**

```json
{
  "scripts": {
    "test": "lingxi-env -- mocha -R spec"
  }
}
```

**终端命令**

```sh
./node_modules/.bin/lingxi-env -- node index.js
```

### 使用自定义 env 文件路径

如需指定自定义 env 文件名或路径，使用 `-f` 参数。

**终端命令**

```sh
./node_modules/.bin/lingxi-env -f ./custom/path/.env -- node index.js
```

## 📜 帮助

```text
用法: lingxi-env [选项] -- <命令> [...参数]

选项:
  -v, --version                       输出版本号
  -e, --environments [env1,env2,...]  指定 .rc 文件中的环境（可多个）
  -f, --file [path]                   自定义 env 文件路径（默认：./.env）
  --fallback                          如果自定义 env 文件不存在，则回退到默认路径
  --no-override                       不覆盖已存在的环境变量
  -r, --rc-file [path]                自定义 rc 文件路径（默认：./.env-cmdrc 或 .js/.json）
  -d, --dynamic-rc-file [path]        自定义动态环境 rc 文件路径（默认：./.env-dynamicrc 或 .js/.json），目前只支持node版本判断
  --node-compatible                   node 版本兼容，在node18以上版本环境默认开启--openssl-legacy-provider
  --silent                            忽略 lingxi-env 错误，仅在被执行程序失败时报错
  --use-shell                         在新 shell 中执行命令并加载环境变量
  --verbose                           输出调试信息
  -x, --expand-envs                   在命令和参数中用环境变量替换 $var
  -h, --help                          输出帮助信息
```

## 🔬 高级用法

### `.rc` 文件用法

对于复杂项目，可以在根目录定义 `.env-cmdrc` 文件，支持多个环境。使用 `-e` 参数指定要使用的环境，多个环境会合并变量，后者覆盖前者。

**.rc 文件 `./.env-cmdrc`**

```json
{
  "development": {
    "ENV1": "Thanks",
    "ENV2": "For All"
  },
  "test": {
    "ENV1": "No Thanks",
    "ENV3": "!"
  },
  "production": {
    "ENV1": "The Fish"
  }
}
```

**终端命令**

```sh
./node_modules/.bin/lingxi-env -e production -- node index.js
# 多环境合并（production 覆盖 test）
./node_modules/.bin/lingxi-env -e test,production -- node index.js
```

### `--no-override` 选项

防止 .env 文件中的变量覆盖已存在的环境变量。

### `--fallback` 文件用法

如果自定义路径下的 .env 文件不存在，则使用默认的 `./.env` 文件。

### `--use-shell`

在新的 shell 环境中执行命令，适合需要共享环境变量的多命令串联。

**终端命令**

```sh
./node_modules/.bin/lingxi-env -f ./test/.env --use-shell -- "npm run lint && npm test"
```

### 异步 env 文件支持

EnvCmd 支持异步读取 `.env` 文件。可以传入导出对象或 Promise 的 `.js` 文件。

**终端命令**

```sh
./node_modules/.bin/lingxi-env -f ./async-file.js -- node index.js
```

### `-x` 参数：参数变量展开

支持在命令参数中用 `$var` 动态替换环境变量。注意：需用 `\` 或 `\$` 转义，防止 shell 预先展开。

**终端命令**

```sh
# $VAR 会在运行时被替换为环境变量值
./node_modules/.bin/lingxi-env -x -- node index.js --arg=\$VAR
```

或在 `package.json` 中（需用 `\\` 插入反斜杠）：

```json
{
  "script": {
    "start": "lingxi-env -x -- node index.js --arg=\\$VAR"
  }
}
```

### `--silent` 静默模式

加上 `--silent` 参数后，lingxi-env 的错误会被忽略，仅保留子进程和 CLI 信号的错误。适合 .env 文件可能不存在但仍需执行命令的场景。

### `--node-compatible` 参数：开启node版本兼容

在本地开发时，有时候需要运行多个工程，不同工程对node版本要求不一致，在高版本node运行时，有时候需要开启兼容性支持选项,如 `--openssl-legacy-provider`

```sh
./node_modules/.bin/lingxi-env --node-compatible node -p 'process.env'
```

### `-d` 参数：设置动态环境 rc 文件路径

与 `--node-compatible` 功能相近，可以自定义添加兼容性选项

**.rc 文件 `./.env-dynamicrc`**

```json
{
  "node >= 18.0": {
    "NODE_OPTIONS": "--openssl-legacy-provider"
  }
}
```

## 💿 示例

TODO

## 💽️ 环境文件格式

目前支持以下环境文件格式，如需其他格式请提交 issue：

- `.env` 以 `key=value` 形式
- `.env.json` 以 JSON 键值对形式
- `.env.js` 导出对象或 Promise 的 JS 文件
- `.env-cmdrc` 或 `.env-cmdrc.json`，JSON 格式，包含至少一个环境
- `.env-cmdrc.js` 导出对象或 Promise 的 JS 文件，顶层为环境名

## 🗂 路径规则

本库遵循标准 bash 路径规则。示例：

Home 目录 = `/Users/test`
工作目录 = `/Users/test/Development/app`

| 类型 | 输入路径 | 展开后路径 |
| -- | -- | ------------- |
| 绝对路径 | `/some/absolute/path.env` | `/some/absolute/path.env` |
| Home 目录 ~ | `~/starts/on/homedir/path.env` | `/Users/test/starts/on/homedir/path.env` |
| 相对路径 | `./some/relative/path.env` 或 `some/relative/path.env` | `/Users/test/Development/app/some/relative/path.env` |
| 上级目录 | `../some/relative/path.env` | `/Users/test/Development/some/relative/path.env` |

## 🛠 API 用法

### `EnvCmd`

在新子进程中用指定环境变量执行命令

- **`options`** { `object` }
  - **`command`** { `string` }: 要执行的命令（如 `node`, `mocha` 等）
  - **`commandArgs`** { `string[]` }: 命令参数（如 `['-R', 'Spec']`）
  - **`envFile`** { `object` }
    - **`filePath`** { `string` }: .env 文件路径（默认：`./.env`）
    - **`fallback`** { `boolean` }: 自定义路径不存在时是否回退到默认
  - **`rc`** { `object` }
    - **`environments`** { `string[]` }: .rc 文件中要读取的环境名
    - **`filePath`** { `string` }: .rc 文件路径（默认：`./.env-cmdrc` 或 .js/.json）
  - **`dynamicrc`** { `object` }
    - **`filePath`** { `string` }: .rc 文件路径（默认：`./.env-dynamicrc` 或 .js/.json）
  - **`options`** { `object` }
    - **`expandEnvs`** { `boolean` }: 是否展开命令参数中的 `$var`（默认：`false`）
    - **`noOverride`** { `boolean` }: 是否禁止覆盖已存在的环境变量（默认：`false`）
    - **`silent`** { `boolean` }: 是否忽略 lingxi-env 错误（默认：`false`）
    - **`useShell`** { `boolean` }: 是否在新 shell 中运行命令（默认：`false`）
    - **`nodeCompatible`** { `boolean` }: 是开启node版本兼容性选项（默认：`false`）
    - **`verbose`** { `boolean` }: 是否输出调试日志（默认：`false`）
  - **返回** { `Promise<object>` }: 返回环境变量对象

### `GetEnvVars`

从 .env 或 .rc 文件解析环境变量

- **`options`** { `object` }
  - **`envFile`** { `object` }
    - **`filePath`** { `string` }: .env 文件路径（默认：`./.env`）
    - **`fallback`** { `boolean` }: 自定义路径不存在时是否回退到默认
  - **`rc`** { `object` }
    - **`environments`** { `string[]` }: .rc 文件中要读取的环境名
    - **`filePath`** { `string` }: .rc 文件路径（默认：`./.env-cmdrc` 或 .js/.json）
  - **`verbose`** { `boolean` }: 是否输出调试日志（默认：`false`）
- **返回** { `Promise<object>` }: 返回环境变量对象

## 🧙 为什么要用

有时候给脚本传递大量环境变量很麻烦，使用文件集中管理更方便，尤其适合开发和测试。

🚨**请勿将敏感环境数据提交到公共 git 仓库！**🚨

## 🧬 相关项目

[`cross-env`](https://github.com/kentcdodds/cross-env) - 跨平台设置环境变量的脚本工具