首页
/ zx 版本体系详解:@latest、@lite 与 @dev 发布通道与能力差异深度剖析

zx 版本体系详解:@latest、@lite 与 @dev 发布通道与能力差异深度剖析

2026-09-07 17:37:10作者:尤峻淳Whitney

本文基于 zx 官方文档 versions 展开,系统讲解 zx 的三个发布通道(@latest@lite@dev)各自包含的能力边界,并对照当前仓库源码(src/index.tssrc/core.tspackage.json)说明 lite 版本是如何从完整版本中剥离出来的。读完本文,你将能准确判断自己的脚本或自定义工具集应该安装哪个通道、哪个入口点,并理解各导出成员($ProcessPromiseglobtempfile 等)在 full 与 lite 包中的归属。

三个版本通道:@latest、@lite、@dev

versions 文档的核心结论是:zx 以多个版本(通道)形式分发,每个通道拥有各自的功能集合:

  • @latest —— 稳定、全功能的版本;
  • @lite —— 将 zx 的核心(core)从扩展(extensions)中分离出来的精简版;
  • @dev —— 实验性的快照与 RC(Release Candidate)。

对应的安装方式为:

npm i zx          # @latest
npm i zx@lite     # @lite
npm i zx@dev      # @dev

另外,安装指南 中补充了第四个通道 legacy,用于兼容旧脚本的遗留维护版本——不提供新特性,仅做 bug 修复,安装时需显式指定版本号(npm i zx@<version>)。也就是说,@latest/@lite/@dev 是 tag 形式的通道,而固定版本号安装(如 安装指南 中演示的 npx zx@8.6.0 script.js)则属于 legacy 语义下的版本锁定方式。

lite 专页@lite 的定位进一步量化:

  • 体积约为完整版本的 1/7(~7x smaller);
  • 不内嵌 CLI、文档、manpage 等资产;
  • 包名相同,只是发布通道不同(@lite);
  • 代码更少,安全审计更快、更可靠;
  • 官方推荐用于“基于 zx 构建自定义工具集”的场景。

能力对比:full 版本 vs lite 版本

以下是 versions 文档给出的完整功能对照表(✔️ 表示该通道包含此能力, 表示不包含):

功能 latest lite
zx/globals ✔️
zx/cli ✔️
$ ✔️ ✔️
ProcessPromise ✔️ ✔️
ProcessOutput ✔️ ✔️
argv ✔️
cd ✔️ ✔️
chalk ✔️ ✔️
defaults ✔️ ✔️
dotenv ✔️
echo ✔️
expBackoff ✔️
fetch ✔️
fs ✔️
glob ✔️
kill ✔️ ✔️
log ✔️ ✔️
minimist ✔️
nothrow ✔️
os ✔️ ✔️
parseArgv ✔️
path ✔️ ✔️
ps ✔️ ✔️
question ✔️
quiet ✔️
quote ✔️ ✔️
quotePowerShell ✔️ ✔️
resolveDefaults ✔️ ✔️
retry ✔️
sleep ✔️
spinner ✔️
syncProcessCwd ✔️ ✔️
tempdir ✔️
tempfile ✔️
updateArgv ✔️
useBash ✔️ ✔️
usePowerShell ✔️ ✔️
usePwsh ✔️ ✔️
version ✔️
which ✔️ ✔️
within ✔️ ✔️
YAML ✔️
MAML ✔️

从这张表可以把 lite 的能力归纳为一条清晰的边界线:

  • 保留(进程执行核心链路):模板字符串 spawner $ 及其背后的 ProcessPromise/ProcessOutput 类、工作目录管理(cdsyncProcessCwd)、进程管理(killps)、日志与终端着色(logchalk)、shell 切换(useBash/usePwsh/usePowerShell)、路径与 OS(pathos)、引号工具(quotequotePowerShell)、默认值解析(defaultsresolveDefaults)、工具查找(which)以及 within
  • 剥离(扩展与便利函数):全局注入入口 zx/globals、命令行入口 zx/cli、参数解析三件套(argv/minimist/parseArgv/updateArgv)、fsglobfetchdotenvechoexpBackoffretrysleepspinnerquestionnothrowquietversion、临时文件(tempdir/tempfile)、以及 YAML/MAML 数据格式支持。

换言之,lite 就是“一个能跑的 $ 模板引擎加进程管理”,full 版本则是“$ 加上一整套脚本工具库”。

各 API 归属何处:zx 的导出结构

对照表中的每一项能力,在源码层面分别落在哪些文件里?结合当前仓库可以逐条印证。

package.json 声明了四个入口点(exports 字段),对应版本表中最关键的几行:

"exports": {
  ".": { "import": "./build/index.js", "require": "./build/index.cjs" },
  "./globals": { "import": "./build/globals.js", "require": "./build/globals.cjs" },
  "./cli": { "import": "./build/cli.js", "require": "./build/cli.cjs" },
  "./core": { "import": "./build/core.js", "require": "./build/core.cjs" },
  "./package.json": "./package.json"
}
  • zx.)——主入口,聚合全部能力;
  • zx/globals——把 zx 的所有函数注入 globalThis,即表中 zx/globals 一行;
  • zx/cli——命令行执行器(bin.zx -> build/cli.js),即表中 zx/cli 一行;
  • zx/core——模板字符串 spawner 核心,供第三方库以自选工具组合的方式复用。

