Nhost CLI 的 npm 发行版:使用 @nhost/cli 实现按项目锁定版本的跨平台安装
【免费下载链接】nhostThe Open Source Firebase Alternative with GraphQL.项目地址: https://gitcode.com/GitHub_Trending/nh/nhost
Nhost 是开源的 Firebase 替代品,其 CLI(cli/)用于搭建本地开发环境(Postgres、GraphQL、Auth、Storage、Serverless Functions 全栈一键拉起)。本文聚焦 Nhost 官方提供的 npm 发行渠道——@nhost/cli包:你不再需要 curl 脚本或 Homebrew,而是通过 npx / pnpm dlx / yarn dlx / bunx 临时运行,或将 CLI 作为项目的 devDependency 安装,从而为整个团队锁定同一版本。读完本文,你将掌握@nhost/cli的完整用法、版本与二进制平台的对应关系,以及这套跨平台 npm 分发机制的底层实现原理。
为什么要把 CLI 搬进 npm
Nhost CLI 本身是用 Go 编写的单一二进制(入口见 cli/main.go,基于 urfave/cli v3),官方提供了多种安装方式:
- Homebrew:
brew install nhost/tap/nhost - Nix flakes:
nix profile install github:nhost/nhost#cli - 快速脚本:
curl -sSL .../cli/get.sh | bash(可带版本参数,如bash -s 1.38.0,见 cli/README.md)
而@nhost/cli这条 npm 渠道的价值在于两点:
- 免 curl / brew:只要项目里已经有 Node.js 工具链(npm / pnpm / Yarn / Bun),就能以最熟悉的方式获取 CLI,无需额外安装系统级工具。
- 按项目锁定版本:把 CLI 声明在
package.json的 devDependencies 里,锁文件(lockfile)会同时锁住 CLI 版本,全团队 CI 与本地环境使用完全一致的二进制——这正是“版本固定到每个项目”的团队协作最佳实践。
一次性使用:npx / pnpm dlx / yarn dlx / bunx
不安装任何东西,直接从 npm 临时拉取并运行最新版:
npx @nhost/cli@latest --version pnpm dlx @nhost/cli@latest --version yarn dlx @nhost/cli@latest --version bunx @nhost/cli@latest --version--version只是验证通道,实际可替换为任何子命令,例如npx @nhost/cli@latest init。四种包管理器语法虽不同(npx、dlx、bunx),但行为一致:下载包、执行、用完即弃。
适用场景:临时体验、CI 一次性任务、不想在项目里引入依赖的场合。注意此方式每次拉取的是@latest,不保证团队一致,因此需要严格版本一致性的场景应改用下面的项目内安装。
项目内安装:把 CLI 变成 devDependency
在项目根目录执行:
npm install -D @nhost/cli pnpm add -D @nhost/cli yarn add -D @nhost/cli bun add -d @nhost/cli安装完成后,CLI 二进制会被链接到本地node_modules/.bin/,用包管理器执行:
npm exec nhost -- --version pnpm exec nhost --version yarn nhost --version bunx nhost --version注意npm exec nhost -- --version中--是为了把--version透传给 nhost 而不是 npm 自身;pnpm exec/yarn/bunx则无需此分隔符。
写入 package.json scripts 固化工作流
更规范的做法是把常用命令固化到package.json的scripts中,团队成员只需记住npm run级别的语义化命令:
{ "scripts": { "backend:up": "nhost up", "backend:down": "nhost down" } }之后执行npm run backend:up即可启动本地全栈环境。nhost up会通过 Docker Compose 拉起 Postgres、GraphQL(Hasura)、Auth、Storage、Functions 等全部服务并打印本地访问地址;nhost down停止整个栈(详见 cli/README.md 的 Get Started 一节,本地 Dashboard 默认运行在local.dashboard.local.nhost.run)。
版本锁定机制:npm 包版本 = CLI 发布版本
@nhost/cli的 npm 包版本与 GitHub 上的 CLI release 版本一一对应(cli@X.Y.Z),因此:
- 锁定包版本 = 锁定 CLI 版本;
- 升级只需 bump devDependency 并重新 install;
- 团队共享
package-lock.json/pnpm-lock.yaml等锁文件后,所有人二进制一致。
这条保证由发布流水线强制执行:发布时以make get-version计算的版本号同时写入五个包,make validate-npm会校验主包与四个平台包的版本号完全一致(见 cli/Makefile 与 cli/build/npm/scripts/validate-staged-packages.mjs 中的pkg.version !== version检查)。任何版本不一致都会让发布失败,从机制上杜绝“npm 包版本与 CLI 版本脱节”的可能。
跨平台分发的底层原理:一个主包 + 四个平台包
@nhost/cli不是把多个平台的二进制塞进一个包,而是采用了“主包 + optionalDependencies 平台包”的分发结构,这是esbuild、@rollup/rollup等工具广泛使用的成熟模式。
主包:@nhost/cli
主包本身只携带一个启动 shim 二进制,真正干活的是按平台安装的可选依赖。从 cli/build/npm/package.json 可以看到核心字段:
{ "name": "@nhost/cli", "bin": { "nhost": "bin/nhost" }, "files": [ "bin/nhost" ], "optionalDependencies": { "@nhost/cli-darwin-arm64": "0.0.0", "@nhost/cli-darwin-x64": "0.0.0", "@nhost/cli-linux-arm64": "0.0.0", "@nhost/cli-linux-x64": "0.0.0" }, "engines": { "node": ">=18" } }字段解读:
bin.nhost:声明命令名nhost,安装后生成node_modules/.bin/nhost可执行链接;files:只发布bin/nhostshim,主包体积极小;optionalDependencies:四个平台包。用optional是因为每个安装环境只需要其中恰好一个,其余三个允许安装失败(不存在于当前平台);engines.node >= 18:对 Node 运行时版本的最低要求。
平台包:以@nhost/cli-darwin-arm64为例
四个平台包结构一致,分别对应 darwin-arm64、darwin-x64、linux-arm64、linux-x64。以 cli/build/npm/platforms/darwin-arm64/package.json 为例:
{ "name": "@nhost/cli-darwin-arm64", "description": "Nhost CLI binary for darwin-arm64", "os": ["darwin"], "cpu": ["arm64"], "files": ["nhost"], "preferUnplugged": true }关键点:
os/cpu字段:npm 只在当前系统匹配时安装该包。macOS arm64 机器只会拉取darwin-arm64包,Linux x64 只会拉取linux-x64包,其余作为不匹配的 optional 依赖被跳过;files: ["nhost"]:平台包里就是该平台编译好的 Go 二进制本体;preferUnplugged: true:在 pnpm 等环境下不放进内容寻址存储(store)而是保持实体文件,确保二进制可以直接执行。
因此整体安装行为是:主包 shim 在运行时(或安装后)从已安装的平台包目录中找到nhost二进制并 exec,用户感知到的就是一个统一的nhost命令。
发布与校验:这些包是怎么保证质量的
这一节面向想深入理解该机制(或需要自维护类似分发)的读者,来自 cli/build/npm/PUBLISHING.md 与 cli/Makefile。
Make 流水线
从仓库根目录(或在cli/下)可执行三个 Make 目标:
make -C cli build-npm # 用 Nix 构建四个平台二进制并暂存到 build/npm/dist make -C cli validate-npm # 发布前校验暂存包 make -C cli publish-npm # 按顺序发布到 npmbuild-npm依赖cli-multiplatformNix derivation,保证二进制与 GitHub release 构建产物同源;validate-npm运行 cli/build/npm/scripts/validate-staged-packages.mjs,校验内容包括:五个包版本一致、主包optionalDependencies恰好指向四个平台包且版本一致、包名保持@nhost/cli前缀、bin/nhost与各平台nhost文件具备可执行权限(fs.constants.X_OK);publish-npm运行 cli/build/npm/scripts/publish-staged-packages.mjs。
发布顺序与跳过逻辑
发布脚本严格按“平台包先行、主包殿后”的顺序执行:
@nhost/cli-darwin-arm64@nhost/cli-darwin-x64@nhost/cli-linux-arm64@nhost/cli-linux-x64@nhost/cli
原因很直接:主包若已发布而平台包缺失,会导致安装失败;反之平台包先发而无主包引用则无害。另外,发布前脚本会执行npm view name@version,若该精确版本在 npm 上已存在则跳过(幂等重跑),因此部分失败后重跑只会补齐缺失的包。
dist-tag 规则
版本号中若含alpha、beta、dev、rc(例如1.50.0-beta.1),自动使用betadist-tag;其余版本使用latest(可用NPM_TAG环境变量覆盖)。这与前面npx @nhost/cli@latest的语义直接相关——@latest指向的就是稳定版 tag。
发布鉴权
CI 采用 npm 可信发布(OIDC),无需在 CI 中存放 npm token。五个包(主包加四个平台包)均需在 npmjs 上配置 trusted publisher,指向本仓库发布工作流的publish-npmjob。CLI 包不使用仓库中面向 JS/SDK 的共享发布工作流,二者相互隔离。
支持的平台与 Windows 用户的正确姿势
官方支持矩阵:
- macOS:arm64(Apple Silicon)、x64(Intel)
- Linux:arm64、x64
- Windows:原生不支持,请使用 WSL2——在 WSL 内部会自动选用 Linux 二进制
从发布结构可以印证:@nhost/cli恰好对应上述四个平台组合(darwin-arm64、darwin-x64、linux-arm64、linux-x64)。Windows 用户在 WSL2 中安装后,无论通过 WSL 的 bash 还是从 Windows 侧透传执行nhost,解析到的都是 linux 平台包。若你使用 Apple Silicon Mac 运行 Intel 版本(Rosetta),npm 会按process.arch识别为 x64 并安装 x64 包,通常也能正常工作,但官方推荐原生 arm64 以获得最佳性能。
使用建议小结
- 个人临时使用:
npx @nhost/cli@latest <subcommand>; - 团队项目:
pnpm add -D @nhost/cli(或对应包管理器命令)+ 提交锁文件,确保全组版本一致; - 日常工作流:把
nhost up/nhost down/nhost init等写进package.jsonscripts,统一入口; - Windows 用户:一律在 WSL2 内安装使用;
- 想了解发布细节或自维护类似分发:阅读 cli/build/npm/PUBLISHING.md 和 cli/build/npm/scripts/ 下的校验与发布脚本,它们完整展示了“主包 + 平台包 + optionalDependencies + 平台先行发布”这一分发模式的工程实现。
【免费下载链接】nhostThe Open Source Firebase Alternative with GraphQL.项目地址: https://gitcode.com/GitHub_Trending/nh/nhost
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考