LoginSignup
34
22

More than 5 years have passed since last update.

RustでNode.jsのモジュールを作りElectronで利用する

Posted at

Rustを使ってNode.jsのモジュールを作る方法について書きます。
Neonを使います。

Electronを使ってデータの可視化アプリを作りたいと思って実装中なのですが、データの読み込み時にすでに書いてあるRustのプログラムを流用したいなーということで方法を探していたら、下の記事を見つけました。

Rust と Electron で GUI アプリケーションを作る

RustをElectronアプリケーションに組み込む方法がいくつか紹介されているのですが、この中で、Neonを使ったNative Addonの作成をやってみたので、その手順をメモとして残します。

ElectronとNeonの環境構築

まずはelectron-quick-startのリポジトリをそのままクローンしてきます。
Electronの公式に従って、

$ git clone https://github.com/electron/electron-quick-start
$ cd electron-quick-start
$ npm install && npm start

これでHello, Worldが表示されたElectronアプリケーションが起動することを確認します。

アプリケーションを終了し、次はNeonを用いた開発に必要なものをいれます。
NeonのBUILDING ELECTRON APPSに従って、

$ vi package.json # devDependenciesに2つを追加
"devDependencies": {
    ...
    "electron-build-env": "^0.2",
    "neon-cli": "^0.1.17"
}

そして、パッケージをいれます。

$ npm install

Rustを用いたモジュール作成

Rustでモジュールを作っていきます。
今回は、NeonのGitHubのREADMEにある、make_an_arrayを追加していきます。

$ cd node_modules
$ neon new make-an-array # いろいろ聞かれますが全部Enterで

すると、以下のような構造が生成されます。

make-an-array/
├── .gitignore
├── README.md
├── lib/
│   └── index.js
├── native/
│   ├── Cargo.toml
│   ├── build.rs
│   └── src/
│       └── lib.rs
└── package.json

lib.rsとindex.jsを編集します。

lib.rs
#[macro_use]
extern crate neon;

use neon::vm::{Call, JsResult};
use neon::js::{Object, JsArray, JsInteger, JsNumber, JsObject};
use neon::mem::Handle;

fn make_an_array(call: Call) -> JsResult<JsArray> {
    let scope = call.scope; // the current scope for rooting handles
    let array: Handle<JsArray> = JsArray::new(scope, 3);
    try!(array.set(0, JsInteger::new(scope, 9000)));
    try!(array.set(1, JsObject::new(scope)));
    try!(array.set(2, JsNumber::new(scope, 3.14159)));
    Ok(array)
}

register_module!(m, {
    m.export("make_an_array", make_an_array)
});
index.js
var addon = require('../native');

exports.make_an_array = addon.make_an_array;

lib.rsにモジュールに追加したい関数を書いて、それをindex.jsでエクスポートします。

次に、electron-quick-start以下に戻り、packege.jsonにビルド用スクリプトを追加します。

$ vi package.json # scriptsにbuildを追加
"scripts": {
    "build": "electron-build-env neon build make-an-array",
    ...
}

最後に、Electronアプリケーションから作ったモジュールを使用するコードを書きます。
今回は短いので、index.htmlのscriptタグ間に挟んでおきます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    <!-- All of the Node.js APIs are available in this renderer process. -->
    We are using Node.js <script>document.write(process.versions.node)</script>,
    Chromium <script>document.write(process.versions.chrome)</script>,
    and Electron <script>document.write(process.versions.electron)</script>.
  </body>

  <script>
   // You can also require other files to run in this process
    console.log(require('make-an-array').make_an_array());
    require('./renderer.js');
  </script>
</html>

それでは、モジュールをビルドし、アプリケーションを実行します。

$ npm run build
$ npm start

ディベロッパーツールを開いて、Arrayがコンソールに出力されていることを確認してください。
無事、作成したモジュールを利用することができました。

JsArrayが使えなくて詰まった

ちなみに私はmake_an_arrayをREADMEからコピペしたあと、必要なモジュールがわからず少しつまりました。
JsArrayのsetがどうしたら使えるのかわからなかったのです。

調べたところ、GitHubにissueがありました。
https://github.com/neon-bindings/neon/issues/57#issuecomment-310842980
neon::js::Objectを入れて、neon::js::Keyを入れないようにしないといけないみたいです。neon::js::Objectを入れないと、arrayにsetがないよと言われるのですが、そのときに、neon::js::Keyを入れたらいいのではないですか?とコンパイラに言われるので、入れてみたら引っかかるという罠でした。

34
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
22