开发工具后端【免费下载链接】napi-rsA framework for building compiled Node.js add-ons in Rust via Node-API项目地址https://gitcode.com/gh_mirrors/na/napi-rs点击查看免费下载本文以 napi-rs 仓库中 crates/macro/CHANGELOG.md 为主线结合 crates/macro 与 crates/backend 的源码实现系统梳理napi-derive过程宏 crate 的架构、全部可用属性、feature 开关以及 3.x 版本的关键能力演进。读完本文你将掌握#[napi]属性宏在 Rust 与 Node.js 之间生成桥接代码的完整工作方式能够正确配置napi-derive的 features、熟练使用类对象类型标签、异步迭代器、discriminant 大小写控制等进阶能力并了解如何通过环境变量调试宏展开产物。napi-derive 在 napi-rs 中的定位napi-rs 是一个用 Rust 编写 Node.js 原生插件add-on的框架其核心体验来自#[napi]过程宏开发者只需在 Rust 函数、结构体、枚举、常量或 impl 块上标注一个属性宏就会在编译期自动生成与 Node-APIN-API对接的桥接代码包括参数转换、返回值转换、模块注册与 TypeScript 类型定义输出。napi-derive位于 crates/macro是一个proc-macro true的 crate见 Cargo.toml当前版本为 3.6.9。它只负责薄薄的一层宏入口与语法解析真正承担 AST 解析和桥接代码生成重活的是它的兄弟 cratenapi-derive-backendcrates/backend其定位是Take care the ast parsing fromnapi-deriveand generate bridge runtime code for both nodejs and rust。二者通过 Cargo.toml 中的依赖napi-derive-backend { version 6.1.4, path ../backend }绑定这也是 CHANGELOG 中大量条目写作 updated the following local packages: napi-derive-backend 的原因——每次 backend 更新都会带动napi-derive发布新版本。核心用法#[napi] 属性宏napi-derive README 给出了最小可用示例。在Cargo.toml中引入napi-derive后即可用#[macro_use] extern crate napi_derive;引入宏或在新版 Rust 中使用use napi_derive::napi;#[macro_use] extern crate napi_derive; use napi::bindgen_prelude::*; #[napi] fn fibonacci(n: u32) - u32 { match n { 1 | 2 1, _ fibonacci_native(n - 1) fibonacci_native(n - 2), } } #[napi] fn get_cwdT: Fn(String) - Result()(callback: T) { callback(env::current_dir().unwrap().to_string_lossy().to_string()).unwrap(); }第一个例子展示普通函数导出u32参数与返回值会被自动映射为 JSnumber。第二个例子展示回调参数Rust 闭包签名会被转换为 JS 回调这依赖napi::bindgen_prelude中的类型系统支持。宏的展开入口在 crates/macro/src/lib.rsnapi是#[proc_macro_attribute]它调用expand::expand生成 TokenStream。值得注意的是展开失败时宏只输出println!诊断信息并原样返回错误 tokens不会 panic 编译进程而如果设置了环境变量NAPI_DEBUG_GENERATED_CODE宏还会把生成的代码打印到 stdout这是调试宏产物最直接的手段。支持的 #[napi] 属性全集#[napi]括号内的可选属性由 crates/macro/src/parser/attrs.rs 中的attrgen!宏集中声明编译期逐一解析。完整的属性清单如下注释中标注了用途属性作用catch_unwind捕获 Rust panic转为 JS 异常抛出async_runtime指定异步任务使用的运行时如 tokiomodule_exports把函数注册为模块 exports 入口js_name自定义导出到 JS 的符号名如js_name customNameconstructor把函数标记为类的构造函数factory标记工厂函数返回类实例getter/setter标记属性访问器可带目标字段名readonly字段只读enumerable/writable/configurable控制属性描述符默认值 trueskip跳过该字段/成员不导出strict启用严格校验return_if_invalid参数无效时直接返回而非抛错object按对象处理结构体object_from_js/object_to_js显式控制 JS 对象到 Rust 结构体的双向转换custom_finalize自定义析构逻辑namespace指定命名空间模块模式自动注入type_tag设置类对象类型标签的盐值3.6.0 引入iterator/async_iterator实现异步迭代器协议ts_args_type/ts_return_type/ts_type覆盖生成的 TypeScript 参数/返回值/字段类型ts_generic_types覆盖生成的 TypeScript 泛型参数string_enum字符串枚举use_nullable可选字段映射为null/undefined默认 falsediscriminant结构化枚举的判别字段名discriminant_case控制判别字段大小写风格3.3.0 引入transparent透明包装类型array元组结构体映射为 JS 数组no_export不导出为模块成员skip_typescript跳过该成员的 TS 类型生成解析器还支持通过#[cfg_attr(condition, napi(...))]条件性地应用#[napi]见 attrs.rs这对跨平台条件导出非常有用。从 crates/backend/src/ast.rs 可以看出宏最终会把各种语法项归一为NapiItem枚举NapiFn函数、NapiStruct结构体、NapiImplimpl 块、NapiEnum枚举、NapiConst常量、NapiType类型别名并各自实现TryToTokens生成桥接代码与ToTypeDef生成 TS 类型定义两个 trait。模块模式与命名空间自动注入#[napi]可以直接标注在mod上批量导出模块内所有带#[napi]标注的成员。展开逻辑位于 crates/macro/src/expand/napi.rs宏会遍历模块内成员将每个成员的#[napi]属性改写为#[napi(namespace 模块名)]从而让导出的符号自动带上命名空间前缀如果模块内再嵌套#[napi]模块则会报错 napi module cannot be nested under another napi module。模块模式还有两个值得注意的实现细节宏内部维护一个BUILT_FLAG: AtomicBoolnapi.rs记录是否已有至少一个#[napi]宏展开过。第一次展开时compare_exchange成功会执行typedef::prepare_type_def_file()为后续累积输出 TypeScript 类型定义做准备。结构体信息会被记录在全局STRUCTS状态中attrs.rs先解析struct定义再解析对应impl块若在非 debug 构建下重复定义constructor会直接报错 Constructor has already been defined。Features 开关按需裁剪编译产物napi-derive的 features 定义在 crates/macro/Cargo.tomlFeature说明default [type-def, strict]默认开启类型定义输出与严格模式type-def启用 TS 类型定义生成依赖napi-derive-backend/type-def与ctorstrict未使用的#[napi]属性会编译报错见 attrs.rs 的check_usednoop空操作模式宏不生成任何桥接代码用于文档/测试场景tracing3.4.0 引入为 NAPI 函数调用输出调试日志compat-mode旧版 napi 兼容模式提供contextless_function、js_function、module_exports、module_init等额外属性宏full一次性开启type-def strict compat-modenoop模式在 expand.rs 中通过#[cfg(feature noop)] mod noop;走一条独立的展开路径完全不依赖parser模块#[cfg(not(feature noop))] mod parser;该路径下甚至不需要syn完整解析。CHANGELOG 3.2.3 中 link issue on cargo test --features noop 修复的就是这条轻量路径的链接问题。strict模式的check_used会把已使用的属性标记下来任何写了但没被消费的#[napi]属性都会产生unused #[napi] attribute诊断错误帮助开发者及时发现拼写错误或无效配置。3.x 版本关键能力演进3.6.0基于 Node 对象类型标签的不可伪造类身份type_tag3.6.0 引入的最重要能力是 unforgeable#[napi]class identity via Node object type tagsPR #3405。它把 Node 的napi_type_tag机制与#[napi(type_tag ...)]属性结合每个类会生成一个内容派生的类型标签默认形如crateversion::module_path::ClassName运行时校验传入对象确实是由该 addon 创建的同名类实例防止跨模块伪造。从 crates/backend/src/ast.rs 的实现注释可以确认其语义type_tag是可选的 crate 级盐值设置后替换默认标签中的crateversion身份分量module_path与类名仍然保留从而避免与恰好同名同版本的无关 addon 发生标签碰撞不设置则沿用默认推导。该标签是纯运行时行为不会出现在生成的 TypeScript 中。对应的运行时实现位于 crates/napi/src/bindgen_runtime/type_tag.rs示例测试可参考 examples/napi/src/type_tag.rs 与 examples/napi/tests/type-tag.spec.ts。3.5.0#[napi(async_iterator)] 异步迭代器3.5.0 新增#[napi(async_iterator)]属性PR #3072允许把 Rust 结构体导出为实现了AsyncIterator协议的 JS 对象。配套地3.2.0 的 make generator an iteratorPR #2784与新增的ScopeGeneratortraitPR #2831让生成器函数可以直接被当作迭代器消费3.1.0 则引入ScopedTaskPR #2786提供带生命周期约束的异步任务使JsValue可以在异步上下文中安全地跨引用解析。3.4.0tracing feature3.4.0 为napi-derive增加tracingfeaturePR #3041用于对 NAPI 函数调用输出调试日志。启用后需同时开启napi-derive-backend/tracing适合在难以用断点排查的 FFI 调用场景下观察每次调用的参数与返回值。3.3.0discriminant_case 与 tsdown 配置修复3.3.0 新增discriminant_casePR #2960允许开发者控制结构化枚举判别字段discriminant在 JS 侧的大小写风格例如将 Rust 的 snake_case 判别字段映射为 camelCase。该配置最终落地为 ast.rs 中NapiStructuredEnum.discriminant_case: OptionCase类型来自convert_casecrate——这也解释了 CHANGELOG 中反复出现的convert_case版本升级记录0.9 → 0.10 → 0.11 → 0.12。3.6.8AsyncTask 完成与 env 销毁的竞态防护3.6.8 修复了 guard AsyncTask completion against env teardownPR #3536当异步任务完成时若宿主环境如 workerd/worker 线程已开始销毁任务完成回调不再尝试访问已失效的napi_env避免悬垂引用导致的崩溃。这与 napi-rs 在 WASI / worker 环境下的 teardown 测试族如 examples/napi/tests/worker-task-teardown.spec.ts是同一主题的运行时与编译期两面。3.3.1Promise 与 ThreadsafeFunction 去 tokio 依赖3.3.1 的 Promise and ThreadsafeFunction::call_async dont require tokioPR #2998属于依赖面收窄这两个 API 不再强制要求宿主 crate 引入 tokio使napi-derive生成的桥接代码在纯 Node-API 线程池场景下也能工作减少不必要的依赖体积。依赖与工具链治理贯穿全版本CHANGELOG 中占比最高的两类条目是依赖升级与工具链修复ctorcrate 从 0.5 一路升级到 1.03.5.5 时 Convert #[ctor] calls to declarative form to remove all featuresPR #32573.5.4 禁用ctor priorityfeature最终在 3.5.6 升到 v1配合module_init/module_exports使用的声明式napi::ctor::declarative::ctor!机制见 lib.rs。convert_case0.9 → 0.12 的升级影响所有涉及命名大小写转换camelCase、snake_case、kebab-case 等的生成逻辑。3.4.1 针对 Rust 1.92.0 的 clippy 修复、3.3.0 的 rust-version 提升、3.2.3 的--features noop链接问题修复保证了不同 Rust 工具链版本下的可编译性。兼容模式compat-mode与旧式宏在compat-modefeature 下lib.rsnapi-derive额外导出 4 个属性宏用于兼容旧版 napi 的写法#[contextless_function]导出一个不依赖调用上下文无this、无参数的 JS 函数生成extern C fn桥接内部通过napi_get_cb_info解包环境。#[js_function]导出一个完整 JS 函数属性参数中声明参数个数arg_len在 x86 Windows 上使用Vec*mut c_void存放参数指针其余平台用固定数组构造CallContext后执行。#[module_exports]生成模块注册逻辑——参数为 1 或 2 个(exports)或(exports, env)通过napi::ctor::declarative::ctor!在加载时调用register_module_exports注册。#[module_init]把函数包装为模块初始化钩子同样基于声明式ctor!。这些宏与 3.5.5 的 ctor 声明式改造一脉相承不再依赖 ctor 的priorityfeature而是用#[ctor(unsafe)]的声明式形式注册减少 feature 面。调试与验证如何观察宏展开napi-derive提供了两个编译期调试手段环境变量NAPI_DEBUG_GENERATED_CODE设置后每次#[napi]展开都会把生成的完整代码println!到 stdoutlib.rs可以直观看到宏为每个函数生成的注册表项、参数转换与返回值转换逻辑。noopfeature构建--features noop可让宏静默展开不生成桥接代码用于隔离宏生成代码与运行时绑定的问题域定位编译错误归属。宏展开失败时错误信息会附带napi macro expand failed.前缀和具体的syn解析诊断如invalid #[napi] attribute、malformed #[napi] attribute、unknown attribute配合strict模式的 unused 属性检查大部分配置错误在编译期即可被精确定位。版本速查表3.1.0 → 3.6.9版本日期关键内容3.6.92026-09-22依赖更新3.6.82026-09-20防护 AsyncTask 完成与 env 销毁竞态3.6.42026-09-10convert_case 升级至 0.123.6.02026-07-21基于 type_tag 的不可伪造类身份3.5.62026-05-13修复类型别名泛型语法、ctor v13.5.52026-04-28ctor 改为声明式调用3.5.02025-12-30新增#[napi(async_iterator)]3.4.02025-12-02新增tracingfeature3.3.02025-10-24新增discriminant_case3.3.12025-11-07Promise/ThreadsafeFunction 不再依赖 tokio3.2.02025-08-07新增ScopeGenerator生成器迭代化3.1.02025-07-21新增ScopedTask从这张表可以看到napi-derive的演进脉络一方面持续收窄与收紧依赖面ctor、convert_case、tokio另一方面围绕类身份安全type_tag、异步协议async_iterator、ScopeGenerator、ScopedTask、类型生成质量ts 覆盖属性、tracing 调试三条主线稳步增加能力。对于使用 napi-rs 的开发者而言跟进napi-derive的升级意味着同时获得更安全的运行时行为3.6.8 的 teardown 防护、更精确的 TS 类型输出3.5.6 的泛型修复以及更灵活的 JS 协议支持3.5.0 的异步迭代器。进一步阅读crates/macro/src/lib.rsnapi属性宏入口与 compat-mode 宏实现crates/macro/src/parser/attrs.rs全部#[napi]属性解析器与 strict 检查crates/macro/src/expand/napi.rs模块模式展开与命名空间注入crates/backend/src/ast.rs桥接 AST 模型与类型标签语义crates/backend/src/codegen桥接代码生成器const/enum/fn/struct/typecrates/backend/src/typegenTypeScript 类型定义生成器crates/macro/CHANGELOG.md完整的版本演进记录examples/napi/src宏各能力对应的可运行示例类、枚举、异步、类型标签、迭代器等examples/napi-cargo-test 与 examples/napi-compat-mode兼容模式与 cargo 集成测试示例赞分享开发工具后端【免费下载链接】napi-rsA framework for building compiled Node.js add-ons in Rust via Node-API项目地址https://gitcode.com/gh_mirrors/na/napi-rs点击查看免费下载相关推荐深入理解 napi-rs 的 napi-derive 过程宏从 [napi] 到 Node.js 原生模块的编译期桥梁深入理解 napi rs 的 napi derive 过程宏从 napi 到 Node.js 原生模块的编译期桥梁 napi derive 是 napi rs开发工具后端napi-rs/cli 全解析从版本演进看 napi-rs 的 Node-API 工程化实践napi rs/cli 全解析从版本演进看 napi rs 的 Node API 工程化实践 napi rs/cli 是 napi rs 生态的命令行工具开发工具后端napi-rs 开发指南从构建、测试到 [napi] 宏与类型生成的完整实践napi rs 开发指南从构建、测试到 napi 宏与类型生成的完整实践 本文是 napi rs 仓库的开发者导航指南。napi rs 是一个基于 Node开发工具后端上一篇告别回家摸黑Home Assistant移动端应用让智能家居控制触手可及下一篇V8 Debug Helper 深度指南用 GDB/LLDB 插件事后剖析 V8 对象与 JavaScript 帧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考