打包

节点可以打包为模块并发布到 npm 存储库。这使得它们以及它们可能具有的任何依赖项都易于安装。

命名

我们于 2022 年 1 月 31 日更新了命名要求。以下内容适用于在该日期之后首次发布的模块。

包应使用限定范围的名称 - 例如 @myScope/node-red-sample 这可以在用户范围或组织范围下。

在范围名称下发布的节点对其名称没有进一步的要求。他们可以使用 OR JUST - 尽管名称中包含确实有助于将模块与项目相关联:@myScope/node-red-sample @myScope/sample node-red

如果要分叉现有包以提供修复,则可以保留相同的名称,但在自己的范围内发布。但请记住,如果原始维护者不回应您的贡献,则 fork 应该始终是最后的手段。

目录结构

以下是 node 包的典型目录结构:

1
2
3
4
5
6
7
8
9
10
11
├── LICENSE
├── README.md
├── package.json
├── examples
│   ├── example-1.json
│   └── example-2.json
└── sample
├── icons
│   └── my-icon.svg
├── sample.html
└── sample.js

对于包中使用的目录结构没有严格的要求。如果一个包包含多个节点,则它们可以全部存在于同一个目录中,也可以每个节点都放在自己的子目录中。examples 文件夹必须位于包的根目录中。

在本地测试 node 模块

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

在 node-red 用户目录中,通常运行 :~/.node-red

1
npm install <path to location of node module>

这将创建指向目录的相应符号链接,以便 Node-RED 将在节点启动时发现该节点。可以选择对节点文件的任何更改 只需重新启动 Node-RED 即可启动。

package.json

除了通常的条目外,该文件还必须包含一个条目,该条目列出了包含运行时要加载的节点的文件 package.json node-red .js

如果单个文件中有多个节点,则只需列出该文件一次。

如果任何节点依赖于其他 npm 模块,则必须将它们包含在属性中。dependencies

为了帮助在 npm 存储库中发现节点,该文件应包含在其属性中。这将确保在按关键字搜索时显示包。node-red keywords

注意:请不要添加 ‘node-red’ 关键字,直到您对节点稳定且正常工作感到满意,并且有足够的文档供其他人使用它。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name" : "@myScope/node-red-sample",
"version" : "0.0.1",
"description" : "A sample node for node-red",
"dependencies": {
},
"keywords": [ "node-red" ],
"node-red" : {
"nodes": {
"sample": "sample/sample.js"
}
}
}

您应该通过条目指定您的节点支持的 Node-RED 版本。例如,以下表示节点需要 Node-RED 2.0 或更高版本。version

1
2
3
4
5
6
"node-red"     : {
"version": ">=2.0.0",
"nodes": {
"sample": "sample/sample.js"
}
}

README.md

README.md 文件应描述节点的功能,并列出使其正常运行所需的任何先决条件。在节点的 html 文件的 info 选项卡部分包含任何未包含的额外说明也可能很有用,甚至可能包含一个演示其用法的小示例流程。

文件应使用 GitHub 风格的 markdown 进行标记。

许可证

请包含一个许可证文件,以便其他人知道他们可以用您的代码做什么和不可以做什么。

发布到 npm

有很多指南可以将包发布到 npm 存储库。 此处提供了基本概述。

添加到 flows.nodered.org

截至 2020 年 4 月,Node-RED 流库不再能够使用关键字自动索引和更新在 npm 上发布的节点。相反,必须手动提交请求。node-red

为此,请确保满足所有打包请求。要向库添加新节点,请单击库页面顶部的按钮,然后选择 ‘node’ 选项。此按钮会将您带到 Add a Node 页面。在这里,重复了需求列表,并描述了将其添加到库中的步骤。+

要更新现有节点,您可以像更新新节点一样重新提交它,也可以通过“请求刷新”链接从流程库上的节点页面请求刷新。这仅对已登录用户可见。

