我如何将我的 Rust Bun 版本管理器 (bum) CLI 发布到 NPM 包
Source: Dev.to
背景
我构建了一个名为 bum 的 CLI——一个用 Rust 编写的快速 Bun 版本管理器。它在本地运行得很好,但我希望任何人都能运行:
npx @owenizedd/bum use 1.3.3
而无需安装 Rust 或编译任何东西。事实证明这完全可行!我从 lekoarts.de 的一篇关于使用 napi‑rs 在 npm 上发布 Rust CLI 的文章中学到了这点。
设置
将 napi-rs 添加到你的 Rust 项目
# Cargo.toml
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
napi = "2.16"
napi-derive = "2.16"
[build-dependencies]
napi-build = "2.1"
用 napi 函数包装你的 CLI
// src/lib.rs
use napi_derive::napi;
#[napi]
pub fn run(args: Vec) -> napi::Result {
let rt = tokio::runtime::Runtime::new()
.map_err(|e| napi::Error::from_reason(format!("Failed to create runtime: {}", e)))?;
// Your CLI logic here
rt.block_on(async {
// run_commands(args).await
});
Ok(())
}
创建一个简单的 bin.js
#!/usr/bin/env node
const { run } = require("./index");
const args = process.argv.slice(2);
try {
run(args);
} catch (e) {
console.error(e);
process.exit(1);
}
配置 package.json
{
"name": "@owenizedd/bum",
"bin": "bin.js",
"napi": {
"name": "bum",
"triples": {
"defaults": true,
"additional": [
"aarch64-apple-darwin",
"x86_64-apple-darwin",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-gnu"
]
}
}
}
OpenSSL 跨编译噩梦
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
zip = { version = "1.1", default-features = false, features = ["deflate"] }
每个平台(例如 darwin-arm64、linux-x64-gnu)都会作为单独的 npm 包发布。最初我们忘记更新它们的 package.json 版本,导致 npm 找不到这些包。
解决方案:在 CI 中同步平台包版本
- name: Sync platform package versions
run: |
VERSION=$(node -p "require('./package.json').version")
for dir in npm/*/; do
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('$dir/package.json'));
pkg.version = '$VERSION';
fs.writeFileSync('$dir/package.json', JSON.stringify(pkg, null, 2));
"
done
打包陷阱
我们最初尝试使用 bun build bin.ts 编译 TypeScript。Bun 将 require('./index') 内联,并用哈希硬编码了 .node 文件名,导致代码损坏:
// Broken bundling result
nativeBinding = require("./bum.darwin-arm64-7xvffnqw.node");
正确(可工作)的导入应该是:
// Correct import
nativeBinding = require("./bum.darwin-arm64.node");
解决方案: 对 bin.js 使用普通的 JavaScript,避免打包。
结果
现在任何人都可以运行:
npx @owenizedd/bum use 1.3.3
它在 macOS、Linux 和 Windows 上都能工作(其他平台仍在测试中)。
参考资料
- Publishing a Rust CLI on npm – 让这成为可能的文章
- napi‑rs Documentation
- bum GitHub Repository