要約
Embedde Node-REDのユーザディレクトリは絶対パスで指定しましょう。
Headless Node-REDが欲しい
Node-REDの実行時にはエディタ等のWeb UIは不要なのでいわゆるHeadlessなモードが欲しかった。軽く調べたところ、httpAdminRootにnullを設定するというのが見つかったが、Webサーバ自体は起動してしまうようなので求めているものとは違った。
Embedded Node-RED
Node-REDのソースを眺めていると、initの第1引数にnullを指定してWebサーバを渡さないことを想定しているような書き方だった。なので以下のガイドを参考にHeadlessなEmbedded Node-REDを作ることにした。
とは言え作るのは簡単である。通常のNode-REDでフローを開発し、そのユーザディレクトリ(./user)をそのまま指定して動かすことを想定している。なお、disableEditorをtrueにしないとエラーが発生して起動しない。
const RED = require('node-red');
const settings = {
userDir: './user',
flowFile: 'flows.json',
disableEditor: true
}
RED.init(null, settings);
RED.start().then(
() => {
console.log('embedded Node-RED is started!');
}
);
カスタムノードモジュール
しかしながら、Node-REDのWebコンソールからインストールしたカスタムノードを使用したフローをheadless.jsで動かそうするとノードが見つからず、エラーになってしまう。
embedded Node-RED is started!
...
17 Nov 12:56:54 - [info] Waiting for missing types to be registered:
17 Nov 12:56:54 - [info] - calculator
カスタムノードはユーザディレクトリのnode_modules配下に確かに存在しているはずなのに。
ユーザディレクトリの指定方法
ググってみたところ、Embedded Node-REDのユーザディレクトリを相対パス指定すると、node_modules配下のカスタムモジュールがロードされないという情報を発見。
https://stackoverflow.com/questions/54494327/node-red-custom-node-modules-location
これをそのまま丸パクリすることで解決することができた。
const RED = require('node-red');
const path = require('path');
const current = path.dirname(__filename);
const settings = {
userDir: current + '/user',
flowFile: 'flows.json',
disableEditor: true
}
RED.init(null, settings);
RED.start().then(
() => {
console.log('embedded Node-RED is started!');
}
);