【n8n教程】:从零上手自定义节点开发(规划 → 编写 → 测试 → 部署)

面向已经会一点 JavaScript/TypeScript、用过 n8n 的同学,带你按官方文档的节奏,一步步把“自定义节点”真正跑起来。


1. 自定义节点到底能做什么?

n8n 自带了大量节点,但在实际项目里你经常会遇到:

这时候,“自定义节点”就是官方推荐的方式:
你可以像官方节点一样,在左侧节点面板里搜索到它,拖拽、配置、连线即可。


2. 官方推荐的整体流程

官方“Creating Nodes”文档把整个过程拆成五步:规划 → 构建 → 测试 → 部署 → 维护/分享。

步骤对应官方文档你要做的事情(简化版)
规划 (Plan)Plan a node选好节点类型、构建风格、UI 参数、文件结构
构建 (Build)Build a node写 TypeScript / 声明式配置,实现节点逻辑
测试 (Test)Test a node在本地 n8n 手动跑 + 用 linter 自动检查
部署 (Deploy)Deploy a node本地私有安装,或发布为社区节点,供云端使用
概览 (Overview)Creating nodes总体说明、参考链接、UI 元素 & 文件结构参考

n8n 的节点开发属于前端 TypeScript + 后端 HTTP/业务逻辑的结合,但官方已经把接口与约定封装得比较好,照着套路走即可。

n8n 工作流编辑界面长什么样?

下面这类界面就是你开发节点后要用到的工作流编辑器:左侧选节点,中间拖线,右侧配置参数。


3. 环境准备(一步步来)

