[ PROMPT_NODE_28090 ]
n8n JavaScript 代码节点开发
[ SKILL_DOCUMENTATION ]
# JavaScript 代码节点
在 n8n Code 节点中编写 JavaScript 代码的专家级指南。
---
## 快速开始
```javascript
// Code 节点的基础模板
const items = $input.all();
// 处理数据
const processed = items.map(item => ({
json: {
...item.json,
processed: true,
timestamp: new Date().toISOString()
}
}));
return processed;
```
### 核心规则
1. **选择“为所有项目运行一次 (Run Once for All Items)”模式**(大多数场景的推荐选择)
2. **访问数据**:使用 `$input.all()`、`$input.first()` 或 `$input.item`
3. **重要**:必须返回 `[{json: {...}}]` 格式
4. **重要**:Webhook 数据位于 `$json.body` 下(而非直接在 `$json` 下)
5. **可用内置工具**:`$helpers.httpRequest()`、`DateTime` (Luxon)、`$jmespath()`
---
## 模式选择指南
Code 节点提供两种执行模式。请根据使用场景进行选择:
### 为所有项目运行一次 (推荐 - 默认)
**适用场景**:95% 的使用案例
- **工作原理**:无论输入项有多少,代码仅执行 **一次**
- **数据访问**:使用 `$input.all()` 或 `items` 数组
- **最佳用途**:聚合、过滤、批处理、转换、带全量数据的 API 调用
- **性能**:处理多个项目时速度更快(单次执行)
```javascript
// 示例:计算所有项目的总和
const allItems = $input.all();
const total = allItems.reduce((sum, item) => sum + (item.json.amount || 0), 0);
return [{
json: {
total,
count: allItems.length,
average: total / allItems.length
}
}];
```
**何时使用:**
- ✅ 跨数据集比较项目
- ✅ 计算总和、平均值或统计数据
- ✅ 排序或排名
- ✅ 数据去重
- ✅ 构建汇总报告
- ✅ 合并来自多个项目的数据
### 为每个项目运行一次
**适用场景**:仅限特殊案例
- **工作原理**:代码针对每个输入项 **分别执行**
- **数据访问**:使用 `$input.item` 或 `$item`
- **最佳用途**:特定于项目的逻辑、独立操作、逐项验证
- **性能**:处理大型数据集时较慢(多次执行)
```javascript
// 示例:为每个项目添加处理时间戳
const item = $input.item;
return [{
json: {
...item.json,
processed: true,
processedAt: new Date().toISOString()
}
}];
```
**何时使用:**
- ✅ 每个项目需要独立的 API 调用
- ✅ 具有不同错误处理的逐项验证
- ✅ 基于项目属性的特定转换
- ✅ 业务逻辑要求必须分开处理项目时
**决策捷径:**
- **需要查看多个项目?** → 使用“所有项目”模式
- **每个项目完全独立?** → 使用“每个项目”模式
- **不确定?** → 使用“所有项目”模式(你始终可以在内部进行循环)
---
## 数据访问模式
### 模式 1:$input.all() - 最常用
**用途**:处理数组、批处理操作、聚合
```javascript
// 获取前一个节点的所有项目
const allItems = $input.all();
// 根据需要进行过滤、映射、归约
const valid = allItems.filter(item => item.json.status === 'active');
const mapped = valid.map(item => ({
json: {
id: item.json.id,
name: item.json.name
}
}));
return mapped;
```
### 模式 2:$input.first() - 非常常用
**用途**:处理单个对象、API 响应、先进先出
```javascript
// 仅获取第一个项目
const firstItem = $input.first();
const data = firstItem.json;
return [{
json: {
result: processData(data),
processedAt: new Date().toISOString()
}
}];
```
### 模式 3:$input.item - 仅限“每个项目”模式
**用途**:在“为每个项目运行一次”模式中使用
```javascript
// 循环中的当前项目
const currentItem = $input.item;
return [{
json: {
...currentItem.json,
itemProcessed: true
}
}];
```
### 模式 4:$node - 引用其他节点
**用途**:需要工作流中特定节点的数据
```javascript
// 获取特定节点的输出
const webhookData = $node["Webhook"].json;
const httpData = $node["HTTP Request"].json;
return [{
json: {
combined: {
webhook: webhookData,
api: httpData
}
}
}];
```
**详见**:[DATA_ACCESS.md](DATA_ACCESS.md) 获取全面指南
---
## 重要:Webhook 数据结构
**最常见的错误**:Webhook 数据嵌套在 `.body` 下
```javascript
// ❌ 错误 - 将返回 undefined
const name = $json.name;
const email = $json.email;
// ✅ 正确 - Webhook 数据在 .body 下
const name = $json.body.name;
const email = $json.body.email;
// 或者使用 $input
const webhookData = $input.first().json.body;
const name = webhookData.name;
```
**原因**:Webhook 节点将所有请求数据包装在 `body` 属性下。这包括 POST 数据、查询参数和 JSON 负载。
**详见**:[DATA_ACCESS.md](DATA_ACCESS.md) 获取完整的 Webhook 结构详情
---
## 返回格式要求
**核心规则**:始终返回带有 `json` 属性的对象数组
### 正确的返回格式
```javascript
// ✅ 单个结果
return [{
json: {
field1: value1,
field2: value2
}
}];
// ✅ 多个结果
return [
{json: {id: 1, data: 'first'}},
{json: {id: 2, data: 'second'}}
];
// ✅ 转换后的数组
const transformed = $input.all()
.filter(item => item.json.valid)
.map(item => ({
json: {
id: item.json.id,
processed: true
}
}));
return transformed;
// ✅ 空结果(没有数据返回时)
return [];
// ✅ 条件返回
if (shouldProcess) {
return [{json: processedData}];
} else {
return [];
}
```
### 错误的返回格式
```javascript
// ❌ 错误:没有数组包裹的对象
return {
json: {field: value}
};
// ❌ 错误:没有 json 包裹的数组
return [{field: value}];
// ❌ 错误:普通字符串
return "processed";
// ❌ 错误:未映射的原始数据
return $input.all(); // 缺少 .map()
// ❌ 错误:结构不完整
return [{data: value}]; // 应该是 {json: value}
```
**重要性**:后续节点期望数组格式。格式错误会导致工作流执行失败。
**详见**:[ERROR_PATTERNS.md](ERROR_PATTERNS.md) #3 获取详细的错误解决方案
---
## 常用模式概览
基于生产工作流,以下是最有用的模式:
### 1. 多源数据聚合
合并来自多个 API、Webhook 或节点的数据
```javascript
const allItems = $input.all();
const results = [];
for (const item of allItems) {
const sourceName = item.json.name || 'Unknown';
// 解析特定源的结构
if (sourceName === 'API1' && item.json.data) {
results.push({
json: {
title: item.json.data.title,
source: 'API1'
}
});
}
}
return results;
```
### 2. 使用正则过滤
从文本中提取模式、提及或关键词
```javascript
const pattern = /b([A-Z]{2,5})b/g;
const matches = {};
for (const item of $input.all()) {
const text = item.json.text;
const found = text.match(pattern);
if (found) {
found.forEach(match => {
matches[match] = (matches[match] || 0) + 1;
});
}
}
return [{json: {matches}}];
```
### 3. 数据转换与增强
映射字段、规范化格式、添加计算字段
```javascript
const items = $input.all();
return items.map(item => {
const data = item.json;
const nameParts = data.name.split(' ');
return {
json: {
first_name: nameParts[0],
last_name: nameParts.slice(1).join(' '),
email: data.email,
created_at: new Date().toISOString()
}
};
});
```
### 4. 前 N 名过滤与排名
排序并限制结果数量
```javascript
const items = $input.all();
const topItems = items
.sort((a, b) => (b.json.score || 0) - (a.json.score || 0))
.slice(0, 10);
return topItems.map(item => ({json: item.json}));
```
### 5. 聚合与报告
求和、计数、分组数据
```javascript
const items = $input.all();
const total = items.reduce((sum, item) => sum + (item.json.amount || 0), 0);
return [{
json: {
total,
count: items.length,
average: total / items.length,
timestamp: new Date().toISOString()
}
}];
```
**详见**:[COMMON_PATTERNS.md](COMMON_PATTERNS.md) 获取 10 个详细的生产模式
---
## 错误预防 - 前 5 大错误
### #1:代码为空或缺少返回(最常见)
```javascript
// ❌ 错误:没有 return 语句
const items = $input.all();
// ... 处理代码 ...
// 忘记返回了!
// ✅ 正确:始终返回数据
const items = $input.all();
// ... 处理 ...
return items.map(item => ({json: item.json}));
```
### #2:表达式语法混淆
```javascript
// ❌ 错误:在代码中使用 n8n 表达式语法
const value = "{{ $json.field }}";
// ✅ 正确:使用 JavaScript 模板字符串
const value = `${$json.field}`;
// ✅ 正确:直接访问
const value = $input.first().json.field;
```
### #3:错误的返回包装器
```javascript
// ❌ 错误:返回对象而非数组
return {json: {result: 'success'}};
// ✅ 正确:必须使用数组包裹
return [{json: {result: 'success'}}];
```
### #4:缺少空值检查
```javascript
// ❌ 错误:如果字段不存在会崩溃
const value = item.json.user.email;
// ✅ 正确:使用可选链安全访问
const value = item.json?.user?.email || '[email protected]';
// ✅ 正确:卫语句
if (!item.json.user) {
return [];
}
const value = item.json.user.email;
```
### #5:Webhook Body 嵌套
```javascript
// ❌ 错误:直接访问 Webhook 数据
const email = $json.email;
// ✅ 正确:Webhook 数据在 .body 下
const email = $json.body.email;
```
**详见**:[ERROR_PATTERNS.md](ERROR_PATTERNS.md) 获取全面错误指南
---
## 内置函数与辅助工具
### $helpers.httpRequest()
在代码中发起 HTTP 请求:
```javascript
const response = await $helpers.httpRequest({
method: 'GET',
url: 'https://api.example.com/data',
headers: {
'Authorization': 'Bearer token',
'Content-Type': 'application/json'
}
});
return [{json: {data: response}}];
```
### DateTime (Luxon)
日期和时间操作:
```javascript
// 当前时间
const now = DateTime.now();
// 格式化日期
const formatted = now.toFormat('yyyy-MM-dd');
const iso = now.toISO();
// 日期计算
const tomorrow = now.plus({days: 1});
const lastWeek = now.minus({weeks: 1});
return [{
json: {
today: formatted,
tomorrow: tomorrow.toFormat('yyyy-MM-dd')
}
}];
```
### $jmespath()
查询 JSON 结构:
```javascript
const data = $input.first().json;
// 过滤数组
const adults = $jmespath(data, 'users[?age >= `18`]');
// 提取字段
const names = $jmespath(data, 'users[*].name');
return [{json: {adults, names}}];
```
**详见**:[BUILTIN_FUNCTIONS.md](BUILTIN_FUNCTIONS.md) 获取完整参考
---
## 最佳实践
### 1. 始终验证输入数据
```javascript
const items = $input.all();
// 检查数据是否存在
if (!items || items.length === 0) {
return [];
}
// 验证结构
if (!items[0].json) {
return [{json: {error: 'Invalid input format'}}];
}
// 继续处理...
```
### 2. 使用 Try-Catch 进行错误处理
```javascript
try {
const response = await $helpers.httpRequest({
url: 'https://api.example.com/data'
});
return [{json: {success: true, data: response}}];
} catch (error) {
return [{
json: {
success: false,
error: error.message
}
}];
}
```
### 3. 优先使用数组方法而非循环
```javascript
// ✅ 优:函数式方法
const processed = $input.all()
.filter(item => item.json.valid)
.map(item => ({json: {id: item.json.id}}));
// ❌ 劣:手动循环
const processed = [];
for (const item of $input.all()) {
if (item.json.valid) {
processed.push({json: {id: item.json.id}});
}
}
```
### 4. 尽早过滤,延迟处理
```javascript
// ✅ 优:先过滤以减少处理量
const processed = $input.all()
.filter(item => item.json.status === 'active') // 先缩小数据集
.map(item => expensiveTransformation(item)); // 然后转换
// ❌ 劣:转换所有内容后再过滤
const processed = $input.all()
.map(item => expensiveTransformation(item)) // 浪费 CPU
.filter(item => item.json.status === 'active');
```
### 5. 使用描述性的变量名
```javascript
// ✅ 优:意图清晰
const activeUsers = $input.all().filter(item => item.json.active);
const totalRevenue = activeUsers.reduce((sum, user) => sum + user.json.revenue, 0);
// ❌ 劣:用途不明
const a = $input.all().filter(item => item.json.active);
const t = a.reduce((s, u) => s + u.json.revenue, 0);
```
### 6. 使用 console.log() 调试
```javascript
// 调试语句会出现在浏览器控制台中
const items = $input.all();
console.log(`Processing ${items.length} items`);
for (const item of items) {
console.log('Item data:', item.json);
// 处理...
}
return result;
```
---
## 何时使用 Code 节点
在以下情况下使用 Code 节点:
- ✅ 需要多个步骤的复杂转换
- ✅ 自定义计算或业务逻辑
- ✅ 递归操作
- ✅ 具有复杂结构的 API 响应解析
- ✅ 多步条件判断
- ✅ 跨项目的数据聚合
考虑使用其他节点的情况:
- ❌ 简单字段映射 → 使用 **Set** 节点
- ❌ 基础过滤 → 使用 **Filter** 节点
- ❌ 简单条件判断 → 使用 **IF** 或 **Switch** 节点
- ❌ 仅发起 HTTP 请求 → 使用 **HTTP Request** 节点
**Code 节点的优势**:处理那些需要链接许多简单节点才能实现的复杂逻辑。
---
## 快速参考清单
在部署 Code 节点前,请核对:
- [ ] **代码不为空** - 必须包含有意义的逻辑
- [ ] **存在 return 语句** - 必须返回对象数组
- [ ] **返回格式正确** - 每个项目:`{json: {...}}`
- [ ] **数据访问正确** - 使用 `$input.all()`、`$input.first()` 或 `$input.item`
- [ ] **无 n8n 表达式** - 使用 JavaScript 模板字符串:`` `${value}` ``
- [ ] **错误处理** - 针对 null/undefined 输入的保护子句
- [ ] **Webhook 数据** - 如果来自 Webhook,通过 `.body` 访问
- [ ] **模式选择** - 大多数情况下选择“所有项目”
- [ ] **性能** - 优先使用 map/filter 而非手动循环
- [ ] **输出一致性** - 所有代码路径返回相同的结构
---
## 额外资源
### 相关文件
- [DATA_ACCESS.md](DATA_ACCESS.md) - 全面的数据访问模式
- [COMMON_PATTERNS.md](COMMON_PATTERNS.md) - 10 个经过生产测试的模式
- [ERROR_PATTERNS.md](ERROR_PATTERNS.md) - 前 5 大错误及解决方案
- [BUILTIN_FUNCTIONS.md](BUILTIN_FUNCTIONS.md) - 完整的内置参考
### n8n 官方文档
- Code 节点指南: https://docs.n8n.io/code/code-node/
- 内置方法: https://docs.n8n.io/code-examples/methods-variables-reference/
- Luxon 文档: https://moment.github.io/luxon/
---
**准备好在 n8n Code 节点中编写 JavaScript 了!** 从简单的转换开始,参考错误模式指南避免常见错误,并查阅模式库获取生产就绪的示例。
数据来源:claude-code-templates(MIT),中文翻译由 AI 生成。详见关于我们。
粤公网安备44030002003366号