mcpField
N
n8n-code-javascript

n8n-code-javascript

github.com/czlonkowski開発23.2k86 回インストール4 日前に更新
リポジトリ

n8n-code-javascript について

n8n Code ノードで JavaScript を書くためのガイドスキルです。ワークフロー構築者向けに、実行モードやデータアクセス、戻り値、サンドボックスの注意点を説明します。

主な機能

  1. 01一括または項目ごとの実行モード選択
  2. 02入力と Webhook データの読み取り
  3. 03有効な n8n アイテムの返却
  4. 04JavaScript によるデータ変換パターン
  5. 05サンドボックスのヘルパーとモジュールの説明

活用シーン

  1. 01ワークフロー項目の集計やフィルタリング
  2. 02Code ノードでのデータ変換
  3. 03戻り値形式エラーの調査

インストール

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

$npx skills add https://github.com/czlonkowski/n8n-mcp --skill n8n-code-javascript

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

同梱ファイル

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

BUILTIN_FUNCTIONS.md
COMMON_PATTERNS.md
DATA_ACCESS.md
ERROR_PATTERNS.md
README.md

詳細

JavaScript コードノード

n8n の Code ノードで JavaScript コードを書くための専門的なガイダンスです。


クイックスタート

// Basic template for Code nodes
const items = $input.all();

// Process data
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: {...}}] を返します — これはモード間で移植可能な標準形式です。Run Once for All Items モードでは、return {…} のようなオブジェクトだけを返しても n8n が自動的にラップするため、こちらも動作します。本当にエラーになるのは、プリミティブ値(文字列/数値)または null を返した場合です。
  4. 重要:Webhook データは $json 直下ではなく、$json.body の下にあります。
  5. 利用可能な組み込み機能:this.helpers.httpRequest()(認証なし — タスクランナーのサンドボックスでは、単独の $helpers グローバルは 未定義 であるため、$helpers.httpRequest() は ReferenceError: $helpers is not defined をスローします)、DateTime(Luxon)、$jmespath()。利用できない機能:this.helpers.httpRequestWithAuthentication(許可リストで禁止されています)、$env(N8N_BLOCK_ENV_ACCESS_IN_NODE=true の場合)、require()(許可リストにある場合を除く)。単純な認証なし GET 以外(認証、ページネーション、再試行)には、HTTP Request ノードを優先し、Code ノードは純粋なロジックに使用します。
  6. インスタンスで許可リストに登録されたライブラリ:セルフホストのインスタンスでは、N8N_RUNNERS_ALLOWED_BUILT_IN_MODULES および N8N_RUNNERS_ALLOWED_EXTERNAL_MODULES(旧設定:NODE_FUNCTION_ALLOW_BUILTIN/NODE_FUNCTION_ALLOW_EXTERNAL)を使ってモジュールを許可リストに登録できます。ユーザーがインスタンスで特定のモジュール(例:axios、lodash、crypto)を許可していると伝えた場合は、require() で使用し、拒否しないでください。不明な場合は確認するか、組み込み機能のみを使用することを既定とします。
  7. 別のスキルが必要ですか? AI Agent にアタッチされた Custom Code Tool(@n8n/n8n-nodes-langchain.toolCode)向けのコードを書く場合は、そこで作業を中止してください。このノードは契約が異なります(入力は query 経由、文字列を返す必要があり、$input/$helpers はありません)。n8n-code-tool スキルを使用してください。

モード選択ガイド

Code ノードには 2 つの実行モードがあります。ユースケースに合わせて選択してください。

Run Once for All Items(推奨 - デフォルト)

このモードの使用対象: ユースケースの 95%

  • 仕組み:入力数にかかわらず、コードを 1 回 実行します
  • データアクセス:$input.all() または items 配列
  • 最適な用途:集計、フィルタリング、バッチ処理、変換、すべてのデータを使った API 呼び出し
  • パフォーマンス:複数のアイテムを処理する場合に高速です(実行は 1 回)
// Example: Calculate total from all items
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
  }
}];

使用する場合:

  • ✅ データセット内の複数のアイテムを比較する
  • ✅ 合計、平均、統計値を計算する
  • ✅ アイテムを並べ替えたり、順位付けしたりする
  • ✅ 重複を排除する
  • ✅ 集計レポートを作成する
  • ✅ 複数のアイテムのデータを結合する