如果在此之后没有出现,您可以在 Node-RED 论坛或 Slack 上寻求帮助。

节点属性

节点的属性由对象在其 html 定义中定义。这些是在运行时创建节点实例时传递给节点构造函数的属性。defaults

在 创建第一个节点 部分的示例中, Node 具有一个名为.(原文空白)的属性。在本节中,我们将添加新的属性调用到节点:name prefix

  1. 向对象添加新条目:defaults

    1
    2
    3
    4
    defaults: {
    name: {value:""},
    prefix: {value:""}
    },

    该条目包括将此类型的新节点拖动到工作区时要使用的默认值。value

  2. 向节点的编辑模板添加条目

    1
    2
    3
    4
    <div class="form-row">
    <label for="node-input-prefix"><i class="fa fa-tag"></i> Prefix</label>
    <input type="text" id="node-input-prefix">
    </div>

    模板应包含一个设置为. <input> id node-input-<propertyname>

  3. 使用节点中的属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function LowerCaseNode(config) {
    RED.nodes.createNode(this,config);
    this.prefix = config.prefix;
    var node = this;
    this.on('input', function(msg) {
    msg.payload = node.prefix + msg.payload.toLowerCase();
    node.send(msg);
    });
    }

属性定义

对象中的条目必须是对象,并且可以具有以下属性:defaults

  • value:(任何类型)属性采用的默认值
  • required: (boolean) _该_属性是否为必需项。如果设置为 true,则如果其值为 null 或空字符串,则该属性将无效。
  • validate: (function) 可选 可用于验证属性值的函数。
  • type: (string) 可选 如果此属性是指向配置节点的指针,则标识节点的类型。

保留属性名称

有一些属性的保留名称不能使用。这些是:

  • 任何单个字符 - x y z d g l 都已使用。其他的则是保留供将来使用。
  • id type wires inputs outputs

如果节点希望允许其提供的输出数量是可配置的,则可以将其包含在数组中。Function (函数) 节点是其工作原理的一个示例。outputs defaults

属性验证

编辑器会尝试验证所有属性,以便在给定无效值时警告用户。

该属性可用于指示属性必须为非 null 和非 null。required

如果需要更具体的验证,则可以使用该属性提供一个函数来检查值是否有效。该函数将传递值,并应返回 true 或 false。它是在节点的上下文中调用的,这意味着可用于访问节点的其他属性。这允许验证依赖于其他属性值。编辑节点时,对象反映节点的当前配置,而不是当前表单元素值。验证器函数应尝试访问属性配置元素,并将该对象作为回退,以实现正确的用户体验validate this this this

提供了一组常见的验证函数。

  • RED.validators.number()- 检查值是否为数字
  • RED.validators.regex(re)- 检查值是否与提供的正则表达式匹配

两种方法 - attribute 和 attribute - 都以相同的方式反映在 UI 中。节点上缺少的配置标记被触发,当值无效或缺失时,相应的 input 用红色括起来。required validate

以下示例显示了如何应用这些验证程序。

1
2
3
4
5
6
7
8
defaults: {
minimumLength: { value:0, validate:RED.validators.number() },
lowerCaseOnly: {value:"", validate:RED.validators.regex(/[a-z]+/) },
custom: { value:"", validate:function(v) {
var minimumLength=$("#node-input-minimumLength").length?$("#node-input-minimumLength").val():this.minimumLength;
return v.length > minimumLength
} }
},

请注意,仅当属性的长度大于属性的当前值或 minimumLength 表单元素的值时,该属性才有效。custom minimumLength

属性编辑对话框

打开编辑对话框后,编辑器会使用节点的编辑模板填充对话框。

对于数组中的每个属性,它会查找设置为 defaults``<input>``id``node-input-<propertyname>``node-config-input-<propertyname> 的元素,或者在 Configuration 节点的情况下查找元素。然后,此输入为自动填充属性的当前值。当编辑对话框关闭时,该属性将采用 input 中的任何值。

