Neonは、Rustを使用してネイティブNodeモジュールを作成できるようにするライブラリおよびツールチェーンである。これは、CおよびC++でできることと似ているが、Rustの安全性の保証が追加されるという利点がある。
Neonは、Node.jsモジュールの作成を簡単にするよう努めている。npmとRustツールチェーンからNeonパッケージをインストールし、neon new <project-name>
を使用して、Cargo.toml
ファイルとサンプルのhello
関数を含むRustソースファイルを埋め込むスケルトンノードモジュールを作成できる。
<project-name>/
├── .git ignore
├── README.md
├── lib/
│ └── index.js
├── native/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
└── package.json
必要なRust依存関係をCargo.toml
に追加し、必要に応じてコードをレイアウトできる。Rust関数をエクスポートして、Nodeプログラムで2つのステップで使用できるようにすることができる。まず、以下を使用して関数を登録する:
register_module!(mut m, {
m.export_function("myFunction", thread_count)
});
次に、lib/index.js
によりエクスポートする:
const addon = require('../native');
module.exports = addon.myFunction;
コードの準備ができたら、次を使用してNodeモジュールをビルドする:
neon build --release
これは簡単に見えるが、とにかくNode環境では善良な市民として行動することに特別な注意を払う必要がある。特に、エクスポートするRust関数は特定のタイプである必要がある:
fn add1(mut cx: FunctionContext) -> JsResult<JsNumber> {
...
}
ここで、FunctionContext
を使用すると、arguments
リストを含むノード呼び出し元環境にアクセスできる。同様に、エクスポートされた関数はJsResult
を返す必要がある。これは、関数が特定の型を返すか、JavaScript例外をスローすることを指定するオプション型である。たとえば、次の構文を使用して特定の引数にアクセスできる:
let x = cx.argument::<JsNumber>(0)?.value();
エクスポートされた関数から値を返すには、期待値を適切にキャストする必要がある。たとえば、関数が数値を返す場合、それを返すときにRustのas f64
キャスト演算子を使用する:
Ok(cx.number(num_cpus::get() as f64))
ネイティブNodeモジュールを構築する利点の中には、非同期のバックグラウンドタスクの実行を可能にできることがある。Neonは、その目的のためにN-APIのマイクロタスクAPIを使用し、非同期タスクの実行を制御するためにJavaScript側のコールバックとPromiseに依存している。
最後に、NeonはElectronアプリでも使用できる。これには、現時点では、Electronアプリで使用されるNeon依存関係を構築するために、中間ツールであるelectron-build-env
を使用する必要がある。Neonチームは、electron-rebuild
のサポートに取り組んでいる。これにより、プロセスが簡素になり、Electronプロジェクトの他の依存関係と同じようにNeon依存関係を使用できるようになる。