Run Once for Each Item

このモードの使用対象: 特定のケースのみ

  • 仕組み:入力アイテムごとにコードを 個別に 実行します
  • データアクセス:$input.item または $item
  • 最適な用途:アイテム固有のロジック、独立した処理、アイテムごとの検証
  • パフォーマンス:大規模なデータセットでは低速です(複数回実行)
// Example: Add processing timestamp to each item
const item = $input.item;

return [{
  json: {
    ...item.json,
    processed: true,
    processedAt: new Date().toISOString()
  }
}];

使用する場合:

  • ✅ 各アイテムで個別の API 呼び出しが必要な場合
  • ✅ エラー処理が異なる、アイテムごとの検証が必要な場合
  • ✅ アイテムのプロパティに応じた、アイテム固有の変換を行う場合
  • ✅ ビジネスロジック上、アイテムを個別に処理する必要がある場合

選択の目安:

  • 複数のアイテムを参照する必要がありますか? → 「All Items」モードを使用します
  • 各アイテムは完全に独立していますか? → 「Each Item」モードを使用します
  • 判断できませんか? → 「All Items」モードを使用します(必要に応じて内部でループできます)
「All Items」がより高速な理由 — アイテムごとの境界

Code ノードでは、モードの選択がパフォーマンスに最も大きく影響します。アイテムごとの実行コンテキストには、それぞれセットアップコストがかかります(n8n 2.x、小さなレコードで測定)。

アイテムごとに実行されるものおおよそのコスト
Code All Items(全体を一度に実行)約0.02 ms/アイテム
任意のノードの式(IF / Set など)約0.2 ms/アイテム
Code Each Item(アイテムごとに完全なサンドボックス)約0.6 ms/アイテム — All Items の約25〜30倍

10k件のアイテムに対して Run Once for Each Item を使用すると、純粋なオーバーヘッドだけで約6秒かかりますが、Run Once for All Items なら約0.2秒です。各アイテムを個別に処理する必要が本当にある場合(個別のエラー処理や、バッチ化できないアイテムごとのAPI呼び出しなど)に限り、Each Item を使用してください。それ以外の場合は、1つの All Items ノード内でループします。式の複雑さによるコストは実質的に無視できるほど小さく(コストの約90%はコードではなく、アイテムごとのコンテキストによるものです)、ノード間のホップごとにすべてのアイテムが再コピーされます。そのため、それぞれを細かく最適化するのではなく、アイテムごとの境界の数を減らしてください。数百件未満なら、これらは問題になりません。大量のアイテムを処理し、I/Oが少ないホットパスで活用してください。

参照:DATA_ACCESS.md → 「Mode Performance」で、関連事項、ホップのコスト、スケールの確認方法を説明しています。


データアクセスのパターン

上流ノードからデータを取得する4つの方法です。$node["Name"] と $('Name') では .first().json または .all() が必要です。.json を直接使うことはできません。

const allItems = $input.all();          // 1. All items — batch ops, aggregation (most common)
const data = $input.first().json;       // 2. First item — single objects, API responses
const item = $input.item;               // 3. Current item — "Each Item" mode ONLY (undefined otherwise)
const other = $node["Webhook"].json;    // 4. Named node — combine data across nodes

フィールドには必ず .json 経由でアクセスしてください(例:item.json.name。item.name ではありません)。また、単独の $json.field より、明示的な $input.first().json.field を優先してください。

参照:DATA_ACCESS.md に完全なガイドがあります。各パターンの例、判断ツリー、よくあるミス(元データの変更、長さチェックの欠落、誤ったモードでの $input.item の使用)を説明しています。


重要:Webhook のデータ構造

最もよくあるミス:Webhook データは .body の下にネストされています。

// ❌ WRONG - Will return undefined
const name = $json.name;
const email = $json.email;

// ✅ CORRECT - Webhook data is under .body
const name = $json.body.name;
const email = $json.body.email;

// Or with $input
const webhookData = $input.first().json.body;
const name = webhookData.name;

理由:Webhook ノードはすべてのリクエストデータを body プロパティの下に格納します。これには POST データ、クエリパラメーター、JSON ペイロードが含まれます。

参照:DATA_ACCESS.md で Webhook のデータ構造の詳細を確認してください。


戻り値の形式に関する要件