有关编辑对话框的更多信息,请参阅此处

自定义编辑行为

默认行为在许多情况下都有效,但有时需要定义一些特定于节点的行为。例如,如果无法将属性正确编辑为简单的或,或者编辑对话框内容本身需要根据所选选项 <input> <select> 具有某些行为。

节点定义可以包含两个功能来自定义编辑行为。

  • oneditprepare在显示对话框之前立即调用。
  • oneditsave在 okay edit 对话框时调用。
  • oneditcancel在取消 Edit 对话框时调用。
  • oneditdelete在按下配置节点的 Edit 对话框中的 Delete 按钮时调用。
  • oneditresize在调整编辑对话框的大小时调用。

例如,当 Inject 节点配置为重复时,它会将配置存储为类似 cron 的字符串:1, 2 * * * * oneditprepare oneditsave。该节点定义了一个函数,该函数可以解析该字符串并提供更加用户友好的 UI。它还具有一个函数,可将用户选择的选项编译回相应的 cron 字符串。

节点凭证

一个节点可以将许多属性定义为 。这些属性与主流文件分开存储,从编辑器导出流时不会包含在内。credentials

要向节点添加凭证,请执行以下步骤:

  1. 在节点的定义中添加一个新条目:credentials

    1
    2
    3
    4
    credentials: {
    username: {type:"text"},
    password: {type:"password"}
    },

    这些条目采用单个选项 — 它们的可以是 type text password 其中的一个。

  2. 将合适的条目添加到节点的编辑模板中

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="form-row">
    <label for="node-input-username"><i class="fa fa-tag"></i> Username</label>
    <input type="text" id="node-input-username">
    </div>
    <div class="form-row">
    <label for="node-input-password"><i class="fa fa-tag"></i> Password</label>
    <input type="password" id="node-input-password">
    </div>

    请注意,该模板使用与常规节点属性相同的元素约定。id

  3. 在节点的文件中,调用必须辈更新包含以下凭证:.js RED.nodes.registerType

    1
    2
    3
    4
    5
    6
    RED.nodes.registerType("my-node",MyNode,{
    credentials: {
    username: {type:"text"},
    password: {type:"password"}
    }
    });

访问凭证

凭证的运行时使用

在运行时中,节点可以使用以下属性访问其凭证:credentials

1
2
3
4
5
function MyNode(config) {
RED.nodes.createNode(this,config);
var username = this.credentials.username;
var password = this.credentials.password;
}

Editor 中的凭证

在编辑器中,节点对其凭证的访问受到限制。任何属于 type 的 API 都可以在 property 下使用 - 就像它们在运行时中一样。但类型的凭证不可用。相反,存在一个名为 is 的相应布尔属性,以指示是否为凭证分配了非空值。text credentials password has_<property-name>

1
2
3
4
5
6
oneditprepare: function() {
// this.credentials.username is set to the appropriate value
// this.credentials.password is not set
// this.credentials.has_password indicates if the property is present in the runtime
...
}

高级凭证使用

虽然上面概述的凭证系统在大多数情况下就足够了,但在某些情况下,有必要在凭证中存储更多的值,而不仅仅是用户提供的值。

例如,要使节点支持 OAuth 工作流程,它必须保留用户永远不会看到的服务器分配的令牌。Twitter 节点提供了一个很好的示例,说明如何实现这一点。

节点外观

节点外观有三个方面可以自定义;图标、背景颜色及其标签。

图标

节点的图标由其定义中的属性指定icon

该属性的值可以是字符串或函数。

如果值是字符串,则用作图标。

如果值是一个函数,它将在首次加载节点时或编辑节点后进行评估。该函数应返回要用作图标的值。

该函数将同时为工作区中的节点(其中引用节点实例)以及调色板中的节点条目调用。在后一种情况下,将不引用特定的 node 实例,并且该函数_必须_返回一个有效的值。this this

