大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。
Neon 是一个库和工具链,用于将 Rust 嵌入到 Node.js 应用程序和库中。从而用于编写安全、快速的原生 Node.js 模块的 Rust 绑定。
使用 Neon,开发者可以像在 C 或 C++ 中一样创建本机 Node 模块,但不会遇到与不安全系统编程相关的一系列问题。 在 Node 中嵌入 Rust 很有用,原因有很多,例如:
Neon 还努力使创建本机模块变得容易,它具有方便的命令行界面和围绕合理的项目约定构建的工作流程。 这消除了构建本机 Node 模块的许多常见麻烦。
目前 Neon 在 Github 上通过 Apache-2.0 协议开源,有超过 7.5k 的 star,是一个值得关注的前端开源项目。
接下来将带着大家设置系统以构建 Neon 项目,从一个简单的 Hello, World! 着手。
Neon 需要 Node.js 并支持最新的 Node 版本和所有 LTS 版本。如果尚未安装 Node.js,或者没有受支持的版本,请访问 Node.js 网站以获取安装说明。
Neon 需要 Rust 来进行开发。 如果尚未安装 Rust,或者没有受支持的版本,请访问 Rust 网站以获取安装说明。
Rust 可能有其他依赖项,具体取决于目标平台(例如 Windows 上的 Visual Studio)。
下面的示例项目是一个返回当前设备中处理器数量的模块。 如果不熟悉处理器和 CPU 等系统概念,请不要惊慌! 可以使用 num_cpus 来完成所有繁重的工作,并且只返回它给我们的数字。
该教程很短,但它展示了 Neon 的一些强大功能:Rust 的 crate 生态正在快速发展,充满了许多有用且独特的库,通常提供在 npm 中很难找到的底层功能或高性能数据结构。
像 num_cpus 这样的库可能很有用,例如,作为调整 Electron 应用程序中 Web Worker 池大小的提示。
接下来要做的第一件事是创建新的 cpu-count Neon 项目:
npm init neon cpu-count
该命令将询问一系列类似于 npm init 的问题。完成后,该工具将创建一个具有以下布局的 cpu-count 目录:
cpu-count/├── Cargo.toml├── README.md├── package.json└── src └── lib.rs
首先要注意的是 Neon 项目既是 Node 包,又是 Rust crate。Rust 源代码位于 src/ 中,但增强 Rust 的 JavaScript 可以并存。
与调整 Babel 以定位最低 JavaScript 版本类似,Neon 可以通过调整 Cargo.toml 中的 napi 功能来定位 Node 版本。 默认情况下,npm init neon 将使用当前安装的 Node 版本。
[dependencies.neon];features = ['napi-6'];
目前为止,还没有实现任何程序,只是为了看看 npm init neon 生成了一个完整的、最小的 Neon 项目。接下来尝试构建它:
cd cpu-countnpm install
构建过程会生成一些文件:
清理构建工件的一个简单方法是运行:
cargo clean
一旦构建了项目,就可以尝试运行它:
node> require('.').hello()hello node
接下来添加对 num_cpus crate 的 Rust 依赖。在 Cargo.toml 中,添加以下行:
[dependencies];num_cpus = '1';
这告诉 Rust 的构建工具 Cargo 获取与 semver 兼容的 num_cpus 包的版本 1。(package.json 等效项为“num_cpus”:“^1”。)
接下来,可以将 npm init neon 生成的示例 hello 函数替换为实际想要的函数。函数应该返回一个 JavaScript 数字,而不是返回一个字符串。 所以将使用 cx.number() 工具函数。
由于 cx.number() 需要 Rust f64(即 64 位浮点数),并且 num_cpus::get() 返回 usize(即指针大小的整数),因此将使用 Rust 的 sas 运算符将整数转换为浮点数:
use neon::prelude::*;fn get_num_cpus(mut cx: FunctionContext) -> JsResult<JsNumber> { Ok(cx.number(num_cpus::get() as f64))}
关于此代码还有一些需要注意的事项:
最后,修改 npm init neon 创建的代码,以使用此函数设置模块导出,而不是初始“hello world”函数:
#[neon::main]fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("get", get_num_cpus)?; Ok(())}
这告诉 Neon 在第一次加载模块时通过创建一个使用上面定义的 get_num_cpus 函数实现的 JavaScript 函数来初始化模块,并将其导出为名为“get”的模块属性。
首先需要 build:
npm run build -- --release
该命令将创建一个发布版本, 发布版本的编译时间较长,但最终库的执行速度更快。 假设没有犯任何错误,可以在项目目录根目录的 Node 控制台上测试新的 Neon 模块:
node> const cpuCount = require('.')> cpuCount.get()4
https://github.com/neon-bindings/neon