你是不是也遇到过这种“无节点可用”的尴尬?
在 N8N 大学,我们每天都会收到读者的私信:“大神,n8n 能不能对接我公司的内部系统?”或者“这个冷门 API 怎么没有现成的节点?”
老实说,n8n 的生态已经很丰富了,但面对海量的 SaaS 工具和私有化部署,官方节点永远不可能覆盖 100% 的场景。这时候,很多人会选择绕路,比如先用 Python 写个脚本再通过 HTTP 调用,或者干脆放弃自动化。
其实,n8n 最硬核的能力在于它允许你“造轮子”。今天,笔者就带你手把手实战,从零构建一个自定义节点。这不仅能解决眼前的问题,更能让你彻底理解 n8n 的底层逻辑。
准备工作:磨刀不误砍柴工
在开始写代码之前,我们需要打通开发环境。别担心,这比你想象的要简单。
- Node.js 环境:确保你的电脑安装了 Node.js(建议 v16 以上版本)。这是运行 n8n 开发工具的基石。
- n8n CLI 工具:我们需要使用官方提供的脚手架工具。在终端运行
npm install -g n8n-node-dev即可安装。 - 一个简单的 API:为了演示,笔者准备了一个免费的公共 API(JSONPlaceholder),用于获取用户数据。你可以替换为任何你想对接的 API。
准备好这些,我们就可以开始创建项目了。记住,自定义节点本质上就是一段 TypeScript/JavaScript 代码,它定义了输入、输出和处理逻辑。
核心实操:构建你的第一个 API 节点
我们将创建一个名为 n8n-nodes-custom-user-fetcher 的节点。它的功能很简单:接收一个用户 ID,通过 API 获取该用户的详细信息。
步骤 1:初始化节点项目
打开终端,进入你想要存放代码的目录,运行以下命令:
n8n-node-dev new
系统会提示你输入节点的名称(如 n8n-nodes-custom-user-fetcher)和描述。按照提示操作,脚手架会自动生成标准的项目结构。这一步非常关键,因为它帮你处理了 Webpack 配置和依赖库。
步骤 2:编写节点逻辑 (src/nodes/UserFetcher.ts)
这是最硬核的部分。在生成的 src/nodes 目录下,找到对应的文件。我们需要定义两个核心部分:接口 (Interface) 和 执行逻辑 (Execute)。
首先,定义输入参数。我们希望用户在界面上输入一个 ID:
// 这是一个简化的代码片段
const fields = [
{
displayName: 'User ID',
name: 'userId',
type: 'string',
default: '',
placeholder: '例如: 1',
description: '要获取的用户 ID',
},
];
接下来,编写实际的 API 调用逻辑。我们使用 n8n 内置的 httpRequest 方法:
const items = this.getInputData();
const item = items[0];
const userId = item.json.userId; // 获取用户输入的 ID
// 调用 API
const responseData = await this.helpers.httpRequest({
method: 'GET',
url: `https://jsonplaceholder.typicode.com/users/${userId}`,
});
// 将结果输出
return [this.helpers.jsonToItem(responseData)];
这里的 this.helpers.httpRequest 是 n8n 提供的封装方法,它自动处理了 Header、代理和错误提示,比原生的 fetch 好用太多。
步骤 3:本地编译与测试
代码写好了,怎么在 n8n 界面里看到它?回到终端,运行:
n8n-node-dev start
这个命令会启动一个监听模式,实时编译你的代码。此时,你需要找到你的 n8n 实例(如果是本地安装,通常在 ~/.n8n 目录),将开发中的节点链接进去。
通常,我们需要在 n8n 的配置文件中增加自定义节点的路径,或者直接将编译后的包放入 custom 节点目录。对于开发版,最直接的方式是运行 n8n 时指定环境变量:
N8N_NODES_CUSTOM=/path/to/your/node/project n8n start
重启 n8n 后,按 Ctrl + R 刷新界面,搜索 "User Fetcher",你就能看到自己创建的节点了!拖拽一个节点,输入 ID,运行,看到结果的那一刻,成就感爆棚。
避坑指南:那些年我们踩过的坑
开发自定义节点虽然爽,但也有几个常见的“坑”,笔者在这里提前预警:
- 依赖管理问题:如果你在节点中使用了第三方库(如
moment或lodash),必须确保它们被正确添加到package.json 的 dependencies 中。否则,编译后的代码在 n8n 运行时会报Module not found错误。 - 输入输出数据格式:n8n 的节点通信基于 JSON 对象。新手常犯的错误是直接返回原生的 API 响应,而没有经过
this.helpers.jsonToItem()处理,导致后续节点无法正确读取数据。记住,n8n 内部传输的是 "Item" 对象。 - TypeScript 类型定义:虽然你可以写纯 JS,但强烈建议使用 TS。n8n 的类型定义非常完善,利用好接口定义(如
INodeExecutionData)能减少 90% 的运行时报错。
还有一点需要注意:如果你的 API 需要鉴权(如 Bearer Token),不要硬编码在代码里。应该在节点的参数配置中添加认证字段,让用户在界面上填写,然后通过 this.getCredentials() 获取。这是 n8n 的最佳实践。
FAQ 问答
Q1: 自定义节点开发需要很高的编程水平吗?
A: 基础的 JavaScript/TypeScript 知识是必须的,但 n8n 的 API 封装得很好。只要理解了“输入 -> 处理 -> 输出”的流程,即使是初学者也能在几小时内写出第一个可用节点。
Q2: 开发好的节点可以分享给别人用吗?
A: 当然可以!你可以将项目打包发布到 npm,或者直接将编译好的 .js 文件分发。N8N 大学建议大家积极提交到社区,让更多人受益。
Q3: 自定义节点会影响 n8n 的性能吗?
A: 逻辑复杂的节点如果执行耗时过长,会阻塞当前的工作流执行。建议在开发时尽量优化异步逻辑,对于耗时任务,考虑使用队列或拆分步骤。
总结与资源
通过今天的学习,你已经掌握了 n8n 自定义节点开发的核心流程。从环境搭建、编写逻辑到本地测试,这标志着你的自动化能力从“使用者”进阶到了“创造者”。
掌握自定义节点,意味着 n8n 不再是一个封闭的工具,而是一个可以无限扩展的低代码平台。无论是对接内部 ERP,还是调用最新的 AI 接口,你都能随心所欲。
如果你在开发过程中遇到任何报错,欢迎随时访问 N8N大学 (n8ndx.com) 查阅更多实战教程。记住,最好的学习方式就是动手,去写你的第二个节点吧!