mcpField
N
n8n-code-nodes

n8n-code-nodes

github.com/n8n-io開発558348 回インストール2 週間前に更新
リポジトリ

n8n-code-nodes について

n8n の Code ノードの選択と記述を案内するスキルです。単純な変換には式や Edit Fields を優先し、広いデータ範囲やライブラリが必要な場合に JavaScript を使う判断を支援します。

主な機能

  1. 01式、Edit Fields、Code の選択ガイド
  2. 02全アイテムを対象とする集約例
  3. 03JavaScript Code ノードの記述パターン
  4. 04一般的な処理での標準ノード活用指針

活用シーン

  1. 01データ変換に適したノードの選択
  2. 02複数ソースのデータ結合と集約
  3. 03標準ノードで独自コードを置き換えられるかの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/n8n-io/skills --skill n8n-code-nodes

インストール後、Claude Code で/n8n-code-nodesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
ARROW_FUNCTIONS_IN_EDIT_FIELDS.md
DECISION_TREE.md
JAVASCRIPT_PATTERNS.md

詳細

n8n コードノード

コードノードは強力ですが、選ぶべきではない場合も多くあります。ORM で済むのに生の SQL に切り替えるようなものです。実際に必要なケースはありますが、式で実現できるロジックをコードノードで処理すると、ワークフローの可読性、デバッグのしやすさ、保守性が損なわれます。パフォーマンスにも大きな差があります。コードはサンドボックス化された JS ランタイムで実行されますが、式と Edit Fields はプロセス内で実行されます。呼び出しごとのオーバーヘッドはコードのほうが数百倍高くなる場合があります(同等のロジックで、経験則では約 2ms 対約 600ms)。頻繁に実行される処理や大量のアイテムを扱う場合、この差は積み重なります。

基本方針

  1. コードノードは最終手段です。 判断の順序は、式({{...}})→ Edit Fields 内のアロー関数 → コードノードです。最初の 2 つで、「このデータを変換する」タスクの大半に対応できます。コードノードを使う価値があるのは、複数ソースの集約、外部ライブラリの利用、そして以下で説明する一部の特定パターンです。

  2. 基本は JavaScript にします。 ユーザーが Python を明示的に指定した場合(「ここでは Python を使って」「Python を使っているので」、Python コードの貼り付けなど)を除き、JS を使います。n8n のほかのすべての場所(式、Edit Fields)は JS であり、JS には厳選されたライブラリの許可リスト(lodash、crypto、luxon)があります。

判断フロー

Need custom logic?
├── Is it a transformation of one or two fields?
│   └── Expression: {{ $json.foo.toUpperCase() }} or {{ $json.items.map(item => item.name).join(', ') }}
│       Most "just transform this" cases land here.
│
├── Is it multi-line, but pure data shaping (map, filter, reduce, conditional)?
│   └── Edit Fields with arrow function expression. See references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md
│
├── Does it need full statements, multiple data sources, or external libs?
│   ├── Are you SURE the above two don't work?
│   │   └── Re-read the parent. The bar is high.
│   └── Yes, genuinely needs it
│       └── Code node. See references/JAVASCRIPT_PATTERNS.md
│
└── Is it actually two separate transformations stitched together?
    └── Use two nodes (Edit Fields → Edit Fields, or Edit Fields → IF). Composability beats one big Code block.

各分岐の例を含む判断ロジックの全体については、references/DECISION_TREE.md を参照してください。

忘れられがちな式の機能

コードノードを使いたくなりがちな一般的なケースでも、式で対応できます。

// ❌ Code node
return { name: $input.first().json.name.toUpperCase() }

// ✅ Expression in Edit Fields, "name" field
{{ $json.name.toUpperCase() }}
// ❌ Code node
const items = $input.first().json.items
return { tags: items.map(item => item.tag).filter(tag => tag).join(', ') }

// ✅ Expression
{{ $json.items.map(item => item.tag).filter(tag => tag).join(', ') }}
// ❌ Code node
const date = new Date($input.first().json.created_at)
return { formatted: date.toISOString().slice(0, 10) }

// ✅ Expression with n8n's date extension
{{ $json.created_at.toDateTime().format('yyyy-MM-dd') }}

式でできることの詳細については、n8n-expressions スキルを参照してください。

Edit Fields 内のアロー関数でできること

Edit Fields は、式を使ってフィールドの値を設定します。インラインのアロー関数を使えば、コードノードを使わずに、複数行にわたるロジックの大半を記述できます。

// In Edit Fields, "summary" field:
{{ (() => {
    const items = $json.items
    const total = items.reduce((sum, item) => sum + item.price, 0)
    const tax = total * 0.08
    return `Total: $${(total + tax).toFixed(2)}`
})() }}

