前言
最近工作接觸到 Node-RED,需要建立專屬的 Node,而在這過程中遇到蠻多坑的,所以特別紀錄一下。
相關技術
坑坑相連
1. Node-RED docker version & Node.js version
問題點
沒有先確認官方 Node-RED docker 所內含的 Node.js 版本,導致所建立的 node 無法在官方 Node-RED docker 中運行。
說明
目前官方所提供的 Node-RED docker 中, 並沒有提供內建 Node.js 10.x 版本 (目前最高只提供到 Node.js 8.x),而我的開發環境是使用 Node.js 10.11.0 版本,更不巧的是我又用到 Node.js 10.11.0 才有的 N-API functions,因此導致 node 在運行時直接出現 segmentation fault Error 訊息。
解決辦法
不要直接使用官方所提供的 Node-RED docker,而是使用 arm32v7/node:10.11.0-stretch
作為 base image,然後另外建一個 Node.js 10.11.0 版本的 Node-RED image。不過這樣做的缺點是,arm32v7/node:10.11.0-stretch 的 image size 超肥,需要在建立 image 過程中刪除一些非必要的檔案,才能讓 image size 維持在要求大小之內。
2. Node-RED Node compile to ARM architecture
問題點
node-gyp 是一個 cross-platform command-line tool,不過要記得下 --arch
option,才能編成正確的 node。
說明
我們會運行 Node-RED 的平台架構為 arm32
,其中又需要使用到 C (N-API) 去對接我方 C lib,所以 Node 中就包含 C code,結果一時忘記 C 在 compile 時需要對應到不同的平台,導致 Node 又無法正確運行啦~只能說這真的是太粗心犯的錯誤,平常只 compile C 會記得確認 cross-compile 問題,現在只是結合 Node.js 就熊熊忘記了。
解決辦法
node-gyp --arch arm configure build
順便說明一下,目前支援的 architecture 包含 arm
, arm64
, ia32
, mips
, mipsel
, ppc
, ppc64
, s390
, s390x
, x32
, and x64
。可參見 Node.js process_arch
3. Create a dynamic select options
問題點
由於 Node html 輸入欄位 (input, select..etc) 的附值由 Node-RED 所操控,所以當透過 async 方式從 server 取得資料,並且動態增減 select option 欄位時,會需要透過額外的手段來設定值。
說明
如果想要讓使用者可以編輯 Node-RED Node 的 Property,我們在編寫 html 時需要遵照 Node-RED 規則,將 html 輸入欄位設定為 node-input-<propertyname>
,例如 node-input-tag
,如此一來, Node-RED 會自動將該 property 當前的值放入對應的欄位中。
For each of the properties in the defaults array, it looks for an
<input>
element with an id set tonode-input-<propertyname>
. This input is then automatically populated with the current value of the property. When the edit dialog is okayed, the property takes whatever value is in the input.

不過如此一來會發生問題,因為 selection options 是透過 async 的方式建立,所以當 Node-RED 在附值給 select 的時候,options 還沒有建立,因此就無法正確地選取到 option。
解決方式
利用其他欄位來記錄當前值,然後在建立出 options 後,再給 select 附上正確的值。
- 先建立兩個欄位
1<select type="text" id="node-input-example">
2<input type="text" id="node-input-example-select">
- 透過 Jquery 來抓取
node-input-example
的值
1const value = $("node-input-example").val();
- 當使用 async 方式將 options 建立完之後,重新附值。
1$("node-input-example-select").val(value);
雖然流程很簡單,不過因為不太熟 Node-RED 流程,所以花了一些時間來查看原因。
結論
雖然寫 WEB 寫一段時間,不過換寫其他平台用的 Plugin,卻還是需要花時間來知道整個 APP 的流程和建立方式,尤其 Node-RED 還是使用 JQuery,對於用久 Frameworok 的我來說還真有點不太習慣。總而言之,透過這次專案,大概了解 Node-RED 該如何寫啦,也算是一個不錯的學習。