再看源码分层的实际切分:

  1. src/core.ts 定义进程执行核心:$sync$)、ProcessPromiseProcessOutputdefaults/resolveDefaultswithinuseBash/usePwsh/usePowerShellsyncProcessCwdcdkill,并重新导出 logpathoschalkwhichpsquotequotePowerShell 等——与版本表中 lite 列打勾的条目一一对应。
  2. src/index.ts 在主入口上叠加扩展能力:export * from './core.ts' + export * from './goods.ts',再从 src/vendor.ts 导出 minimistdotenvfsYAMLMAMLglob(别名 globby),并定义 VERSION/version 及标记为 deprecated 的 nothrow/quiet 函数——对应版本表中 lite 列不勾选的条目。
  3. src/globals.ts 通过 Object.assign(globalThis, _) 将主入口的全部导出注入全局,并声明了 $argvglobbytmpdir/tmpfile 等全局变量——这就是 zx/globals 入口的实现。

因此,“lite 分离 core 与 extensions”并非打包时随意裁剪,而是源码本身就按 core / goods / vendor / globals 分层组织,lite 只需发布 core 这一层。

lite 包是如何构建与验证的

从构建脚本可以进一步确认 lite 的生产方式。package.jsonscripts 中包含:

"build:lite": "node scripts/build-pkgjson-lite.mjs",
"build:manifest": "npm run build:pkgjson && npm run build:lite && npm run build:jsr"

即每次构建都会生成一个 lite 专用 package.json(package-lite.json)。集成测试 test/it/build-npm.test.jszx@lite 做了端到端验证:把 package-lite.json 换回 package.jsonnpm pack 打包、解包后运行最小脚本(import { $ } from "./package/build/core.js"),并断言产物满足:

  • 包名仍为 zx(“同包名、不同通道”);
  • devDependencies 不存在(不携带开发依赖);
  • bin 字段不存在(不含 CLI 可执行入口);
  • 文件清单为精简后的构建产物集合。

这与 versions 表中 zx/clizx/globals 在 lite 列缺失、bin 被移除的事实完全吻合。

版本号与运行环境约束

关于“当前是什么版本”的权威来源有两处:

  • package.json 顶层的 "version": "8.9.0",以及 "engines": { "node": ">= 12.17.0" }——即本仓库对应 zx 8.9.0,官方声明支持 Node.js 12.17.0 及以上;
  • src/versions.ts 维护内置依赖版本表(chalk 5.6.2、depseek 0.4.6、dotenv 0.2.3、fetch 1.6.7、fs 11.3.5、glob 16.2.0、minimist 1.2.8、ps 1.2.1、which 7.0.0、yaml 2.9.0 等),src/index.ts 据此导出 VERSION/versionversions.zx || '0.0.0')。

这说明 zx 采取“打包内联第三方依赖”的构建策略:fsglobminimist 等并非要求用户另行安装,而是随包内置,这也是版本表里它们与 $ 一起出现在 latest 列、却在 lite 列被整体剥离的原因——lite 连这些内联依赖一并移除了。

此外,安装指南 列出的运行环境要求是:Linux / macOS / Windows,JavaScript 运行时为 Node.js >= 12.17.0、Bun >= 1.0.0、Deno 1.x/2.x 或 GraalVM Node.js,并需要 bash 或 PowerShell 之一。这些约束对三个通道同样适用。

如何选择并安装

结合 versionslite 的说明,选型可以按下面的决策路径走:

  1. 写独立运维/部署脚本、希望开箱即用全部工具globfsretryspinnerquestionYAML 等):

    npm i zx        # 安装 @latest 稳定版
    npx zx script.js # 或免安装直接运行;npx zx@8.6.0 可锁定版本
    
  2. 编写轻量脚本,或把自己的工具集构建在 zx 之上lite 官方推荐场景):

    npm i zx@lite
    npm i zx@8.5.5-lite   # 通道 + 精确版本组合
    

    代码侧只需保留 core 用法:

    import { $ } from 'zx'
    await $`echo foo`
    
  3. 跟踪未发布的新特性或验证 RC(接受不稳定):

    npm i zx@dev
    

    FAQ 中也用 npx zx@dev --install 演示了借助 dev 通道临时安装脚本内联依赖的用法。

  4. 需要兼容旧脚本:显式固定版本号 npm i zx@<version>(legacy 通道语义,见 安装指南 的 Channels 表)。

lite 还给出了一条“功能量级”参照线(由轻到重):Node 内置 child_process < zurk < zx@lite < zx,帮助开发者判断当前需求是否值得引入完整 zx,还是用更轻的依赖即可。

小结与参考文件

登录后查看全文
热门项目推荐
相关项目推荐