「ワンライナーにするには少し複雑すぎるロジック」には、これが適切な方法です。パターンや書式については、references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md を参照してください。

コードノードが適切な選択肢となる場合

実際に必要なケースはあります。基準は高く設定されていますが、「決して使わない」という意味ではありません。以下のケースは正当な用途です。ためらわずにコードを使ってください。

データセット全体にわたる複数ソースの集約

ノードで次の処理が必要な場合です。

  • 複数の上流ノードを同時に読み取る(例:$('Source A').all()、$('Source B').all()、$('Source C').first().json)。
  • すべてのアイテムをまとめて(アイテムごとではなく)統計情報や変換を計算する。
  • 中間データ構造(ルックアップマップ、アキュムレーター、比率)を使った複数ステップのロジックを適用する。

最も一般的な正当なケースです。例:

  • 分析結果の集計:グループごとの平均、パーセンタイルスコア、カテゴリ間の正規化。
  • あるソースからルックアップテーブルを作成し、別のソースの行と結合する。
  • 2 つの参照データセット間でオフセットや比率を計算し、それを 3 つ目のデータセットに適用する。
// Real-world shape: aggregate test results from one source,
// model metadata from another, category mapping from a third,
// and produce per-model-per-category averages.

const testResults = $('Get Test Results').all().map(item => item.json)
const models = $('Get Models').all().map(item => item.json)
const categoryMap = $('Get Category Map').first().json.testCategoryMap

const categoryByTestId = Object.fromEntries(
    categoryMap.map(mapping => [mapping.testId, mapping.category])
)

const result = models.map(model => {
    const modelTests = testResults.filter(test => test.modelId === model.id)
    const stats = modelTests.reduce((acc, test) => {
        const cat = categoryByTestId[test.testId]
        if (!cat) return acc
        acc[cat] ??= { scored: 0, available: 0, count: 0 }
        acc[cat].scored += test.pointsScored ?? 0
        acc[cat].available += test.pointsAvailable ?? 0
        acc[cat].count += 1
        return acc
    }, {})

    const averages = Object.fromEntries(
        Object.entries(stats).map(([category, stat]) => [
            category,
            { avg: stat.available > 0 ? stat.scored / stat.available : 0, n: stat.count }
        ])
    )

    return { modelId: model.id, modelName: model.modelName, ...averages }
})

return result.map(json => ({ json }))

技術的には、式でも $('Node Name').all() を使ってアイテムをまたいでデータにアクセスし、インラインで reduce できます。しかし、これほど複雑な構造(結合、グループ化、ネストされた集約)を扱うと、結果は読みづらくデバッグもできない一行の巨大な式になります。コードノードを使ってください。

外部ライブラリ

JS コードでは厳選された許可リスト(lodash など)から require できますが、式ではできません。

まず、標準ノードがないか必ず確認してください。 n8n には、思われているより多くの標準ノードがあります。標準ノードでできることにコードノードを使ってしまうのは、よくある間違いです。次の 2 つの節では、特に注意すべきケースを説明します。

暗号処理にはコードではなく Crypto ノードを使う

HMAC、署名、ハッシュ化、暗号化には、n8n に標準の Crypto ノード(n8n-nodes-base.crypto)があります。 使ってください。JavaScript を書かずに、SHA256、MD5、HMAC、暗号化/復号、乱数生成に対応できます。

// WRONG (recurring AI slip):
const crypto = require('crypto')
const hash = crypto.createHash('sha256').update(buf).digest('hex').slice(0, 12)

// RIGHT: configure the Crypto node with operation: 'hash', type: 'SHA256'
//   then read $('Hash').item.json.<output> downstream.

require('crypto') を使うコードのパターンは、「コードノードが必要」と誤って判断される最も一般的な例の 1 つです。必要ありません。Crypto ノードで対応できます。

文字列ではなくバイナリをハッシュする

バイナリ(PDF、画像、ファイルバッファー)をハッシュする必要があるからといって、すぐに Code を使わないでください。Crypto ノードには binaryPropertyName パラメーターがあります。バイナリスロットのキーを指定すれば、バッファーを直接ハッシュできます。ユーザーコードで this.helpers.getBinaryDataBuffer(...) を使う必要はありません。

// WRONG (recurring AI slip with binary):
const crypto = require('crypto')
const buf = await this.helpers.getBinaryDataBuffer($itemIndex, 'data')
const hash = crypto.createHash('sha256').update(buf).digest('hex')

// RIGHT: Crypto node configured to hash binaryPropertyName='data', SHA256.
//   Then $('Crypto').item.json.<output> has the hash; chain a Set node for any field shaping.