1
2
3
...
icon: "file.svg",
...

图标可以是:

  • Node-RED 提供的股票图标的名称,
  • 模块提供的自定义图标的名称,
  • Font Awesome 4.7 图标

Stock 图标

  • alert.svg
     - arrow-in.svg
     - bridge-dash.svg
     - bridge.svg
     - db.svg
     - debug.svg
     - envelope.svg
     - feed.svg
     - file.svg
     - function.svg
     - hash.svg
     - inject.svg
     - light.svg
     - serial.svg
     - template.svg
     - white-globe.svg

注意:在 Node-RED 1.0 中,所有这些图标都已替换为 SVG 替代图标,以获得更好的外观。为了确保向后兼容性,编辑器会自动将 png 版本的任何请求替换为 SVG 版本(如果可用)。

自定义图标

节点可以在与其和 files 一起调用的目录中提供自己的图标。当编辑器查找给定的图标文件名时,这些目录将添加到搜索路径中。因此,图标文件名必须是唯一的 icons .js .html

图标应为透明背景上的白色,纵横比为 2:3,大小至少为 40 x 60。

Font Awesome 图标

Node-RED 包括一整套 Font Awesome 4.7 图标

要指定 FA 图标,该属性应采用以下格式:

1
2
3
...
icon: "font-awesome/fa-automobile",
...

用户定义的图标

用户可以在编辑器中的节点编辑对话框的 ‘外观’ 选项卡上自定义单个节点图标。

: 如果节点的对象中具有属性,则无法自定义其图标。例如,icon defaults ui_button node-red-dashboard

背景颜色

节点背景颜色是快速区分不同节点类型的主要方法之一。它由节点定义中的属性指定 color

1
2
3
...
color: "#a6bbcf",
...

我们使用了柔和的调色板。新节点应尝试找到适合此调色板的颜色。

以下是一些常用的颜色:
image.png

标签

一个节点有四个 label 属性 label paletteLabel outputLabel inputLabel

节点标签

工作区中节点的 可以是静态文本,也可以根据节点的属性在每个节点的基础上动态设置label

该属性的值可以是字符串或函数。

如果值是字符串,则用作标签。

如果值是一个函数,它将在首次加载节点时或编辑节点后进行评估。该函数应返回要用作标签的值。

如上一节所述,节点有一个约定,即节点具有一个属性来帮助区分它们。以下示例显示了如何设置选取此属性的值或默认为一些明智的事情。name label

1
2
3
4
5
...
label: function() {
return this.name||"lower-case";
},
...

请注意,不能在 label 函数中使用 credential 属性。

调色板标签

默认情况下,节点的类型在调色板中用作其标签。该属性可用于覆盖此属性。paletteLabel

label 一样,此属性可以是字符串或函数。如果它是一个功能,则在将节点添加到调色板时对其进行一次评估。

标签样式

标签的 css 样式也可以使用 property 动态设置。目前,此属性必须标识要应用的 css 类。如果未指定,它将使用 default 类。唯一的其他预定义类是 labelStyle node_label node_label_italic

以下示例显示了如何设置该属性:labelStyle node_label_italic name

1
2
3
4
5
...
labelStyle: function() {
return this.name?"node_label_italic":"";
},
...

对齐

默认情况下,图标和标签在节点中左对齐。对于位于流末尾的节点,约定是右对齐内容。这是通过将节点定义中的属性设置为 :align``right 来完成的

1
2
3
...
align: 'right',
...

端口标签

节点可以在其输入和输出端口上提供标签,将鼠标悬停在端口上即可看到这些标签。

这些可以通过节点的 html 文件静态设置

1
2
3
4
...
inputLabels: "parameter for input",
outputLabels: ["stdout","stderr","rc"],
...

或由函数生成,该函数传递索引以指示输出引脚(从 0 开始)。

