Node-REDのfunctionノードをフローライブラリに登録できるオリジナルノードに変換してみよう

　こんにちは、(株)日立製作所 研究開発グループ サービスコンピューティング研究部の横井一仁です。

　本ドキュメントでは、ノード開発容易化ツール[「Node generator」](https://github.com/node-red/node-red-nodegen/wiki/Japanese)の使い方をご紹介します。[前の記事](https://qiita.com/kazuhitoyokoi/items/934e8babbb5ed467f660)で紹介した画像認識を行うNode-REDのfunctionノードを、共有可能なオリジナルノードに変換してみます。

![imagerecognition2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/177b512b-9c0b-b09b-39e0-43cb8d63d8e2.png)

# Node generatorとは

　Node generatorとは、Node-REDのオリジナルノードを自動生成するコマンドラインツールです。

　JavaScriptコードを書いたfunctionノードを共有可能なオリジナルノードに変換したり、Swagger Codegenの様に[OpenAPIドキュメント(Swagger)](https://qiita.com/disc99/items/37228f5d687ad2969aa2)からノードのソースコードを生成したりできます。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/c667866f-5d65-5520-310d-bdeeef40f74e.png' width='454px' height='300px'>

　[日立が開発し、OSS化した](https://businessnetwork.jp/tabid/65/artid/5598/page/1/Default.aspx)本ツールは、現在[OpenJS Foundation (Linux Foundation)](https://openjsf.org)管理下のNode-RED公式のサブプロジェクトとなっており、開発コミュニティと協力して機能拡張が行われているOSSになっています。

　本ツールは下記サイトで紹介されている様に、CiscoやIBMなどのNode-RED活用企業でも活用されています。

- Ciscoでの活用例: https://developer.cisco.com/meraki/meraki-dashboard-api-node-red-node/
- IBM USでの活用例: https://developer.ibm.com/tutorials/use-node-red-node-generator-to-create-new-nodes-from-apis-and-services/

# functionノードからオリジナルノードを生成

　本ドキュメントで用いた動作環境は、Node-REDをインストール済のWindows環境です。Node generatorはmacOSやLinuxにも対応していますので、その場合は適宜ファイルパス等を変更して試してみてください。

## (1) functionノードのコードをライブラリに書き出す

　まず、functionノードのJavaScriptコードをファイルとして書き出す操作を行います。

　本操作は、functionノードのノードプロパティ上にある本のマークのボタンをクリックし、「ライブラリへ保存」を選択すればOKです。ライブラリにコードを書き出すと、Node-REDのホームディレクトリの下の「lib¥functions」ディレクトリ(Windowsの場合は「C:¥Users¥<ユーザ名>¥.node-red¥lib¥functions」)にJavaScriptのコードが入ったファイルが書き出されます。

## (2) Node generatorをインストール

　管理者モードでコマンドプロンプトを起動し、ビルドツール(Windowsの場合のみ)とNode generatorをインストールします。

```shell
npm install -g node-red-nodegen
npm install -g windows-build-tools    （Windowsの場合のみ）
```

## (3) 管理者モードのコマンドプロンプトを閉じる

## (4) コマンドプロンプトを開き、ホームディレクトリへ移動

　ユーザモードでコマンドプロンプトを開き直し、cdコマンドを実行してホームディレクトリに移動します。

```shell
cd
```

## (4) functionノードのJavaScriptコードからノードを生成

　Node generatorを用いてfunctionノードのJavaScriptコードからノードを生成します。

```shell
node-red-nodegen .node-red¥lib¥functions¥image-segmenter.js
```

　以上でノードの作成ができました。カレントディレクトリ内にnode-red-contrib-image-segmenterディレクトリが生成されているはずです。このディレクトリの中には、以降の手順で編集するpackage.json(モジュールの情報が記載されているファイル)とnode.js(Node-REDランタイムで実行されるノードのソースコードファイル)が含まれています。

　次にこのノードをNode-REDから呼び出せるように設定してみます。

## (5) 生成されたディレクトリに移動

```shell
cd node-red-contrib-image-segmenter
```

　今回は、外部モジュールを利用しているため、追加で下記(5-A)(5-B)の手順も行います(functionノードが外部のnpmモジュールを使っていない場合は(5-A)(5-B)の手順はスキップしてください)。

### (5-A) package.jsonファイルに依存関係を追加（17行目付近）

```javascript
  "keywords": [
    "node-red-nodegen"
  ],
  "dependencies": {     <- 依存関係を追加
    "@codait/max-image-segmenter": "0.1.4"  <- 依存関係を追加
  },                    <- 依存関係を追加
  "devDependencies": {
    "node-red": "0.18.7",
```

### (5-B) node.jsファイルに定義を追加（206行目付近）

```javascript
        }
        sandbox.global.set("imageSegmenter", require('@codait/max-image-segmenter'));  <- vm.createContext()の前に定義を追加
        var context = vm.createContext(sandbox);
        try {
            this.script = vm.createScript(functionText, {
```

## (6) 依存モジュールのインストール、シンボリック作成の準備

```shell
npm link
```

## (7) Node-REDのホームディレクトリに移動

```shell
cd
cd .node-red
```

## (8) シンボリックリンク作成

```shell
npm link node-red-contrib-image-segmenter
```

## (9) Node-REDを起動

　node-redコマンドを用いてNode-REDを起動します。もし起動中の場合はCtrl+cで終了してから再度Node-REDを起動し直してください。

```shell
node-red
```

　Node-REDフローエディタ( http://<Node-REDのIPアドレス>:<ポート番号> )にアクセスすると、機能カテゴリの中に青色のimage-segmenterノードが登場しているはずです。

　本ノードは、書き出し元のfunctionノードと同様に、前に[node-red-contrib-browser-utilsモジュール](https://flows.nodered.org/node/node-red-contrib-browser-utils)のfile injectノード、後ろにdebugノードをつなぐことで、画像認識を行うことができます。

![generatednode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/ce4f6514-8dd2-bd7f-0197-486f34cfeda8.png)

# 最後に

　Node-REDは、非エンジニアでも開発できるビジュアルプログラミングツールであるため、コーディングの能力が必要となるfunctionノードを多用するとNode-REDの良さが薄れてしまいます。Node generatorを用いて、functionノードを再配布可能なノードに変換し、フローライブラリに登録することで、非エンジニアの方も再利用ができる様になるでしょう。

　Node generatorの使い方については、詳細の日本語ドキュメントも公開していますので、ぜひ見てみてください。

- Node generatorのドキュメント: https://github.com/node-red/node-red-nodegen/wiki/Japanese