はじめに
node-redのカスタムノードを開発の際、実行時にJavascriptに何かエラーがあっても、下のようななんとも簡素なメッセージしか表示されません。これだけでは規模の大きいカスタムノードのデバッグは無理です。
node-red側: [node-red-contrib-linking-device/linking-device] SyntaxError: Unexpected token .
ブラウザ側:SyntaxError: Undefined variable
ということで、整えたデバッグ環境について以下に説明します。
ESLintで事前にシンタックスチェックを行う
node-redのカスタムノードプログラミングでは、Nodejs用Javascriptと、htmlファイル内のJavascriptが混在するのが特徴で、ESLinの設定にひと手間必要です。
ESLintのインストール
eslintと、htmlファイル内scriptをチェックするプラグイン: eslint-plugin-htmlをnpmインストール。また、ローカライズ用のjsonファイルをチェックするeslint-plugin-jsonもインストール。
npm i --save-dev eslint
npm i --save-dev eslint-plugin-html
npm i --save-dev eslint-plugin-json
ESLint設定ファイル作成
ES2017で書くNodejs用の設定
{
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2017
},
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"no-console": "off",
"no-unused-vars": [2, {
"args": "after-used",
"argsIgnorePattern": "^_" }]
},
"plugins": [
"json"
]
}
htmlファイル内のscript用設定
{
"env": {
"browser": true,
"jquery": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"off"
],
"semi": [
"error",
"always"
],
"no-console": "off",
"no-unused-vars": [2, {
"args": "after-used",
"argsIgnorePattern": "^_"
}] },
"globals": {
"RED": false
},
"plugins": [
"html"
]
}
package.jsonにlintスクリプトを追加
ソースコードは プロジェクトフォルダ/src
にある想定です。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint --ext .json --ext .js src || eslint -c .eslintrc.html.json --ext .html src"
},
ESLint実行
npm run lint
これで事前にスクリプトのチェックを行うことが出来ます。
Chrome devtoolsを使ってカスタムノードのNodejsスクリプトをデバッグ
node-red-template-embeddedの用意
Setup a own Node-RED Dev Environment in 5 min. という記事を参考に、node-redをピュアなNodejs実行環境下で動かす node-red-template-embedded を使います。これを使えば、Chrome devtoolsでソースコードデバッグができるようになります。
適当なフォルダにてnode-red-template-embeddedをcloneする
git clone https://github.com/sbarwe/node-red-template-embedded.git
cd node-red-template-embedded
commitはしない前提で、node-red-template-embeddedの内容をいじります。
デバッグしたいカスタムノードをnpm link
node-red-template-embeddedのフォルダから npm link node-red-contrib-mynode
します。
package.jsonをいじる
本来は、これでnpm i && npm run debugすればいいのですが、node-red-template-embeddedは若干古く、最近のnodejsでは動きません。
以下のように、package.jsonのscript中の"debug"を変更、また"dev"を追加します。
"scripts": {
:
"debug": "cross-env NODE_ENV=development \"nodemon --config .nodemonrc.json --inspect src/server.js\"",
"dev": "NODE_ENV=development node --inspect=0.0.0.0:9929 src/server.js"
},
Raspberry Pi固有の設定 (結局は不要)
Raspberry Piで npm run debug
を行ったところ、以下のエラーが出ました
[nodemon] Internal watch failed: watch /home/pi/git/node-red-template-embedded/node_modules/rc/node_modules/minimist/test/dotted.js ENOSPC
[nodemon] exiting
エラーを起こしているnodemonは、ソースファイルの変更を検知してデバッグ対象のプログラムを再起動してくれるのですが、監視ファイル数が多すぎてエラーになっている模様。
調べたところ、Raspberry Piでは監視ファイル最大数がデフォルトでは8192と少なかったので4倍にしました。
echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
Chromeのdevtoolsでリモート接続できない
npm run debug でnode-redを立ち上げた後は、Chromeのdevtoolsで接続してデバッグすればいいのですが、上記設定では原則同じマシン上での接続となります。--inspect を --inspect=0.0.0.0:9229 と指定すればリモートから接続できるはずなのですがだめ。
どうやら、nodemonでは無効なようです。まあもともとセキュリティー上推奨しないとNodejsのドキュメントに書いてあるのでしょうがないですね(sshトンネルでのリモート接続が推奨されてます。でも家庭内LANなのでめんどくさい)。
ということで、Raspberry Piをリモートデバッグする為に、nodemonを使わずnodeを --inspect=0.0.0.0:9929 つきで直接起動するスクリプトdevを追加しています。npm run devでnode-redをリモートデバッグできるようになります。
Chromeのdevtoolsでブレークポイント設定が出来ない
PC上のChrome devtoolsで接続し、ブレークポイントを設定しようとしたらどうも機能しない。
最初はRaspberry pi3が32bit OSだからこんなものなのかと思ったのですが、Chrome66以降の不具合とのこと:
回避策が書いてありますが、devtoolsのChrome拡張 NIM をインストールします。これは勝手にdevtoolsが立ち上がって便利。
参考:node --inspectの chrome-devtools://... コピペを自動化するChrome拡張を使う
これでようやくデバッグの環境が整いました。
デバッグの手順
-
node-red-stop
を実行し、通常のnode-redは止めておく - chromeで
NIM
を実行し(window内右上の緑のアイコン)、デバッグターゲットのIPアドレスとポート(9229)を設定 - カスタムノードのjsやhtmlファイルをエディット
- custom node開発側で、
npm run lint
してシンタックスエラーをチェック・修正 - node-red-template-embedded 側でnpm run dev (もしくはnpm run debug)してnode-red起動
- Chromeブラウザで
http://<ターゲットのIPアドレス>:1880/admin/
(URLに注意) を開いて、カスタムノードをテストする。UI側もnodejs側も、Chrome devtoolsを使って便利にデバッグできます。 - バグの調査が完了したら、
npm run dev
を実行中のコンソールでCtrl+Cを2回押してnode-redをとめる - 手順3に戻る
手順5で、npm run debugを使える場合は、7, 8は不要です。
なお、6では単にリロードボタンを押すのではなく、上記URLを再読み込みする必要があります。そうしないと、カスタムノードのhtmlファイルの内容が更新されないようでした。