標準形式:[{json: {...}}] — 各オブジェクトが json プロパティを持つオブジェクトの配列です。曖昧さがなく、どちらの実行モードでも同じように動作するため、デフォルトとして使用してください。

Run Once for All Items モードでは、n8n は出力時に緩い形式を自動で正規化します。単一の json を持たないオブジェクトや、json を持たないオブジェクトの配列は、自動的に json の下にラップされます。そのため、return {foo: 1} は実行できます。一方、ラップする対象がなく、実行時に「Code doesn't return items properly」エラーになるのは、プリミティブ値(文字列/数値/ブール値)または null/undefined です。(n8n-mcp ≥ 2.63.0 では、オブジェクトをそのまま返してもエラーとして扱われなくなりました。これは、この自動ラップ動作を反映しています。)

正しい戻り値の形式
// ✅ Single result
return [{
  json: {
    field1: value1,
    field2: value2
  }
}];

// ✅ Multiple results
return [
  {json: {id: 1, data: 'first'}},
  {json: {id: 2, data: 'second'}}
];

// ✅ Transformed array
const transformed = $input.all()
  .filter(item => item.json.valid)
  .map(item => ({
    json: {
      id: item.json.id,
      processed: true
    }
  }));
return transformed;

// ✅ Empty result (when no data to return)
return [];

// ✅ Conditional return
if (shouldProcess) {
  return [{json: processedData}];
} else {
  return [];
}
標準形式ではない戻り値(自動でラップされます — 標準形式を推奨)
// ⚠️ Auto-wrapped in All Items mode → [{json: {field: value}}]. Runs, but prefer the array form.
return {
  json: {field: value}
};

// ⚠️ Auto-wrapped → [{json: {field: value}}]. Runs, but add the json wrapper for clarity.
return [{field: value}];

// ✅ Fine — input items already carry a json property, so returning them unchanged is a valid passthrough
return $input.all();
実際に無効な戻り値
// ❌ FAILS: primitive — n8n errors "Code doesn't return items properly"
return "processed";

// ❌ FAILS: null / undefined — nothing to pass to the next node
return null;

重要な理由:標準形式の [{json: {...}}] は曖昧さがなく、どちらのモードでも同じように動作します。n8n は All Items モードで、オブジェクト単体やオブジェクトの配列を自動的に正規化します。しかし、プリミティブ値や null の戻り値にはラップする対象がないため、実行が停止します。

参照:ERROR_PATTERNS.md #3 で、エラーの詳しい解決方法を確認してください。


よく使うパターンの概要

本番ワークフローでよく使われる Code ノードの形を紹介します。まずは簡単な例として、すべてのアイテムを合計・集計します。

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 } }];

完全なライブラリには10種類のパターンが含まれています。複数ソースの集計、正規表現によるフィルタリング、Markdown/構造化テキストの解析、JSON の比較、CRM/フォームの変換、リリース処理、計算フィールドを使った配列変換、Slack Block Kit の書式設定、上位N件のランキング、文字列集計レポートなどがあり、それぞれにバリエーションがあります。

参照:COMMON_PATTERNS.md に、本番で使える10種類の詳しいパターンがあります(また、ベストプラクティスのセクションでは、入力値の検証、try-catch、早期のフィルタリング、ループより配列メソッドを使う方法、console.log によるデバッグを紹介しています)。


エラーの防止 - よくある間違い

Code ノードで繰り返し発生する失敗を、おおよその頻度順に示します。

  1. コードが空/return がない — 必ず最後に return [...] を記述し、すべての分岐で値を返すようにしてください。
  2. 式の構文をコードとして使用 — JavaScript を記述する場所に {{ }} を書かないでください(return {{ $json.x }} は構文エラーです)。`${$json.field}` または $input.first().json.field を使用してください。文字列リテラル内の {{ }} は問題ありません。n8n が評価しない、単なる文字列です。
  3. 戻り値の形式 — return [{json:{...}}] を推奨します。単独の return {…} は All Items モードで自動的にラップされますが、実際にエラーになるのはプリミティブ値(文字列/数値)や null を返した場合です。
  4. null チェックがない — オプショナルチェーンを使用してください:item.json?.user?.email || 'fallback'。
  5. Webhook の本文のネスト — $json.email は未定義です。$json.body.email を使用してください。
  6. 認証ヘルパーがブロックされる(httpRequestWithAuthentication)および $env がブロックされる — シークレットは Code ノードのサンドボックスではなく、クレデンシャル/HTTP Request ノード経由で扱ってください。

