@zqw-cli/qenv 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +867 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1487 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,867 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">qenv</h1>
|
|
3
|
+
<p align="center">
|
|
4
|
+
跨平台环境变量管理 CLI 工具<br/>
|
|
5
|
+
<strong>一套命令,三端一致 — Windows · macOS · Linux</strong>
|
|
6
|
+
</p>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@zqw-cli/qenv"><img src="https://img.shields.io/npm/v/@zqw-cli/qenv.svg?style=flat-square" alt="npm version" /></a>
|
|
9
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@zqw-cli/qenv.svg?style=flat-square" alt="node version" /></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" alt="license" /></a>
|
|
11
|
+
</p>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 为什么选 qenv?
|
|
17
|
+
|
|
18
|
+
在不同操作系统上管理环境变量是件令人头疼的事:Windows 用 `setx`,macOS/Linux 要编辑 `.bashrc` 或 `.zshrc`,项目里还有 `.env` 文件需要维护……
|
|
19
|
+
|
|
20
|
+
**qenv 将这一切统一为一行命令。**
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 不管你在什么平台,设置环境变量永远是这一行
|
|
24
|
+
qenv set NODE_ENV production
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 核心亮点
|
|
28
|
+
|
|
29
|
+
| 特性 | 说明 |
|
|
30
|
+
|------|------|
|
|
31
|
+
| 🌍 **跨平台统一** | 同一命令在 Windows / macOS / Linux 上行为一致 |
|
|
32
|
+
| 📋 **Manifest 追踪** | 记录每一个由 qenv 管理过的变量,支持 `list`、`diff`、`clean` |
|
|
33
|
+
| 🐚 **Shell 集成** | 通过 `qenv init` 安装 wrapper,支持 `--local` 在当前终端立即生效 |
|
|
34
|
+
| 📁 **`.env` 文件支持** | 用 `--file` 读写项目级 `.env` 文件,无需额外工具 |
|
|
35
|
+
| 📦 **批量导入导出** | `qenv import` / `qenv export` 快速迁移环境配置 |
|
|
36
|
+
| 🎨 **友好的终端输出** | 彩色图标、表格对齐、敏感值自动脱敏 |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 目录
|
|
41
|
+
|
|
42
|
+
- [安装](#安装)
|
|
43
|
+
- [快速上手](#快速上手)
|
|
44
|
+
- [命令参考](#命令参考)
|
|
45
|
+
- [qenv set](#qenv-set)
|
|
46
|
+
- [qenv get](#qenv-get)
|
|
47
|
+
- [qenv remove](#qenv-remove)
|
|
48
|
+
- [qenv list](#qenv-list)
|
|
49
|
+
- [qenv import](#qenv-import)
|
|
50
|
+
- [qenv export](#qenv-export)
|
|
51
|
+
- [qenv diff](#qenv-diff)
|
|
52
|
+
- [qenv clean](#qenv-clean)
|
|
53
|
+
- [qenv init](#qenv-init)
|
|
54
|
+
- [全局选项](#全局选项)
|
|
55
|
+
- [Shell 集成详解](#shell-集成详解)
|
|
56
|
+
- [工作原理](#工作原理)
|
|
57
|
+
- [平台驱动层](#平台驱动层)
|
|
58
|
+
- [Manifest 机制](#manifest-机制)
|
|
59
|
+
- [Scope 说明](#scope-说明)
|
|
60
|
+
- [常见用法示例](#常见用法示例)
|
|
61
|
+
- [注意事项与限制](#注意事项与限制)
|
|
62
|
+
- [开发指南](#开发指南)
|
|
63
|
+
- [项目结构](#项目结构)
|
|
64
|
+
- [License](#license)
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 安装
|
|
69
|
+
|
|
70
|
+
**要求:** Node.js >= 16
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install -g @zqw-cli/qenv
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
安装后即可在任意终端中使用 `qenv` 命令:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
qenv --version
|
|
80
|
+
# 1.0.0
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 快速上手
|
|
86
|
+
|
|
87
|
+
### 1. 设置环境变量
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# 设置用户级系统环境变量(永久生效,重启终端后可用)
|
|
91
|
+
qenv set NODE_ENV production
|
|
92
|
+
|
|
93
|
+
# 设置后覆盖已有的变量
|
|
94
|
+
qenv set NODE_ENV development --overwrite
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 2. 读取环境变量
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
qenv get NODE_ENV
|
|
101
|
+
# NODE_ENV=production
|
|
102
|
+
|
|
103
|
+
# 只输出纯值(适合在脚本中使用)
|
|
104
|
+
qenv get NODE_ENV --raw
|
|
105
|
+
# production
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 3. 使用 .env 文件
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# 写入项目 .env 文件
|
|
112
|
+
qenv set DATABASE_URL postgres://localhost/mydb --file
|
|
113
|
+
|
|
114
|
+
# 写入指定的 .env 文件
|
|
115
|
+
qenv set API_KEY sk-xxx --file .env.local
|
|
116
|
+
|
|
117
|
+
# 查看 .env 文件中的所有变量
|
|
118
|
+
qenv list --file .env.local
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 4. 批量操作
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 从 .env 文件批量导入到系统变量
|
|
125
|
+
qenv import .env.prod
|
|
126
|
+
|
|
127
|
+
# 先预览再导入
|
|
128
|
+
qenv import .env.prod --dry-run
|
|
129
|
+
|
|
130
|
+
# 导出所有 qenv 管理的变量到文件
|
|
131
|
+
qenv export .env.backup
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 5. 查看与维护
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# 列出所有由 qenv 管理的变量
|
|
138
|
+
qenv list
|
|
139
|
+
|
|
140
|
+
# 对比 manifest 记录与系统实际值
|
|
141
|
+
qenv diff
|
|
142
|
+
|
|
143
|
+
# 清理已失效的记录
|
|
144
|
+
qenv clean
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 命令参考
|
|
150
|
+
|
|
151
|
+
> 💡 每个命令都支持 `--help` 查看详细用法,例如 `qenv set --help`。
|
|
152
|
+
|
|
153
|
+
### qenv set
|
|
154
|
+
|
|
155
|
+
设置环境变量。
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
用法: qenv set <name> <value> [options]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
| 选项 | 说明 |
|
|
162
|
+
|------|------|
|
|
163
|
+
| `--local` | 仅在当前 Shell 会话中生效(需先运行 `qenv init`) |
|
|
164
|
+
| `--system` | 设置系统级变量(需管理员/sudo 权限) |
|
|
165
|
+
| `--file [path]` | 写入 `.env` 文件,默认路径为 `./.env` |
|
|
166
|
+
| `--json` | 将 value 作为 JSON 解析并校验 |
|
|
167
|
+
| `--overwrite` | 如果变量已存在,强制覆盖 |
|
|
168
|
+
|
|
169
|
+
**示例:**
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# 基础用法:设置用户级系统变量(永久)
|
|
173
|
+
qenv set NODE_ENV production
|
|
174
|
+
|
|
175
|
+
# 仅当前终端会话生效(需 qenv init)
|
|
176
|
+
qenv set API_KEY sk-xxx --local
|
|
177
|
+
|
|
178
|
+
# 写入项目 .env 文件
|
|
179
|
+
qenv set PORT 3000 --file
|
|
180
|
+
|
|
181
|
+
# 写入指定 .env 文件
|
|
182
|
+
qenv set PORT 3000 --file .env.local
|
|
183
|
+
|
|
184
|
+
# JSON 值校验
|
|
185
|
+
qenv set CONFIG '{"debug":true}' --json
|
|
186
|
+
|
|
187
|
+
# 覆盖已有变量
|
|
188
|
+
qenv set NODE_ENV development --overwrite
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**行为说明:**
|
|
192
|
+
- 默认会检查变量是否已存在,若已存在则提示使用 `--overwrite`
|
|
193
|
+
- 不带 `--file` 或 `--local` 时,变量写入当前用户的系统环境(永久生效)
|
|
194
|
+
- 写入的变量会自动记录到 manifest 中,可通过 `qenv list` 查看
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### qenv get
|
|
199
|
+
|
|
200
|
+
获取环境变量的值。
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
用法: qenv get <name> [options]
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
| 选项 | 说明 |
|
|
207
|
+
|------|------|
|
|
208
|
+
| `--source` | 显示变量来源(qenv 管理 / 系统原有 / 文件) |
|
|
209
|
+
| `--file [path]` | 从 `.env` 文件读取,默认路径为 `./.env` |
|
|
210
|
+
| `--json` | 以 JSON 格式输出 `{ name, value, source }` |
|
|
211
|
+
| `--raw` | 仅输出纯值,不带任何前缀(适合 `$()` 嵌入脚本使用) |
|
|
212
|
+
|
|
213
|
+
**示例:**
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# 读取系统变量
|
|
217
|
+
qenv get NODE_ENV
|
|
218
|
+
# NODE_ENV=production
|
|
219
|
+
|
|
220
|
+
# 查看变量来源
|
|
221
|
+
qenv get NODE_ENV --source
|
|
222
|
+
# NODE_ENV=production
|
|
223
|
+
# ℹ Source: qenv (system)
|
|
224
|
+
|
|
225
|
+
# 从 .env 文件读取
|
|
226
|
+
qenv get DATABASE_URL --file .env.prod
|
|
227
|
+
|
|
228
|
+
# 纯值输出(适合脚本嵌入)
|
|
229
|
+
echo "当前环境: $(qenv get NODE_ENV --raw)"
|
|
230
|
+
|
|
231
|
+
# JSON 格式
|
|
232
|
+
qenv get PORT --json
|
|
233
|
+
# {"name":"PORT","value":"3000","source":"qenv (system)"}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**行为说明:**
|
|
237
|
+
- `--raw` 模式下,如果变量不存在,进程退出码为 `1`,stdout 无输出
|
|
238
|
+
- 不加 `--raw` 时,变量不存在会输出 `⚠ Variable "XXX" not found`
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### qenv remove
|
|
243
|
+
|
|
244
|
+
删除环境变量。别名:`qenv rm`。
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
用法: qenv remove <name> [options]
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
| 选项 | 说明 |
|
|
251
|
+
|------|------|
|
|
252
|
+
| `--system` | 删除系统级变量(需管理员/sudo 权限) |
|
|
253
|
+
| `--local` | 从当前 Shell 会话中移除(需 `qenv init`) |
|
|
254
|
+
| `--file [path]` | 从 `.env` 文件中删除 |
|
|
255
|
+
| `--force` | 跳过确认提示,直接删除 |
|
|
256
|
+
| `--all` | 配合 `--file` 使用,清空文件中所有变量 |
|
|
257
|
+
|
|
258
|
+
**示例:**
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# 删除用户级系统变量(会有确认提示)
|
|
262
|
+
qenv remove NODE_ENV
|
|
263
|
+
|
|
264
|
+
# 跳过确认直接删除
|
|
265
|
+
qenv remove NODE_ENV --force
|
|
266
|
+
|
|
267
|
+
# 从 .env 文件删除
|
|
268
|
+
qenv remove DATABASE_URL --file .env.prod
|
|
269
|
+
|
|
270
|
+
# 清空 .env 文件中所有变量
|
|
271
|
+
qenv remove --all --file
|
|
272
|
+
|
|
273
|
+
# 从当前会话移除(需 qenv init)
|
|
274
|
+
qenv remove API_KEY --local
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**行为说明:**
|
|
278
|
+
- 默认删除前会弹出确认提示 `(y/N)`,使用 `--force` 跳过
|
|
279
|
+
- 删除成功后同时从 manifest 中清除记录
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### qenv list
|
|
284
|
+
|
|
285
|
+
列出环境变量。别名:`qenv ls`。
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
用法: qenv list [options]
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
| 选项 | 说明 |
|
|
292
|
+
|------|------|
|
|
293
|
+
| `--all` | 列出系统中所有环境变量(等同 `printenv`) |
|
|
294
|
+
| `--file [path]` | 列出 `.env` 文件中的变量 |
|
|
295
|
+
| `--json` | 以 JSON 格式输出 |
|
|
296
|
+
| `--verify` | 检验 manifest 记录与系统实际值是否一致 |
|
|
297
|
+
| `--stale` | 仅显示已失效的 manifest 记录 |
|
|
298
|
+
|
|
299
|
+
**示例:**
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# 列出 qenv 管理的变量(默认)
|
|
303
|
+
qenv list
|
|
304
|
+
|
|
305
|
+
# 输出示例:
|
|
306
|
+
# NAME VALUE SCOPE UPDATED
|
|
307
|
+
# ─────────────────────────────────────────────────────
|
|
308
|
+
# NODE_ENV pro***ion system 2 days ago
|
|
309
|
+
# API_KEY sk-***xxx system 1 hour ago
|
|
310
|
+
# DATABASE_URL (not found) ⚠ system 5 days ago
|
|
311
|
+
#
|
|
312
|
+
# ⚠ 1 stale entry found. Run `qenv clean` to remove.
|
|
313
|
+
|
|
314
|
+
# 列出所有系统变量
|
|
315
|
+
qenv list --all
|
|
316
|
+
|
|
317
|
+
# 列出 .env 文件变量
|
|
318
|
+
qenv list --file .env.prod
|
|
319
|
+
|
|
320
|
+
# 仅查看失效记录
|
|
321
|
+
qenv list --stale
|
|
322
|
+
|
|
323
|
+
# JSON 输出
|
|
324
|
+
qenv list --json
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**输出说明:**
|
|
328
|
+
- `VALUE` 列会自动脱敏显示(保留前 3 位和后 3 位,中间用 `***` 替代)
|
|
329
|
+
- `UPDATED` 列显示上次更新的相对时间(如 `2 days ago`、`just now`)
|
|
330
|
+
- 系统中已不存在的变量会显示 `(not found) ⚠` 标记
|
|
331
|
+
- `--all` 模式展示完整值,不做脱敏处理
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
### qenv import
|
|
336
|
+
|
|
337
|
+
从 `.env` 文件批量导入环境变量。
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
用法: qenv import <file> [options]
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
| 选项 | 说明 |
|
|
344
|
+
|------|------|
|
|
345
|
+
| `--local` | 导入到当前 Shell 会话(需 `qenv init`) |
|
|
346
|
+
| `--dry-run` | 预览将要导入的变量,不实际执行 |
|
|
347
|
+
| `--overwrite` | 覆盖已存在的变量 |
|
|
348
|
+
|
|
349
|
+
**示例:**
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# 将 .env 文件中的变量导入为系统环境变量
|
|
353
|
+
qenv import .env
|
|
354
|
+
|
|
355
|
+
# 先预览,确认后再操作
|
|
356
|
+
qenv import .env.prod --dry-run
|
|
357
|
+
# ℹ Preview of import from .env.prod:
|
|
358
|
+
# + NODE_ENV=production
|
|
359
|
+
# + API_KEY=sk-xxx
|
|
360
|
+
# + PORT=3000
|
|
361
|
+
#
|
|
362
|
+
# Total: 3 variables
|
|
363
|
+
|
|
364
|
+
# 覆盖已存在的变量
|
|
365
|
+
qenv import .env --overwrite
|
|
366
|
+
|
|
367
|
+
# 导入到当前会话(需 qenv init)
|
|
368
|
+
qenv import .env.dev --local
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**行为说明:**
|
|
372
|
+
- 默认不覆盖已存在的变量,逐条跳过并提示
|
|
373
|
+
- `.env` 文件格式支持:`KEY=VALUE`、带引号 `KEY="VALUE"`、注释 `# ...`
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
### qenv export
|
|
378
|
+
|
|
379
|
+
将环境变量导出为 `.env` 格式。
|
|
380
|
+
|
|
381
|
+
```
|
|
382
|
+
用法: qenv export [file] [options]
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
| 选项 | 说明 |
|
|
386
|
+
|------|------|
|
|
387
|
+
| `--all` | 导出系统中所有环境变量 |
|
|
388
|
+
| `--filter <prefix>` | 仅导出匹配指定前缀的变量 |
|
|
389
|
+
|
|
390
|
+
**示例:**
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# 导出 qenv 管理的变量到 stdout
|
|
394
|
+
qenv export
|
|
395
|
+
|
|
396
|
+
# 导出到文件
|
|
397
|
+
qenv export .env.backup
|
|
398
|
+
|
|
399
|
+
# 导出所有系统变量
|
|
400
|
+
qenv export env-full.txt --all
|
|
401
|
+
|
|
402
|
+
# 仅导出特定前缀的变量
|
|
403
|
+
qenv export --filter REACT_APP_
|
|
404
|
+
qenv export .env.react --filter REACT_APP_
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**行为说明:**
|
|
408
|
+
- 不指定文件时输出到 stdout,可配合管道使用:`qenv export | grep NODE`
|
|
409
|
+
- 默认只导出 manifest 中跟踪的变量,`--all` 则导出系统全部
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
### qenv diff
|
|
414
|
+
|
|
415
|
+
对比 manifest 记录与系统中的实际值。
|
|
416
|
+
|
|
417
|
+
```
|
|
418
|
+
用法: qenv diff [options]
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
| 选项 | 说明 |
|
|
422
|
+
|------|------|
|
|
423
|
+
| `--json` | 以 JSON 格式输出对比结果 |
|
|
424
|
+
|
|
425
|
+
**示例:**
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
qenv diff
|
|
429
|
+
# 输出示例:
|
|
430
|
+
# NAME SCOPE STATUS
|
|
431
|
+
# ─────────────────────────────────────────
|
|
432
|
+
# NODE_ENV system ✔ in sync
|
|
433
|
+
# API_KEY system ✔ in sync
|
|
434
|
+
# OLD_VAR system ✖ missing
|
|
435
|
+
#
|
|
436
|
+
# ⚠ 1 variable missing from system. Run `qenv clean` to remove stale entries.
|
|
437
|
+
|
|
438
|
+
qenv diff --json
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**状态说明:**
|
|
442
|
+
|
|
443
|
+
| 状态 | 含义 |
|
|
444
|
+
|------|------|
|
|
445
|
+
| `✔ in sync` | manifest 记录的变量在系统中存在 |
|
|
446
|
+
| `✖ missing` | manifest 中记录了但系统中已不存在 |
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
### qenv clean
|
|
451
|
+
|
|
452
|
+
清理 manifest 中的失效记录。
|
|
453
|
+
|
|
454
|
+
```
|
|
455
|
+
用法: qenv clean [options]
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
| 选项 | 说明 |
|
|
459
|
+
|------|------|
|
|
460
|
+
| `--force` | 跳过确认提示,直接清理 |
|
|
461
|
+
|
|
462
|
+
**示例:**
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# 交互式清理(有确认提示)
|
|
466
|
+
qenv clean
|
|
467
|
+
# ℹ Found 2 stale entries:
|
|
468
|
+
# ⚠ OLD_VAR_1
|
|
469
|
+
# ⚠ OLD_VAR_2
|
|
470
|
+
#
|
|
471
|
+
# Remove these stale entries from manifest? (y/N)
|
|
472
|
+
|
|
473
|
+
# 跳过确认直接清理
|
|
474
|
+
qenv clean --force
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
### qenv init
|
|
480
|
+
|
|
481
|
+
安装 Shell 集成(wrapper function),以支持 `--local` 模式。
|
|
482
|
+
|
|
483
|
+
```
|
|
484
|
+
用法: qenv init [options]
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
| 选项 | 说明 |
|
|
488
|
+
|------|------|
|
|
489
|
+
| `--shell <type>` | 指定 Shell 类型:`bash` / `zsh` / `fish` / `pwsh` |
|
|
490
|
+
| `--print` | 仅打印 wrapper 代码,不自动安装 |
|
|
491
|
+
| `--uninstall` | 从配置文件中移除 wrapper |
|
|
492
|
+
|
|
493
|
+
**示例:**
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
# 自动检测当前 Shell 并安装
|
|
497
|
+
qenv init
|
|
498
|
+
|
|
499
|
+
# 指定 Shell 类型
|
|
500
|
+
qenv init --shell zsh
|
|
501
|
+
|
|
502
|
+
# 只查看代码,不安装
|
|
503
|
+
qenv init --print
|
|
504
|
+
|
|
505
|
+
# 卸载 Shell 集成
|
|
506
|
+
qenv init --uninstall
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
> 详见 [Shell 集成详解](#shell-集成详解)。
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## 全局选项
|
|
514
|
+
|
|
515
|
+
以下选项可与任意命令组合使用:
|
|
516
|
+
|
|
517
|
+
| 选项 | 说明 |
|
|
518
|
+
|------|------|
|
|
519
|
+
| `-V, --version` | 输出版本号 |
|
|
520
|
+
| `-h, --help` | 显示帮助信息 |
|
|
521
|
+
| `--no-color` | 禁用终端彩色输出 |
|
|
522
|
+
| `--silent` | 禁止所有 stdout 输出(仅保留 stderr 错误信息) |
|
|
523
|
+
| `--verbose` | 输出调试信息(驱动层调用详情) |
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
# 无色输出(适合重定向到文件)
|
|
527
|
+
qenv list --no-color > vars.txt
|
|
528
|
+
|
|
529
|
+
# 静默模式(CI 中使用)
|
|
530
|
+
qenv set CI true --silent
|
|
531
|
+
|
|
532
|
+
# 调试模式
|
|
533
|
+
qenv set NODE_ENV test --verbose
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
## Shell 集成详解
|
|
539
|
+
|
|
540
|
+
### 为什么需要 Shell 集成?
|
|
541
|
+
|
|
542
|
+
`qenv set NAME value` 默认将变量写入**系统环境**(永久但需重启终端),如果你希望变量在**当前终端窗口立即可用**,需要使用 `--local` 模式。
|
|
543
|
+
|
|
544
|
+
然而,一个子进程(qenv CLI)无法直接修改父进程(你的终端)的环境变量。为了解决这个限制,qenv 使用了 **shell wrapper + eval** 机制:
|
|
545
|
+
|
|
546
|
+
1. `qenv init` 在你的 Shell 配置文件中安装一个 wrapper function
|
|
547
|
+
2. 调用 `qenv set NAME value --local` 时,wrapper 实际执行的是 `qenv --shell-eval set NAME value --local`
|
|
548
|
+
3. qenv 在 `--shell-eval` 模式下只向 stdout 输出一行 shell 表达式(如 `export NAME="value"`)
|
|
549
|
+
4. wrapper 用 `eval` 执行这行表达式,从而修改当前 Shell 会话的环境
|
|
550
|
+
|
|
551
|
+
### 各 Shell 的 wrapper 代码
|
|
552
|
+
|
|
553
|
+
**Bash / Zsh**(写入 `~/.bashrc` 或 `~/.zshrc`):
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
# qenv shell integration
|
|
557
|
+
qenv() { eval "$(command qenv --shell-eval "$@")"; }
|
|
558
|
+
# end qenv
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Fish**(写入 `~/.config/fish/config.fish`):
|
|
562
|
+
|
|
563
|
+
```fish
|
|
564
|
+
# qenv shell integration
|
|
565
|
+
function qenv
|
|
566
|
+
eval (command qenv --shell-eval $argv)
|
|
567
|
+
end
|
|
568
|
+
# end qenv
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**PowerShell**(写入 `$PROFILE`):
|
|
572
|
+
|
|
573
|
+
```powershell
|
|
574
|
+
# qenv shell integration
|
|
575
|
+
function qenv { $result = & qenv.cmd --shell-eval @args; if ($result) { Invoke-Expression $result } }
|
|
576
|
+
# end qenv
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### 手动安装
|
|
580
|
+
|
|
581
|
+
如果不想自动修改配置文件,可以用 `--print` 查看代码后手动添加:
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
qenv init --print
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
## 工作原理
|
|
590
|
+
|
|
591
|
+
### 平台驱动层
|
|
592
|
+
|
|
593
|
+
qenv 根据 `process.platform` 自动选择合适的驱动:
|
|
594
|
+
|
|
595
|
+
| 平台 | 用户级操作 | 系统级操作 (`--system`) |
|
|
596
|
+
|------|-----------|----------------------|
|
|
597
|
+
| **Windows** | `setx NAME "value"`(写入 `HKCU\Environment`) | `reg add HKLM\...\Environment`(需管理员) |
|
|
598
|
+
| **macOS** | 追加 `export NAME="value" # qenv:managed` 到 `~/.zshrc` | 写入 `/etc/environment`(需 sudo) |
|
|
599
|
+
| **Linux** | 追加 `export NAME="value" # qenv:managed` 到 `~/.bashrc` | 写入 `/etc/environment`(需 sudo) |
|
|
600
|
+
| **.env 文件** | 直接读写指定的 `.env` 文件 | — |
|
|
601
|
+
|
|
602
|
+
**Unix 驱动细节:**
|
|
603
|
+
- 使用注释标记 `# qenv:managed` 管理 Shell 配置文件中的行
|
|
604
|
+
- 更新变量时通过正则精准替换已标记的行,不会产生重复条目
|
|
605
|
+
- 自动检测当前 Shell 类型,选择正确的配置文件
|
|
606
|
+
|
|
607
|
+
**Windows 驱动细节:**
|
|
608
|
+
- 用户级变量使用 `setx` 命令,系统级使用 `reg add` 操作注册表
|
|
609
|
+
- 设置变量后自动广播 `WM_SETTINGCHANGE` 消息,通知其他进程刷新环境
|
|
610
|
+
- 自动校验值长度,超过 `setx` 的 1024 字符限制时提前报错
|
|
611
|
+
|
|
612
|
+
### Manifest 机制
|
|
613
|
+
|
|
614
|
+
qenv 使用 [conf](https://github.com/sindresorhus/conf) 库将 manifest 持久化到用户配置目录:
|
|
615
|
+
|
|
616
|
+
| 平台 | 路径 |
|
|
617
|
+
|------|------|
|
|
618
|
+
| **macOS / Linux** | `~/.config/qenv/config.json` |
|
|
619
|
+
| **Windows** | `%APPDATA%\qenv\config.json` |
|
|
620
|
+
|
|
621
|
+
**数据结构示例:**
|
|
622
|
+
|
|
623
|
+
```json
|
|
624
|
+
{
|
|
625
|
+
"version": 1,
|
|
626
|
+
"vars": {
|
|
627
|
+
"NODE_ENV": {
|
|
628
|
+
"scope": "system",
|
|
629
|
+
"filePath": null,
|
|
630
|
+
"setAt": "2026-03-16T10:00:00Z",
|
|
631
|
+
"updatedAt": "2026-03-16T12:00:00Z",
|
|
632
|
+
"setBy": "qenv@1.0.0"
|
|
633
|
+
},
|
|
634
|
+
"DATABASE_URL": {
|
|
635
|
+
"scope": "file",
|
|
636
|
+
"filePath": "D:\\projects\\myapp\\.env",
|
|
637
|
+
"setAt": "2026-03-16T09:00:00Z",
|
|
638
|
+
"updatedAt": "2026-03-16T09:00:00Z",
|
|
639
|
+
"setBy": "qenv@1.0.0"
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
**字段说明:**
|
|
646
|
+
|
|
647
|
+
| 字段 | 说明 |
|
|
648
|
+
|------|------|
|
|
649
|
+
| `scope` | `system`(用户级永久)/ `system-wide`(系统级)/ `file`(.env 文件) |
|
|
650
|
+
| `filePath` | 仅 `scope=file` 时有值,记录 `.env` 文件的绝对路径 |
|
|
651
|
+
| `setAt` | 首次设置时间(ISO 8601 格式) |
|
|
652
|
+
| `updatedAt` | 最近一次更新时间 |
|
|
653
|
+
| `setBy` | 写入时的 qenv 版本号 |
|
|
654
|
+
|
|
655
|
+
> ⚠️ **重要边界:** manifest 仅记录"qenv 操作过哪些变量",不独占管理权。如果用户或其他工具直接修改了同一变量,qenv 不会阻止,但 `qenv diff` 可以发现变量已被删除(`missing`)。
|
|
656
|
+
|
|
657
|
+
### Scope 说明
|
|
658
|
+
|
|
659
|
+
| Scope | 触发方式 | 生效范围 | 持久性 |
|
|
660
|
+
|-------|---------|---------|--------|
|
|
661
|
+
| `system`(默认) | `qenv set NAME value` | 新终端窗口 | ✅ 永久 |
|
|
662
|
+
| `system-wide` | `qenv set NAME value --system` | 所有用户的新终端 | ✅ 永久 |
|
|
663
|
+
| `session` | `qenv set NAME value --local` | 仅当前终端窗口 | ❌ 关闭即失效 |
|
|
664
|
+
| `file` | `qenv set NAME value --file` | 取决于应用是否读取 | ✅ 文件存在即有效 |
|
|
665
|
+
|
|
666
|
+
---
|
|
667
|
+
|
|
668
|
+
## 常见用法示例
|
|
669
|
+
|
|
670
|
+
### CI/CD 中批量设置环境变量
|
|
671
|
+
|
|
672
|
+
```bash
|
|
673
|
+
# 从密钥管理中导出 .env 文件,然后导入到系统
|
|
674
|
+
qenv import .env.ci --overwrite --silent
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### 在脚本中获取值
|
|
678
|
+
|
|
679
|
+
```bash
|
|
680
|
+
# Bash / Zsh
|
|
681
|
+
DB_HOST=$(qenv get DB_HOST --raw)
|
|
682
|
+
echo "连接到数据库: $DB_HOST"
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
```powershell
|
|
686
|
+
# PowerShell
|
|
687
|
+
$dbHost = qenv get DB_HOST --raw
|
|
688
|
+
Write-Host "连接到数据库: $dbHost"
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
### 在不同 .env 文件间切换
|
|
692
|
+
|
|
693
|
+
```bash
|
|
694
|
+
# 查看各环境配置
|
|
695
|
+
qenv list --file .env.dev
|
|
696
|
+
qenv list --file .env.staging
|
|
697
|
+
qenv list --file .env.prod
|
|
698
|
+
|
|
699
|
+
# 导入开发环境配置到当前会话
|
|
700
|
+
qenv import .env.dev --local
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
### 导出特定前缀的变量
|
|
704
|
+
|
|
705
|
+
```bash
|
|
706
|
+
# 只导出 React 应用相关变量
|
|
707
|
+
qenv export .env.react --filter REACT_APP_
|
|
708
|
+
|
|
709
|
+
# 只导出 AWS 相关变量到 stdout
|
|
710
|
+
qenv export --filter AWS_
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
### 项目初始化模板
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
# 为新同事快速搭建开发环境
|
|
717
|
+
qenv import .env.example --overwrite
|
|
718
|
+
qenv list --verify
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
### 定期维护 manifest
|
|
722
|
+
|
|
723
|
+
```bash
|
|
724
|
+
# 检查是否有过期的记录
|
|
725
|
+
qenv diff
|
|
726
|
+
|
|
727
|
+
# 自动清理所有失效记录
|
|
728
|
+
qenv clean --force
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
---
|
|
732
|
+
|
|
733
|
+
## 注意事项与限制
|
|
734
|
+
|
|
735
|
+
### Windows 平台
|
|
736
|
+
|
|
737
|
+
| 限制 | 说明 |
|
|
738
|
+
|------|------|
|
|
739
|
+
| `setx` 字符上限 | 值不能超过 **1024 个字符**,超出时 qenv 会提前报错 |
|
|
740
|
+
| 需重启终端 | 通过 `setx` 设置的变量需要打开**新终端窗口**才能生效 |
|
|
741
|
+
| 管理员权限 | `--system` 模式需要以**管理员身份**运行终端 |
|
|
742
|
+
|
|
743
|
+
> 💡 **提示:** 使用 `--local` 模式可以避免重启终端的问题,变量立即在当前窗口生效。
|
|
744
|
+
|
|
745
|
+
### macOS / Linux 平台
|
|
746
|
+
|
|
747
|
+
| 限制 | 说明 |
|
|
748
|
+
|------|------|
|
|
749
|
+
| 需 source 配置 | 修改 `.bashrc` / `.zshrc` 后需 `source` 或重启终端才能生效 |
|
|
750
|
+
| sudo 权限 | `--system` 操作 `/etc/environment` 需要 sudo |
|
|
751
|
+
| Shell 兼容 | 已内置支持 Bash、Zsh、Fish;其他 Shell 可用 `qenv init --print` 手动适配 |
|
|
752
|
+
|
|
753
|
+
### 通用限制
|
|
754
|
+
|
|
755
|
+
| 限制 | 说明 |
|
|
756
|
+
|------|------|
|
|
757
|
+
| 变量名规则 | 必须匹配 `/^[A-Za-z_][A-Za-z0-9_]*$/`(字母或下划线开头) |
|
|
758
|
+
| 不存储值 | manifest 仅记录元信息,不缓存变量的实际值 |
|
|
759
|
+
| 非独占管理 | 其他工具可修改同一变量,qenv 不阻止但 `diff` 可检测差异 |
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
## 开发指南
|
|
764
|
+
|
|
765
|
+
### 环境准备
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
git clone https://github.com/user/qenv.git
|
|
769
|
+
cd qenv
|
|
770
|
+
npm install
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
> 📦 npm 包名为 `@zqw-cli/qenv`,CLI 命令名仍为 `qenv`。
|
|
774
|
+
|
|
775
|
+
### 常用命令
|
|
776
|
+
|
|
777
|
+
| 命令 | 说明 |
|
|
778
|
+
|------|------|
|
|
779
|
+
| `npm run build` | 使用 tsup 构建,输出到 `dist/` |
|
|
780
|
+
| `npm run dev` | 开发模式(watch,文件变更自动重新构建) |
|
|
781
|
+
| `npm test` | 运行 Vitest 单元测试 |
|
|
782
|
+
| `npm link` | 本地全局链接,方便开发调试 |
|
|
783
|
+
|
|
784
|
+
### 本地调试
|
|
785
|
+
|
|
786
|
+
```bash
|
|
787
|
+
# 构建
|
|
788
|
+
npm run build
|
|
789
|
+
|
|
790
|
+
# 直接运行
|
|
791
|
+
node dist/index.js --help
|
|
792
|
+
|
|
793
|
+
# 或全局链接后使用
|
|
794
|
+
npm link
|
|
795
|
+
qenv --help
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
### 技术栈
|
|
799
|
+
|
|
800
|
+
| 工具 | 用途 |
|
|
801
|
+
|------|------|
|
|
802
|
+
| [TypeScript](https://www.typescriptlang.org/) | 类型安全的开发语言 |
|
|
803
|
+
| [tsup](https://github.com/egoist/tsup) | 零配置打包,输出 CJS + DTS,自动加 `#!/usr/bin/env node` |
|
|
804
|
+
| [Commander.js](https://github.com/tj/commander.js) | CLI 框架,链式 API,自动 `--help` 生成 |
|
|
805
|
+
| [chalk](https://github.com/chalk/chalk) | 终端彩色输出 |
|
|
806
|
+
| [conf](https://github.com/sindresorhus/conf) | 跨平台 JSON 持久化存储(manifest) |
|
|
807
|
+
| [ora](https://github.com/sindresorhus/ora) | 终端 spinner 加载动画 |
|
|
808
|
+
| [Vitest](https://vitest.dev/) | 快速单元测试框架 |
|
|
809
|
+
|
|
810
|
+
### 发布到 npm
|
|
811
|
+
|
|
812
|
+
```bash
|
|
813
|
+
# prepublishOnly 会自动执行 build + test
|
|
814
|
+
npm publish
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
---
|
|
818
|
+
|
|
819
|
+
## 项目结构
|
|
820
|
+
|
|
821
|
+
```
|
|
822
|
+
qenv/
|
|
823
|
+
├── src/
|
|
824
|
+
│ ├── index.ts # CLI 入口:注册全部命令 + 全局选项 + --shell-eval 处理
|
|
825
|
+
│ ├── commands/
|
|
826
|
+
│ │ ├── set.ts # qenv set — 设置环境变量
|
|
827
|
+
│ │ ├── get.ts # qenv get — 读取环境变量
|
|
828
|
+
│ │ ├── remove.ts # qenv remove (rm) — 删除环境变量
|
|
829
|
+
│ │ ├── list.ts # qenv list (ls) — 列出变量 + 失效标记
|
|
830
|
+
│ │ ├── diff.ts # qenv diff + qenv clean — 对比 & 清理 manifest
|
|
831
|
+
│ │ ├── init.ts # qenv init — 安装/卸载 Shell 集成
|
|
832
|
+
│ │ └── import.ts # qenv import + qenv export — 批量导入导出
|
|
833
|
+
│ ├── drivers/
|
|
834
|
+
│ │ ├── types.ts # EnvDriver 接口定义(get/set/remove/list)
|
|
835
|
+
│ │ ├── index.ts # 驱动选择器(根据 process.platform)
|
|
836
|
+
│ │ ├── windows.ts # Windows 驱动(setx / reg add / reg query)
|
|
837
|
+
│ │ ├── unix.ts # Unix 驱动(读写 .bashrc / .zshrc / config.fish)
|
|
838
|
+
│ │ └── dotenv.ts # .env 文件驱动(解析、写入、保留注释)
|
|
839
|
+
│ ├── shell/
|
|
840
|
+
│ │ ├── detect.ts # Shell 类型自动检测(bash/zsh/fish/pwsh/cmd)
|
|
841
|
+
│ │ └── eval.ts # --shell-eval 输出 eval 表达式
|
|
842
|
+
│ ├── manifest/
|
|
843
|
+
│ │ └── index.ts # Manifest 管理器(基于 conf 库的单例)
|
|
844
|
+
│ └── utils/
|
|
845
|
+
│ ├── logger.ts # 统一日志输出(success/warn/error/info/table)
|
|
846
|
+
│ ├── validator.ts # 变量名校验 + .env 解析 + 序列化
|
|
847
|
+
│ └── platform.ts # 平台判断 + 权限检测 + Home 目录
|
|
848
|
+
├── tests/
|
|
849
|
+
│ ├── validator.test.ts # 校验器 & .env 解析测试(15 cases)
|
|
850
|
+
│ ├── dotenv.test.ts # .env 驱动集成测试(8 cases)
|
|
851
|
+
│ ├── platform.test.ts # 平台工具测试(2 cases)
|
|
852
|
+
│ ├── shell.test.ts # Shell 检测测试(2 cases)
|
|
853
|
+
│ └── manifest.test.ts # Manifest 结构测试(2 cases)
|
|
854
|
+
├── dist/ # 构建输出(.gitignore)
|
|
855
|
+
├── tsup.config.ts # tsup 构建配置
|
|
856
|
+
├── tsconfig.json # TypeScript 编译配置
|
|
857
|
+
├── vitest.config.ts # Vitest 测试配置
|
|
858
|
+
├── package.json # 包描述 & 脚本
|
|
859
|
+
├── .gitignore
|
|
860
|
+
└── README.md # 本文档
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
---
|
|
864
|
+
|
|
865
|
+
## License
|
|
866
|
+
|
|
867
|
+
[MIT](LICENSE) © 2026
|