创建您的第一个节点

当工作流部署时,节点被创建。在工作流运行期间,它们可能会发送和接收一些消息,并且在下一次工作流部署时,它们会被删除。

它们由一对文件组成

  • 一个定义节点功能的 JavaScript 文件,
  • 一个定义节点属性、编辑对话框和帮助文本的 HTML 文件。

一个 package.json 文件用于将其打包成一个 npm 模块。

创建一个简单的节点

本示例将展示如何创建一个将消息有效负载转换为全小写字符的节点。

请确保您的系统上已安装 Node.js 的当前 LTS 版本。在撰写本文时,版本为 10.x。

创建一个您将用于开发代码的目录。在该目录中,创建以下文件

  • package.json
  • lower-case.js
  • lower-case.html

package.json

这是 Node.js 模块用来描述其内容的标准文件。

要生成一个标准的 package.json 文件,您可以使用命令 npm init。它会提出一系列问题来帮助创建文件的初始内容,并尽可能使用合理的默认值。当提示时,请将其命名为 node-red-contrib-example-lower-case

生成后,您必须添加一个 node-red 部分

{
    "name" : "node-red-contrib-example-lower-case",
    ...
    "node-red" : {
        "nodes": {
            "lower-case": "lower-case.js"
        }
    }
}

这告诉运行时该模块包含哪些节点文件。

有关如何打包节点的更多信息,包括命名要求以及在发布节点前应设置的其他属性,请参阅打包指南

注意:请不要将此示例节点发布到 npm!

lower-case.js

module.exports = function(RED) {
    function LowerCaseNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        node.on('input', function(msg) {
            msg.payload = msg.payload.toLowerCase();
            node.send(msg);
        });
    }
    RED.nodes.registerType("lower-case",LowerCaseNode);
}

节点被包装为一个 Node.js 模块。该模块导出一个函数,当运行时在启动时加载该节点时会调用此函数。该函数被调用时带有一个参数 RED,它为模块提供了对 Node-RED 运行时 API 的访问权限。

节点本身由一个函数 LowerCaseNode 定义,每当创建节点的新实例时都会调用该函数。它会接收一个包含在流编辑器中设置的节点特定属性的对象。

该函数调用 RED.nodes.createNode 函数来初始化所有节点共享的特性。之后,就是节点特定的代码。

在这个实例中,该节点为 input 事件注册了一个监听器,每当有消息到达该节点时就会调用它。在此监听器中,它将有效负载更改为小写,然后调用 send 函数将消息在流中传递下去。

最后,使用节点的名称 lower-caseLowerCaseNode 函数注册到运行时。

如果节点有任何外部模块依赖项,它们必须包含在其 package.json 文件的 dependencies 部分中。

关于节点运行时部分的更多信息,请参见这里

lower-case.html

<script type="text/javascript">
    RED.nodes.registerType('lower-case',{
        category: 'function',
        color: '#a6bbcf',
        defaults: {
            name: {value:""}
        },
        inputs: 1,
        outputs: 1,
        icon: "file.svg",
        label: function() {
            return this.name||"lower-case";
        }
    });
</script>

<script type="text/html" data-template-name="lower-case">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
</script>

<script type="text/html" data-help-name="lower-case">
    <p>A simple node that converts the message payloads into all lower-case characters</p>
</script>

节点的 HTML 文件提供以下内容

  • 在编辑器中注册的主节点定义
  • 编辑模板
  • 帮助文本

在本例中,节点只有一个可编辑的属性 name。虽然不是必需的,但有一个广泛使用的惯例,即使用此属性来帮助区分单个流中节点的多个实例。

关于节点编辑器部分的更多信息,请参见这里

在 Node-RED 中测试您的节点

一旦您按照上述描述创建了一个基本的节点模块,您就可以将其安装到您的 Node-RED 运行时中。

要本地测试节点模块,可以使用 npm install <folder> 命令。这允许您在本地目录中开发节点,并在开发过程中将其链接到本地的 Node-RED 安装中。

在您的 Node-RED 用户目录(通常是 ~/.node-red)中,运行

npm install <location of node module>

例如,在 Mac OS 或 Linux 上,如果您的节点位于 ~/dev/node-red-contrib-example-lower-case,您需要执行以下操作

cd ~/.node-red
npm install ~/dev/node-red-contrib-example-lower-case

在 Windows 上,您需要执行

cd C:\Users\my_name\.node_red
npm install C:\Users\my_name\Documents\GitHub\node-red-contrib-example-lower-case

这会在 ~/.node-red/node_modules 中创建一个指向您的节点模块项目目录的符号链接,这样 Node-RED 启动时就会发现该节点。对节点文件的任何更改都可以通过简单地重启 Node-RED 来生效。在 Windows 上,同样,使用 npm 5.x 或更高版本

注意npm 会自动在您用户目录下的 package.json 文件中为您的模块添加一个条目。如果您不希望它这样做,请在 npm install 命令中使用 --no-save 选项。

单元测试

为了支持单元测试,可以使用一个名为 node-red-node-test-helper 的 npm 模块。这个测试助手是一个基于 Node-RED 运行时构建的框架,旨在简化节点测试。

使用这个框架,您可以创建测试流,然后断言您的节点属性和输出是否按预期工作。例如,要为 lower-case 节点添加单元测试,您可以在您的节点模块包中添加一个 test 文件夹,其中包含一个名为 _spec.js 的文件

test/lower-case_spec.js

var helper = require("node-red-node-test-helper");
var lowerNode = require("../lower-case.js");

describe('lower-case Node', function () {

  afterEach(function () {
    helper.unload();
  });

  it('should be loaded', function (done) {
    var flow = [{ id: "n1", type: "lower-case", name: "test name" }];
    helper.load(lowerNode, flow, function () {
      var n1 = helper.getNode("n1");
      n1.should.have.property('name', 'test name');
      done();
    });
  });

  it('should make payload lower case', function (done) {
    var flow = [{ id: "n1", type: "lower-case", name: "test name",wires:[["n2"]] },
    { id: "n2", type: "helper" }];
    helper.load(lowerNode, flow, function () {
      var n2 = helper.getNode("n2");
      var n1 = helper.getNode("n1");
      n2.on("input", function (msg) {
        msg.should.have.property('payload', 'uppercase');
        done();
      });
      n1.receive({ payload: "UpperCase" });
    });
  });
});

这些测试检查节点是否正确加载到运行时中,以及它是否按预期将有效负载正确转换为小写。

两个测试都使用 helper.load 将节点加载到运行时中,提供待测节点和一个测试流。第一个测试检查运行时的节点是否具有正确的 name 属性。第二个测试使用一个辅助节点来检查节点的输出是否确实是小写。

该辅助模块包含取自 Node-RED 核心节点的其他测试示例。有关该辅助模块的更多信息,请参阅相关的 README 文件。