参照:ERROR_PATTERNS.md には包括的なガイドがあります。各エラーの誤ったコードと正しいコード、エスケープのルール、サンドボックスの制限(エラー #6~#7)、防止チェックリスト、エラーメッセージのクイック検索表を掲載しています。


組み込み関数とヘルパー

// HTTP requests (no auth — see sandbox note below)
const res = await this.helpers.httpRequest({ method: 'GET', url: 'https://api.example.com/data' });

// DateTime (Luxon): now, formatting, arithmetic
const now = DateTime.now();
const formatted = now.toFormat('yyyy-MM-dd');
const tomorrow = now.plus({ days: 1 });

// $jmespath() — query JSON structures
const adults = $jmespath($input.first().json, 'users[?age >= `18`]');

// $getWorkflowStaticData() — data that persists across executions

サンドボックス(n8n v2.0 の JsTaskRunnerSandbox 以降):アクセサーは this.helpers.httpRequest() です。この環境では $helpers グローバルは未定義です($helpers.httpRequest() は ReferenceError をスローします)。this が失われるネストされた非同期関数内では、await fn.call(this, ...) のように呼び出してください。this.helpers.httpRequestWithAuthentication と this.helpers.requestWithAuthenticationPaginated は拒否リストに登録されています(→ UnsupportedFunctionError)。認証付きの呼び出しには、クレデンシャルを設定した HTTP Request ノード(推奨)、サブワークフロー、またはトークンがすでにワークフロー内をデータとして流れている場合に限り this.helpers.httpRequest() に手動で Authorization: Bearer ${token} ヘッダーを指定する方法を使用してください。N8N_BLOCK_ENV_ACCESS_IN_NODE=true の場合、$env はブロックされます。require() が機能するのは、許可リストに登録されたモジュールのみです。Buffer、URL、および標準の JavaScript グローバル(Math、JSON、Object、Array)は常に使用できます。

参照:BUILTIN_FUNCTIONS.md には完全なリファレンスがあります。httpRequest の全オプション、DateTime/Luxon のすべての操作、JMESPath のパターン、静的データの使用例、サンドボックス制限の詳細を掲載しています。


ベストプラクティス

  • 最初に入力を検証する — 処理の前に、配列が空でないか、.json が存在するかを確認してください。
  • リスクのある処理(HTTP 呼び出しなど)は try-catch で囲む。クラッシュさせず、エラーオブジェクトを返してください。
  • 手動のループより配列メソッド(filter/map/reduce)を優先してください。
  • 早めにフィルタリングし、変換は後で行う — コストのかかる処理の前にデータセットを絞り込んでください。
  • わかりやすい名前を付け、デバッグには console.log() を使用してください(出力はブラウザーのコンソールに表示されます)。

参照:COMMON_PATTERNS.md →「ベストプラクティス」には、それぞれのコード例があります。


本番環境での注意点

実際のデプロイで得られた貴重な教訓を、DATA_ACCESS.md →「本番環境での注意点」にまとめています。

  • SplitInBatches の出力は直感に反します:main[0] = 完了(すべてのバッチの処理後に1回だけ実行)、main[1] = 各バッチ(ループ本体)です。安全策として、完了出力の後に Limit 1 ノードを追加してください。
  • コストを左右するのは反復回数です:ループの各反復では、エンジンを通じて本体全体が再実行されます(1回あたり約0.8 msのオーバーヘッド)。batchSize: 1 は Each Item と同等のループです。実際の制約(レート制限、ページサイズ、メモリ)が許す最大のバッチサイズを使用するか、ループ自体を使わないでください。
  • 反復をまたぐ蓄積(重大):ループ後に $('Node Inside Loop').all() を呼び出しても、直近の反復のアイテムだけが返されます。$getWorkflowStaticData('global') を使って蓄積してください(処理前にリセットし、ループ内で追加し、処理後に読み取ります)。
  • pairedItem:入力と1対1に対応しないアイテムを出力する場合は、pairedItem: { item: i } を設定してください。設定しないと、後続の Set ノードで paired_item_no_info エラーが発生します。
  • ノード参照の構文:$('Node').first().json または $('Node').all() を使います。参照に対して .json を直接使ってはいけません。
  • 浮動小数点の精度:浮動小数点の誤差による誤検出を避けるため、通貨はセント単位で比較します。Math.round(a*100) !== Math.round(b*100) を使ってください。

Code ノードを使う場合

Code ノードを使う前に、n8n Expression Syntax スキルの変換ゲートキーパーに従ってください。式 → Edit Fields フィールド内のアロー関数 IIFE → Code ノードの順に検討します。最初の2つの方法で、ほとんどの「このデータを変換する」タスクをそれぞれ約1~10 msで処理できます。一方、サンドボックス内で実行される Code ノードは約500~1000 msかかります。単一アイテムの整形だけなら約100倍の差がありますが、機能上の違いはありません。Code ノードを使う価値があるのは、データセット全体の集計($input.all())、許可リストにあるライブラリの利用、または非同期処理の場合に限られます。また、暗号処理(HMAC、ハッシュ化、署名)や XML/SOAP/RSS の解析をコードで実装する前に、ネイティブノードがないか確認してください。n8n には、JavaScriptを使わずにこれらを処理できる Crypto ノード(nodes-base.crypto)と XML ノード(nodes-base.xml)があります。ネイティブノードでできる処理に Code ノードを使うのは、よくある誤った選択の1つです。

次の場合は Code ノードを使います。

  • ✅ 複数のステップが必要な複雑な変換
  • ✅ カスタム計算やビジネスロジック
  • ✅ 再帰処理
  • ✅ 複雑な構造を持つ API レスポンスの解析
  • ✅ 複数ステップの条件分岐
  • ✅ アイテムをまたぐデータ集計

次の場合は他のノードを検討します。

  • ❌ 単純なフィールドのマッピング → Set ノードを使用
  • ❌ 基本的なフィルタリング → Filter ノードを使用
  • ❌ 単純な条件分岐 → IF または Switch ノードを使用
  • ❌ HTTP リクエストのみ → HTTP Request ノードを使用

Code ノードが得意なこと:単純なノードを多数つなぐ必要がある複雑なロジック


他のスキルとの連携

連携するスキル:

n8n Expression Syntax:

  • 他のノードでは {{ }} 構文を使って式を記述します
  • Code ノードでは JavaScript を直接使います({{ }} は使いません)
  • 式とコードの使い分け

n8n MCP Tools Expert:

  • Code ノードの検索方法:search_nodes({query: "code"})
  • 設定方法の確認:get_node({nodeType: "nodes-base.code"})
  • コードの検証:validate_node({nodeType: "nodes-base.code", config: {...}})

n8n Node Configuration:

  • モードの選択(All Items と Each Item)
  • 言語の選択(JavaScript と Python)
  • プロパティの依存関係の理解

n8n Workflow Patterns:

  • 変換ステップでの Code ノードの使用
  • Webhook → Code → API のパターン
  • ワークフローでのエラー処理

n8n Validation Expert:

  • Code ノードの設定の検証
  • 検証エラーへの対処
  • よくある問題の自動修正

クイックリファレンスチェックリスト

Code ノードをデプロイする前に、以下を確認してください。

  • コードが空でない - 意味のあるロジックが必要です
  • return 文がある - プリミティブ値やnullではなく、アイテムを返します
  • 標準的な戻り値の形式 - 各アイテムは{json: {...}}です(オブジェクトのみでも自動的にラップされますが、明示してください)
  • データアクセスが正しい - $input.all()、$input.first()、または$input.itemを使用しています
  • {{ }}をコードとして記述していない - JavaScript のテンプレートリテラルを使用します:`${value}`
  • エラー処理 - null/undefined の入力に対するガード節があります
  • Webhook データ - Webhook からのデータの場合は.body経由でアクセスします
  • モードの選択 - ほとんどの場合、「All Items」を選択します
  • パフォーマンス - 手動ループよりも map/filter を優先します
  • 一貫した出力 - すべてのコードパスで同じ構造を返します

追加リソース

関連ファイル
n8n のドキュメント

n8n の Code ノードで JavaScript を書く準備ができました! まずは簡単な変換から始め、よくあるミスを避けるためにエラーパターンガイドを活用し、本番環境ですぐに使える例についてはパターンライブラリを参照してください。

コメント