要跟着本教程动手,建议你先准备好:

  1. 1. 基础技能
    • • 会一点 JavaScript/TypeScript(函数、对象、Promise 等)
    • • 会用 npm(npm initnpm installnpm publish 基本命令)
    • • 会用 git
  2. 2. 开发环境
    • • Node.js(建议 18+)
    • • 一个代码编辑器(VS Code 即可)
    • • git 命令行
  3. 3. 本地 n8n 实例
    • • 最简单:npx n8n 直接启动(默认 http://localhost:5678)
    • • 或用 Docker 自建(方便挂载自定义节点目录):
      官方与社区节点安装文档都建议把 n8n 数据目录挂载到容器的 /home/node/.n8n,例如:

    
    
    
  docker run -it --rm \
  --name n8n \
  -p 5678:5678 \
  -e N8N_COMMUNITY_PACKAGES_ENABLED=true \
  -v ~/n8n-data:/home/node/.n8n \
  docker.n8n.io/n8nio/n8n

其中 N8N_COMMUNITY_PACKAGES_ENABLED=true 是加载社区/自定义节点所必需的环境变量。


4. 第一步:规划你的节点(Plan a node)

这一阶段只动脑,不动手写代码,目标是把以下四件事想清楚。

4.1 选择节点类型

常见的有两大类:

  1. 1. 普通节点(Regular node)
    • • 有输入,有输出
    • • 例如 HTTP Request、Edit Fields (Set)、Code
    • • 用于“处理数据、调用服务”
  2. 2. 触发器节点(Trigger node)
    • • 负责“什么时候启动工作流”
    • • 例如 Cron、Webhook、Gmail Trigger
    • • 触发器节点通常没有上游输入,而是自己推送数据给后面的节点

新手建议:先从“普通节点”开始。
例如:封装一个“调用公开 HTTP API”并返回 JSON 的节点。


4.2 选择构建风格:声明式 vs 代码式

官方文档目前主推两种“节点构建风格”:

  1. 1. 声明式(Declarative-style node)
    • • 用配置对象描述:
      • • 这个节点有哪些参数(UI 字段)
      • • 请求怎么发(URL、Method、Query、Body)
      • • 响应如何映射到 item
    • • 优点:不需要写太多 execute() 里的业务代码,更接近“配置一个 HTTP 集成”
    • • 适合:绝大多数“包装 REST API”型节点
  2. 2. 代码式(Code-style / imperative)
    • • 主要在 execute 方法里写 TypeScript 逻辑:
      • • 读参数
      • • 发 HTTP 请求、处理数组、做循环/条件
      • • 组织并返回输出数据
    • • 优点:灵活,不限于 HTTP,复杂逻辑都能写
    • • 适合:复杂业务规则、需要多次调用 API、或处理本地文件等

初学建议:先做一个“声明式 HTTP 节点”,体验打通全流程。


4.3 设计 UI:用户在右侧面板看到什么?

n8n 的节点 UI 本质上是“一个配置结构”,内部渲染成表单。

常见字段类型:

你需要想清楚:

一个简单示例:封装猫咪语录 API 的节点


4.4 设计节点代码的文件结构

一个最小的自定义节点包,大致目录结构如下:


    
    
    
  my-n8n-cat-node/
├─ package.json        # 声明 n8n 节点、依赖、名字等
├─ tsconfig.json       # TypeScript 配置(可复用官方模板)
├─ nodes/
│  └─ CatFact.node.ts  # 具体节点实现文件
└─ credentials/        # 若需要鉴权(本例不需要,可为空)

package.json 里,需要有一个 n8n 字段,告诉 n8n:


5. 第二步:编写你的第一个声明式 HTTP 节点(实战示例)

下面以“调用公开猫咪语录 API:https://catfact.ninja/fact”为例,写一个最小可用的节点骨架。
注意:代码是结构示意,重点是帮助你理解,不是完整生产代码

5.1 初始化项目

在你本机某个目录下:


    
    
    
  mkdir my-n8n-cat-node
cd
 my-n8n-cat-node
npm init -y

随后:

5.2 配置 package.json 中的 n8n 字段

package.json 中增加类似配置(示例):


    
    
    
  {
  "name"
: "my-n8n-cat-node",
  "version"
: "0.1.0",
  "main"
: "dist/nodes/index.js",
  "n8n"
: {
    "nodes"
: [
      "dist/nodes/CatFact.node.js"

    ]
,
    "credentials"
: []
  }
,
  "scripts"
: {
    "build"
: "tsc",
    "lint"
: "eslint ."
  }

}

要点:

5.3 编写 CatFact.node.ts(简化版结构)

nodes/CatFact.node.ts 示例结构(删掉了一些高级配置,只保留最关键部分,帮助你看清“形状”):


    
    
    
  import type {
  INodeType
,
  INodeTypeDescription
,
  IExecuteFunctions
,
} from 'n8n-workflow';

export
 class CatFact implements INodeType {
  description
: INodeTypeDescription = {
    displayName
: 'Cat Fact',
    name
: 'catFact',
    group
: ['transform'],
    version
: 1,
    description
: 'Get random cat facts from catfact.ninja',
    defaults
: {
      name
: 'Cat Fact',
    },
    inputs
: ['main'],
    outputs
: ['main'],
    properties
: [
      {
        displayName
: 'Limit',
        name
: 'limit',
        type
: 'number',
        typeOptions
: {
          minValue
: 1,
          maxValue
: 10,
        },
        default
: 1,
        description
: 'How many facts to fetch',
      },
      {
        displayName
: 'Only Text',
        name
: 'onlyText',
        type
: 'boolean',
        default
: true,
        description
: 'Return only fact text field',
      },
    ],
  };

  async
 execute(this: IExecuteFunctions) {
    const
 items = this.getInputData();
    const
 returnData = [];

    const
 limit = this.getNodeParameter('limit', 0) as number;
    const
 onlyText = this.getNodeParameter('onlyText', 0) as boolean;

    // 简单写法:只看第一条输入 item,执行一次请求

    const
 response = await this.helpers.request({
      method
: 'GET',
      uri
: 'https://catfact.ninja/facts',
      qs
: { limit },
      json
: true,
    });

    const
 facts = response?.data || [];

    for
 (const fact of facts) {
      if
 (onlyText) {
        returnData.push({ json: { fact: fact.fact } });
      } else {
        returnData.push({ json: fact });
      }
    }

    return
 [returnData];
  }
}

这里混合了“声明式 UI”(properties)和“代码式 execute”,是最常见的模式:
UI 用配置描述,逻辑用 TypeScript 写。

完整的类型定义(INodeTypeDescription 各字段含义、UI 元素种类)可以在官方 “Build a declarative-style node” 文档与参考章节里查到。


6. 第三步:在本地 n8n 中测试节点(Test a node)

官方文档推荐两种测试方式都用上:手动测试 + linter 自动检查。

6.1 把节点安装到本地 n8n 实例

常见方式(以 Docker、自定义包为例):

  1. 1. 先构建 TypeScript

    
    
    
  npm run build
  1. 2. 把整个包放到 n8n 数据目录的 custom 下,例如:

    
    
    
  cd ~/n8n-data
mkdir
 -p custom
cd
 custom
# 假设你已经在别处写好包,可以用 npm 安装或直接拷贝

npm i /path/to/my-n8n-cat-node
  1. 3. 确保 n8n 容器启动时挂载了该目录,并设置了

    
    
    
  -v ~/n8n-data:/home/node/.n8n
-e N8N_COMMUNITY_PACKAGES_ENABLED=true
  1. 4. 重启 n8n
    • • Docker:docker stop n8n && <之前的 docker run 命令>
    • • Docker Compose:docker compose restart

n8n 只会在启动时扫描 custom 目录里的包,所以每次装新节点后必须重启


6.2 在编辑器里手动测试节点

  1. 1. 打开本地 n8n(默认 http://localhost:5678)
  2. 2. 新建一个空工作流
  3. 3. 添加节点:
    • • 先拖一个 Manual Trigger(手动触发) 节点
    • • 再在左侧搜索刚才安装的 Cat Fact 节点,拖到画布上
    • • 用连线把 Manual Trigger 连到 Cat Fact 节点
  4. 4. 选中 Cat Fact,在右侧参数面板里设置:
    • Limit = 3
    • Only Text = true
  5. 5. 点击顶部“执行工作流”(或单独执行节点),观察输出数据

6.3 用 linter 自动测试

官方提供了节点 linter,用于检查:

基本使用方式:

  1. 1. 在 package.json 里添加一个 lint 脚本(官方模板里通常已给出)
  2. 2. 在项目根目录运行:

    
    
    
  npm run lint
  1. 3. 根据输出逐条修复

具体 linter 的安装命令与配置请以官方 “Test a node” 文档为准;教程里保持概念即可,避免跟版本耦合过死。


7. 第四步:部署与分享节点(Deploy a node)

当你在本地反复测试、linter 通过后,就可以考虑“给别人用”了。

7.1 仅自己用:私有节点

如果只是团队内部 / 自己用,有两个简单方式:

  1. 1. 复制包到每个 n8n 实例的 custom 目录
    • • 缺点:多个实例要手动同步更新版本
  2. 2. 在私有 npm 仓库发布包
    • • 运维只需要在 ~/n8n-data/customnpm i my-n8n-cat-node@latest 然后重启即可

这种方式在自托管 n8n 中很常见,适合企业内网集成。

7.2 分享给社区:发布为社区节点

如果希望别人能在 n8n 云端(hosted)直接安装你的节点,需要:

  1. 1. 把节点打包并发布到 npm(公开包)
  2. 2. 按照官方要求提交到 n8n 的“社区节点仓库”
  3. 3. 通过审核后,就会出现在 n8n 后台的“社区节点”列表中,
    云端环境也可以像装插件一样一键安装使用

官方也明确:在云端想用自定义节点,只能通过“社区节点”的方式安装,不能像本地那样直接挂个 custom 目录。


8. 实战案例:导入一个完整工作流 JSON(可以直接跑)

最后给一个完整可执行工作流 JSON 作为实战练习,让你熟悉:

8.1 工作流功能说明:一键发送一条短信

示例来自一个公开的 n8n 工作流数据集中:
它做的事情非常简单:

注意:要真正发送短信,你需要一个 Plivo 账号和有效的手机号码,这里只是展示结构与导入方法。


8.2 完整工作流 JSON 代码

你可以直接复制下面这段 JSON,在 n8n 中导入并运行(记得先配置 Plivo 凭据)。


    
    
    
  {
  "name"
: "",
  "nodes"
: [
    {

      "name"
: "On clicking 'execute'",
      "type"
: "n8n-nodes-base.manualTrigger",
      "position"
: [250, 300],
      "parameters"
: {},
      "typeVersion"
: 1
    }
,
    {

      "name"
: "Plivo",
      "type"
: "n8n-nodes-base.plivo",
      "position"
: [500, 300],
      "parameters"
: {
        "to"
: "+14156667778",
        "from"
: "+14156667777",
        "message"
: "Hello world!"
      }
,
      "credentials"
: {
        "plivoApi"
: ""
      }
,
      "typeVersion"
: 1
    }

  ]
,
  "active"
: false,
  "settings"
: {},
  "connections"
: {
    "On clicking 'execute'"
: {
      "main"
: [
        [

          {

            "node"
: "Plivo",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }

}

这个 JSON 的几个关键点:

这一结构与官方的“导出/导入工作流”文档描述是一致的:
n8n 会把工作流保存为 JSON,其中 nodesconnectionsname 等是导入时的关键字段。


8.3 如何在 n8n 中导入这个工作流

  1. 1. 打开 n8n,进入 “Workflows” 页面
  2. 2. 点击右上角 “Import” / “导入”
  3. 3. 选择 “从剪贴板导入”(Import from clipboard)
  4. 4. 把上面的 JSON 粘贴进去,点击确认
  5. 5. 进入刚导入的工作流:
    • • 双击 Plivo 节点
    • • 在 Credentials 下拉里选择你已经配置好的 Plivo 凭据
    • • 把 tofrom 改成你自己的测试号码
  6. 6. 点击顶部的 “执行工作流”(或点击触发器节点上的执行按钮)

如果一切配置正确,你会收到一条 “Hello world!” 短信。


8.4 如何把示例工作流改成“使用你自己的自定义节点”

练习题:现在你已经有了 Cat Fact 节点,可以试试这样改造:

  1. 1. 在上面的工作流里:
    • • 删除 Plivo 节点
    • • 改为添加你的 Cat Fact 节点
  2. 2. 连线:
    • Manual TriggerCat Fact
  3. 3. 执行:
    • • 观察 Cat Fact 输出的 JSON 数据

进一步挑战:

这就是一个完整闭环

规划节点 → 编写节点 → 测试节点 → 部署节点 → 在真实工作流中使用它。


9. 总结与下一步建议

通过这篇教程,你已经掌握了:

  1. 1. 从 0 规划一个自定义节点:选类型、选构建风格、设计 UI、确定文件结构
  2. 2. 用 TypeScript 写出一个最小节点骨架:定义 description + 实现 execute
  3. 3. 在本地 n8n 中安装 & 测试节点:挂载 custom 目录、启用社区包、手动执行
  4. 4. 了解如何部署和分享节点:私有安装 vs 社区节点
  5. 5. 通过完整 JSON 工作流练习导入/执行:熟悉工作流 JSON 结构与导入流程

下一步可以做什么?


引用链接

[1] 官方文档: https://docs.n8n.io/integrations/creating-nodes/overview/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#