Crypto に関して Code が有効なのは、Crypto ノードが対応していない非標準の署名方式(たとえば、カスタムの AWS 形式の署名)が必要で、かつ httpCustomAuth 認証情報も適合しない場合です。まれなケースです。理由を明確に説明してください。

XML/SOAP/RSS の解析:Code ではなく XML ノードを使う

n8n には、解析と文字列化の操作を備えたネイティブの XML ノード(n8n-nodes-base.xml)があります。 XML をすでに JSON に変換できます。変換後は通常の JSON なので、Edit Fields のアロー関数式で、Code を使いたくなるようなフィールドの抽出、配列の正規化(Array.isArray(...) ? ... : ...)、リンクの検索(.find())に対応できます。

// WRONG (recurring AI slip):
// XML node already parsed → another Code node to extract a few fields:
const entry = $('Parse XML').item.json.feed.entry
const firstEntry = Array.isArray(entry) ? entry[0] : entry
return { json: { title: firstEntry.title, url: firstEntry.link.find(link => link.type === 'pdf').href } }

// RIGHT: Edit Fields with arrow function expressions:
//   title:  ={{ (() => { const entry = $('Parse XML').item.json.feed.entry; return Array.isArray(entry) ? entry[0].title : entry.title; })() }}
//   pdfUrl: ={{ $('Parse XML').item.json.feed.entry.link.find(link => link.type === 'pdf')?.href }}

複数行のアロー関数を使ってもインライン式ではフィールド抽出ロジックが複雑すぎる場合は、次に試すのは Code ノードではなく、複数行のアロー関数を 1 つ使った Edit Fields です。references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.md を参照してください。

これらに共通する点

有効なケースは、スコープに関するものです。データセット全体、複数のソース、または単一アイテム用ツールでは対応できないステートフルな構成が該当します。無効なケースは、式でできること、またはネイティブノードですでにできることを Code で行う場合です。

簡単な確認方法:

  • 「この Code ノードの役割を『この 1 つのアイテムを受け取り、…する』と説明できますか?」 はいなら、ツールの選択が間違っています。
  • 「これに対応するネイティブノードはありますか?」 まず search_nodes で検索してください。Crypto、XML、JSON 解析、日付計算(Luxon)、HTTP 呼び出し、ファイル I/O、正規表現によるマッチングには、すべてネイティブノードまたは式レベルのサポートがあります。

JavaScript Code ノードの詳細

2 つのモードがあります。

  • Run Once for All Items(デフォルト。これを使用): $input.all() を使って 1 回実行します。アイテムごとのロジックが必要な場合は、内部で for (const item of $input.all()) を使用してください。これが標準的な形式で、ほとんどの場合に適しています。
  • Run Once for Each Item: $input.first()(または $input.item)を使って、アイテムごとに 1 回実行します。

一般的な形式:

// Run Once for All Items
const items = $input.all()
const totals = items.map(item => ({
  ...item.json,
  total: item.json.qty * item.json.price,
}))
return totals.map(json => ({ json }))

戻り値は { json: ... } オブジェクト(または { json: ..., binary: ... })の配列にする必要があります。生の JSON を返すことはできません。

バイナリの処理、エラーパターン、Code ノード固有のバグについては、references/JAVASCRIPT_PATTERNS.md を参照してください。

リファレンスファイル

ファイル読むタイミング
references/DECISION_TREE.mdCode ノードを使いたくなったとき、よりシンプルな方法が本当に使えないか確認する
references/ARROW_FUNCTIONS_IN_EDIT_FIELDS.mdデータの整形だけで、変換が複数行になるとき
references/JAVASCRIPT_PATTERNS.mdCode ノードが本当に必要で、言語に JavaScript を使うとき

アンチパターン

アンチパターン問題点修正方法
Code ノードで return { x: $input.first().json.x.toUpperCase() } を実行する1 つの式のためにノード全体を使っているEdit Fields の式に置き換える
Code ノードでメール本文用の HTML 文字列を組み立てるEmail ノードの本文フィールドでは式を使用できる式を Email ノードに直接記述する
Code ノードで日付の書式設定に new Date() を使うLuxon の明快さに劣る式で Luxon を使う。n8n-expressions を参照
Set ノードと Code ノードの組み合わせ(Set で入力を作成し、Code で変換する)1 つの Edit Fields ノードで済む処理に 2 つのノードを使っているアロー関数を使った 1 つの Edit Fields にまとめる
認証情報やトークンを Code ノードのテキストに貼り付けるテキストフィールドと同じ情報漏えいが起きるCode ノードではなく、認証情報を使う

コメント