1
2
3
4
5
...
outputLabels: function(index) {
return "my port number "+index;
}
...

在这两种情况下,用户都可以使用 configuration editor 的部分覆盖它们node settings

: 标签不是动态生成的,不能通过属性进行设置 msg

按钮

节点的左边缘或右边缘可以有一个按钮,如核心 Inject 和 Debug 节点所示。

一个关键原则是编辑器不是用于控制流程的控制面板。所以一般来说,节点上不应该有按钮。Inject 和 Debug 节点是特殊情况,因为按钮在流的开发中起着重要作用。

其定义中的属性用于描述按钮的行为。它必须至少提供一个在单击按钮时将调用的函数 button onclick

1
2
3
4
5
6
7
...
button: {
onclick: function() {
// Called when the button is clicked
}
},
...

该属性还可以定义一个函数,以根据节点的当前配置动态启用和禁用按钮。同样,它可以定义一个函数来确定是否应该显示按钮 enabled visible

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
button: {
enabled: function() {
// return whether or not the button is enabled, based on the current
// configuration of the node
return !this.changed
},
visible: function() {
// return whether or not the button is visible, based on the current
// configuration of the node
return this.hasButton
},
onclick: function() { }
},
...

也可以将其配置为切换按钮 - 如 Debug 节点所示。这是通过添加一个名为 property 的属性来完成的,该属性标识节点对象中的一个属性,该属性应该用于存储一个布尔值,每当按下按钮时,该值都会切换 button toggle defaults

1
2
3
4
5
6
7
8
9
10
11
...
defaults: {
...
buttonState: {value: true}
...
},
button: {
toggle: "buttonState",
onclick: function() { }
}
...

节点编辑对话框

节点的编辑对话框是用户配置节点以执行所需作的主要方式。

该对话框应该易于使用,并且与其他节点相比,其设计和外观应保持一致。

编辑对话框在节点的 HTML 文件中提供,位于 tag:<script> 内

1
2
3
<script type="text/html" data-template-name="node-type">
<!-- edit dialog content -->
</script>
  • 标签应该有一个 of - 这将帮助大多数文本编辑器提供适当的语法高亮。它还可以防止浏览器在将节点加载到编辑器中时将其视为普通 HTML 内容 <script> type text/html
  • 该标签应设置为其编辑对话框的节点类型。这是编辑器在编辑特定节点时知道要显示哪些内容的方式 data-template-name

编辑对话框通常由一系列行组成 - 每行都包含一个标签和不同属性的输入

1
2
3
4
<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>
  • 每行都由类为 <div>``的 form-row 创建
  • 典型的行将具有 a,其中包含一个图标和属性名称,后跟一个(原文空白)。该图标是使用一个元素创建的,该元素的类取自 Font Awesome 4.7 中提供的元素。<label>``<input>``<i>
  • 包含属性的 form 元素的 id 必须为 node-input-<propertyname>。对于 Configuration 节点,id 必须为node-config-input-<property-name>
  • 类型可以是字符串/数字属性,也可以是布尔属性。或者,如果存在一组受限的选择,则可以使用 element <input> text checkbox <select>

Node-RED 提供了一些标准的 UI 小部件,节点可以使用这些小部件来创建更丰富、更一致的用户体验。

按钮

要向编辑对话框添加按钮,请使用标准 HTML 元素并为其指定类 <button> red-ui-button

普通按钮
小按钮
切换按钮



js<br>$(".my-button-group").on("click", function() {<br> $(".my-button-group").removeClass("selected");<br> $(this).addClass("selected");<br>})<br>

要在活动按钮上切换类,您需要向函数添加代码以处理事件 selected oneditprepare

_注意: _ 避免元素之间的空格,因为 span 当前无法正确折叠空格。这将在未来得到解决 <button> button-group

输入

对于简单的文本输入,可以使用标准元素 <input>

