napi-rs 与 Node.js 原生模块
问题
napi-rs 是什么?如何用 Rust 编写 Node.js 原生模块?
答案
napi-rs 是用 Rust 编写 Node.js 原生模块的框架,基于 Node-API(N-API),提供了类型安全的绑定。SWC、Rspack、Biome 等工具都通过 napi-rs 与 Node.js 生态集成。
为什么用 Rust 写 Node.js 原生模块
| 方案 | 语言 | 安全性 | 性能 | 开发体验 |
|---|---|---|---|---|
| 纯 JS | JavaScript | 安全 | 慢 | 好 |
| C++ Addon | C++ | 手动管理内存 | 最快 | 差 |
| napi-rs | Rust | 内存安全 | 接近 C++ | 好 |
| WebAssembly | Rust/C++ | 安全 | 较快(有开销) | 中等 |
快速上手
# 创建项目
npx @napi-rs/cli new my-napi-module
cd my-napi-module
src/lib.rs
use napi_derive::napi;
/// 同步函数:直接导出
#[napi]
pub fn sum(a: i32, b: i32) -> i32 {
a + b
}
/// 异步函数:返回 AsyncTask
#[napi]
pub async fn read_file_async(path: String) -> napi::Result<String> {
tokio::fs::read_to_string(&path)
.await
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
/// 带回调的流式处理
#[napi(ts_args_type = "callback: (line: string) => void")]
pub fn process_lines(input: String, callback: napi::JsFunction) {
for line in input.lines() {
callback
.call(None, &[line.into()])
.unwrap();
}
}
自动生成的 TypeScript 类型
// index.d.ts(napi-rs 自动生成)
export function sum(a: number, b: number): number
export function readFileAsync(path: string): Promise<string>
export function processLines(input: string, callback: (line: string) => void): void
在 Node.js 中使用
import { sum, readFileAsync } from './index.js';
console.log(sum(1, 2)); // 3
const content = await readFileAsync('./package.json');
napi-rs 的跨平台分发
napi-rs 的 CLI 工具支持预编译 + 按平台发布 npm 包:
@my-scope/my-module # 主包(选择性加载)
@my-scope/my-module-darwin-arm64 # macOS ARM
@my-scope/my-module-darwin-x64 # macOS Intel
@my-scope/my-module-linux-x64 # Linux x64
@my-scope/my-module-win32-x64 # Windows x64
用户 npm install @my-scope/my-module 时,自动下载对应平台的预编译二进制,无需本地编译。
常见面试问题
Q1: napi-rs vs WebAssembly,哪个更适合 Node.js 扩展?
答案:
| 维度 | napi-rs | WebAssembly |
|---|---|---|
| 性能 | 原生速度 | 有 Wasm 运行时开销 |
| 系统调用 | ✅ 完全访问 | ❌ 受限沙箱 |
| 文件/网络 | ✅ 直接调用 | ❌ 需要通过 JS |
| 跨平台 | 需要为每个平台编译 | ✅ 一次编译到处运行 |
| 分发 | 多平台预编译 npm 包 | 单个 .wasm 文件 |
选择建议:
- 需要系统调用(文件、网络、OS API)→ napi-rs
- 纯计算(加密、编解码、算法)→ WebAssembly
- 需要极致性能 → napi-rs