在某些情况下,Node-RED 提供小部件作为替代方案。它允许用户指定属性的类型及其值 TypedInput

例如,如果属性可以是 String、number 或 boolean。或者,如果该属性用于标识消息、流或全局上下文属性。

它是一个 jQuery 小部件,需要将代码添加到节点的函数中,以便将其添加到页面 oneditprepare

小组件的完整 API 文档,包括可用 内置类型可在此处获得。TypedInput

纯 HTML 输入
TypedInput
字符串/数字/布尔值


js<br>$("#node-input-example1").typedInput({<br> type:"str",<br> types:["str","num","bool"],<br> typeField: "#node-input-example1-type"<br>})<br>

当 TypedInput 可以设置为多个类型时,一个额外的节点 property 来存储有关类型的信息。此 Cookie 将作为隐藏的 <input>
JSON 格式输入

js<br>$("#node-input-example2").typedInput({<br> type:"json",<br> types:["json"]<br>})<br>

JSON 类型包括一个按钮,该按钮将打开专用的 JSON Edit 对话框(在此演示中禁用)。
msg/flow/global 格式输入

js<br>$("#node-input-example3").typedInput({<br> type:"msg",<br> types:["msg", "flow","global"],<br> typeField: "#node-input-example3-type"<br>})<br>
选择框
js<br>$("#node-input-example4").typedInput({<br> types: [<br> {<br> value: "fruit",<br> options: [<br> { value: "apple", label: "Apple"},<br> { value: "banana", label: "Banana"},<br> { value: "cherry", label: "Cherry"},<br> ]<br> }<br> ]<br>})<br>
多选框
js<br>$("#node-input-example5").typedInput({<br> types: [<br> {<br> value: "fruit",<br> multiple: "true",<br> options: [<br> { value: "apple", label: "Apple"},<br> { value: "banana", label: "Banana"},<br> { value: "cherry", label: "Cherry"},<br> ]<br> }<br> ]<br>})<br>

多选结果值是所选选项的逗号分隔列表。

多行文本编辑器

Node-RED 包括一个基于 Ace 代码编辑器的多行文本编辑器,或者如果通过用户设置启用,则包括 Monaco 编辑器

多行文本编辑器

在以下示例中,我们将编辑的 node 属性称为 exampleText

在 HTML 中,为编辑器添加占位符。这必须具有 css 类。您还需要在元素上设置 <div> node-text-editor height

1
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-example-editor"></div>

在节点的函数中,文本编辑器使用以下函数进行初始化:oneditprepare RED.editor.createEditor

1
2
3
4
5
this.editor = RED.editor.createEditor({
id: 'node-input-example-editor',
mode: 'ace/mode/text',
value: this.exampleText
});

在对话框关闭时,还需要 and 函数从编辑器中取回值,并确保从页面中正确删除编辑器 oneditsave oneditcancel

1
2
3
4
5
6
7
8
9
oneditsave: function() {
this.exampleText = this.editor.getValue();
this.editor.destroy();
delete this.editor;
},
oneditcancel: function() {
this.editor.destroy();
delete this.editor;
},

节点上下文

节点可以在其 context 对象中存储数据。

有关 context 的更多信息,请阅读 Using Context 指南

节点有三个可用的上下文范围:

  • Node - 仅对设置值的节点可见
  • 流 - 对同一流(或编辑器中的选项卡)上的所有节点可见
  • 全局 - 对所有节点可见

与提供预定义变量来访问每个上下文的 Function 节点不同,自定义节点必须自行访问这些上下文:

1
2
3
4
5
6
// Access the node's context object
var nodeContext = this.context();

var flowContext = this.context().flow;

var globalContext = this.context().global;

这些上下文对象中的每一个都具有编写函数指南中描述的相同 get/set 函数。

注意:默认情况下,由其他节点使用和共享的配置节点是全局的,除非另有规定 由节点的用户指定。因此,不能假定他们有权访问 Flow 上下文。