mcpField
E
electron-node-upgrade

electron-node-upgrade

github.com/electron開発123.6k55 回インストール今日更新
リポジトリ

electron-node-upgrade について

Electron の Node.js 依存関係を更新するためのスキルです。パッチ同期、ビルド、テストを段階的に進め、競合の解決と検証を案内します。

主な機能

  1. 013段階のアップグレード手順
  2. 02パッチ競合の解決ガイド
  3. 03ビルドと起動の検証
  4. 04Node.js テストスイートの案内
  5. 05パッチの書き出しとコミット規則

活用シーン

  1. 01Electron の Node.js バージョン更新
  2. 02Node.js パッチの競合解決
  3. 03Node.js API 変更への Electron の適応
  4. 04更新後のビルドとテストの確認

インストール

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

$npx skills add https://github.com/electron/electron --skill electron-node-upgrade

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

同梱ファイル

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

references/
patch-analysis.md
phase-one-commit-guidelines.md
phase-three-commit-guidelines.md
phase-two-commit-guidelines.md

詳細

Electron Node.js アップグレード:フェーズ 1

概要

e sync --3 を繰り返し実行し、パッチの競合が発生したら修正して、成功するまで続けます。その後、パッチをエクスポートし、変更をまとめてコミットします。

完了条件

以下を満たした時点でフェーズ 1 は完了です。

  • e sync --3 がコード 0 で終了する(パッチの失敗がない)
  • コミットガイドラインに従ってすべての変更がコミットされている

これらの条件を満たすまで作業を続けてください。

重大 パッチが不要になったと 100%確信できる場合を除き、パッチを削除したりスキップしたりしないでください。メジャーバージョンのアップグレードでは、非推奨の V8 API に対応する shim や上流の変更をバックポートするパッチは、新しい Node.js バージョンにすでに取り込まれているため削除できることがよくありますが、削除する前に確認してください。複雑な競合や解決が難しい問題については、ほかのすべての選択肢を試し尽くした後でユーザーに提示してください。解決できないという理由だけでパッチを削除しないでください。

重大 git am --skip を使った後、新しいコミットを作成してパッチを手動で再作成することは絶対に避けてください。元のパッチの作成者情報、コミットメッセージ、シリーズ内の位置が失われます。git am --continue が「No changes」と報告した場合は、その理由を調べてください。変更が、先行する競合解決の 3-way マージによってすでに取り込まれている可能性があります。スキップして再作成するのではなく、この状況をユーザーに提示してください。

背景

roller/node/main ブランチは、Electron の DEPS にある Node.js 依存バージョンを更新するため、自動化によって作成されます。旧バージョンと新バージョンの間の破壊的変更に対応する作業は行われていません。

Node.js のバージョン更新には、次の 2 種類があります。

  • バージョン引き上げ(パッチ/マイナー):electron-roller[bot] がコミットタイトル chore: bump node to v{version} で自動化します。簡単なパッチインデックスの更新は patchup[bot] が自動的に処理します。問題なく適用されることが多いものの、パッチを手動で修正する必要がある場合があります。
  • メジャーアップグレード(例:v22 → v24):コミットタイトル chore: upgrade Node.js to v{X}.{Y}.{Z} で手動の大規模な PR を行います。通常、不要になったパッチの削除、多数のパッチの調整、package.json の @types/node の更新を伴います。

主なディレクトリ:

  • 現在のディレクトリ:Electron リポジトリ(e コマンドは必ずここで実行します)
  • ../third_party/electron_node:Node.js リポジトリ(パッチを適用する場所)
  • patches/node/:Node.js 用のパッチファイル
  • docs/development/patches.md:パッチシステムのドキュメント

事前確認

アップグレードセッションの開始時に、以下を 1 回実行してください。

  1. rerere キャッシュをクリアする(有効な場合):Electron リポジトリと ../third_party/electron_node リポジトリの両方で git rerere clear を実行します。以前の試行で記録された古い解決が、誤ったマージを気付かないうちに適用する可能性があります。
  2. pre-commit フックがインストールされていることを確認する:.git/hooks/pre-commit が存在するか確認します。存在しない場合は、yarn husky を実行してインストールします。このフックは lint-staged を実行し、C++ ファイルの clang-format を処理します。
  3. ほかのブランチに同じロールがないか確認する:同じ Node.js バージョンを対象とする roller/node/main と、該当する兄弟ブランチ roller/node/{N}-x-y を fetch します。すでに修正が含まれている場合は、再導出せず、そのまま(パッチ名、内容、コミットタイトル、Ref: 行を含めて)再利用します。references/phase-one-commit-guidelines.md の「兄弟 Roller ブランチからの修正の再利用」を参照してください。

ワークフロー

  1. e sync --3 を実行します(--3 フラグは 3-way マージを有効にします。必ず指定してください)
  2. 成功した場合 → ステップ 5 に進みます
  3. パッチに失敗した場合:
    • エラー出力から対象のリポジトリとパッチを特定します
    • 失敗を分析します(references/patch-analysis.md を参照)
    • ../third_party/electron_node の作業ディレクトリで競合を修正します
    • ../third_party/electron_node で git am --continue を実行します
    • そのリポジトリのすべてのパッチが適用されるまで繰り返します
    • 重要:git am --continue が成功したら、必ず e patches node を実行して修正をエクスポートしてください
    • ステップ 1 に戻ります
  4. e sync --3 が成功したら、e patches all を実行します
  5. ここで references/phase-one-commit-guidelines.md を読み、その指示に正確に従って変更をコミットします。

コマンドリファレンス

コマンド目的
e sync --3依存関係をクローンし、3-way マージでパッチを適用します
git am --continueコンフリクト解消後に続行します(node リポジトリで実行)
e patches nodenode リポジトリからコミットをパッチファイルにエクスポートします
e patches allすべてのターゲットからすべてのパッチをエクスポートします
e patches node --commit-updatesパッチをエクスポートし、些細な変更を自動コミットします
e patches --list-targetsターゲットと設定パスを一覧表示します

パッチシステムのメンタルモデル

patches/node/*.patch  →  [e sync --3]  →  ../third_party/electron_node commits
                      ←  [e patches]   ←

パッチを編集すべきタイミング

状況対応
git am のコンフリクトが発生している最中node リポジトリで修正し、その後 git am --continue を実行します
コンフリクト外でパッチを変更する場合.patch ファイルを直接編集します
新しいパッチを作成する場合(稀、避けること)node リポジトリでコミットし、その後 e patches node を実行します

新しいパッチを作成するのではなく、99% のケースでは既存のパッチを修正してください。

パッチ修正のルール

  1. 著者情報を保持する: TODO コメント内に元の著者を保持します(パッチの From: フィールドから)
  2. TODO の担当者を絶対に変更しない: TODO(name) は元の名前を保持する必要があります
  3. 説明を更新する: アップストリームで API やマクロが変更された場合、パッチのコミットメッセージを現在の状態に合わせて更新します
  4. パッチをスキップして再作成しない: git am --continue が「No changes — did you forget to use 'git add'?」と表示した場合、git am --skip を実行して代替のコミットを作成しないでください。そのパッチの変更は、以前の 3-way マージの解消によってすでに取り込まれています。これは、以前のコンフリクト解消が変更を取り込みすぎたことを意味します。状況をユーザーに提示して指示を仰いでください。正しい修正には、各パッチの変更を分離したままにするため、以前の解消をより慎重にやり直す必要がある場合があります。

Electron Node.js アップグレード: フェーズ 2

概要

e build -k 999 -- --quiet を繰り返し実行し、発生するビルドの問題を修正しながら、成功するまで進めます。その後、e start --version を実行して Electron が起動することを検証し、変更をアトミックにコミットします。

フェーズ 1 の完了後、直ちにフェーズ 2 を実行してください。

成功基準

フェーズ 2 は以下の条件を満たしたときに完了です:

  • e build -k 999 -- --quiet がコード 0 で終了する(ビルドの失敗がない)
  • e start --version を実行して Electron の起動を確認している
  • すべての変更がコミットガイドラインに従ってコミットされている

これらの基準を満たすまで停止しないでください。コードや機能を削除せず、近道をするためにコードをコメントアウトしないでください。既存のすべてのコード、ロジック、意図を機能させてください。

コンテキスト

roller/node/main ブランチは、DEPS 内の Electron の Node.js 依存関係バージョンを更新するために自動化によって作成されます。旧バージョンと新バージョン間の破壊的変更に対応する作業は何も行われていません。Node.js の API(特に内部の V8 統合、OpenSSL/BoringSSL の互換性、ビルドシステムのファイル)はバージョン間で頻繁に変更されます。いずれの場合も、Node.js の変更を考慮して Electron のコードを更新する必要があり、Electron のビルドを修正するために Node.js のコードに変更を加えることは強く避けてください。

主要なディレクトリ:

  • 現在のディレクトリ: Electron リポジトリ(e コマンドは常にここで実行してください)
  • ../third_party/electron_node: Node.js リポジトリ(ビルドの問題を修正するためにこのコードに触れず、コンテキストを得るために読むだけにしてください)

ワークフロー

  1. e build -k 999 -- --quiet を実行します(--quiet フラグはターゲットごとのステータス行を抑制し、エラーと最終結果のみを表示します)
  2. 成功した場合 → ステップ 6 に進みます
  3. ビルドに失敗した場合:
    • コンパイルエラーメッセージから「electron」内の該当ファイルを特定します
    • 失敗の原因を分析します
    • Node.js の変更に合わせて Electron のコードを調整し、ビルドの問題を修正します
    • e build -t {target_that_failed}.o を実行し、修正対象の失敗したターゲットだけをビルドします
      • ビルドログの失敗行から target_that_failed を特定できます。例:FAILED: 2e506007-8d5d-4f38-bdd1-b5cd77999a77 "./obj/electron/shell/browser/api/electron_api_utility_process.o" CXX obj/electron/shell/browser/api/electron_api_utility_process.o の場合、ターゲット名は obj/electron/shell/browser/api/electron_api_utility_process.o です
    • 今すぐ references/phase-two-commit-guidelines.md を読み、その指示に厳密に従って変更をコミットします。
    • ステップ 1 に戻ります
  4. 重要:コミット(特にパッチのコミット)の後は、必ずすぐに electron リポジトリで git status を実行します
    • インデックス/ハンクヘッダーのみが変更された、ほかの変更済み .patch ファイルがないか確認します
    • これらは修正の影響を受けた依存パッチです。次のコマンドですぐにコミットします:git commit -am "chore: update patches (trivial only)"
  5. ステップ 1 に戻ります
  6. e build が成功したら、e start --version を実行します
  7. ../third_party/electron_node で git status を実行し、Node.js リポジトリに未コミットの変更がないか確認します
    • 変更がある場合は、以下の「A. パッチの修正」の指示に従い、適切なパッチファイルに変更を正しくコミットします

コマンドリファレンス

コマンド目的
e build -k 999 -- --quietElectron をビルドし、エラーが発生しても続行してステータス行を抑制します
e build -t {target}.o修正を検証するため、特定のターゲットだけをビルドします
e start --versionビルド成功後、Electron が起動することを検証します

2 種類のビルド修正

A. パッチの修正(パッチが適用された Node.js ファイルの場合)

エラーが Electron のパッチ対象ファイルで発生している場合(grep -l "filename" patches/node/*.patch で確認します):

  1. Node.js ソースツリー内のファイルを編集します(../third_party/electron_node/...)
  2. 元のパッチコミットを対象に、修正用コミットを作成します:
    cd ../third_party/electron_node
    git add <modified-file>
    git commit --fixup=<original-patch-commit-hash>
    GIT_SEQUENCE_EDITOR=: git rebase --autosquash --autostash -i <commit>^
    
  3. 更新されたパッチを書き出します:e patches node
  4. references/phase-one-commit-guidelines.md に従って、更新されたパッチファイルをコミットします。

修正対象の元のパッチコミットを見つけるには、git log --oneline | grep -i "keyword from patch name" を実行します。

リベースのベースコミットは、パッチ適用前の Node.js のコミットです。refs/patches/upstream-head ref を確認して見つけます。

B. Electron コードの修正(shell/、electron/ などのファイルの場合)

Electron 独自のソースコードでエラーが発生している場合:

  1. electron リポジトリ内のファイルを直接編集します
  2. 直接コミットします(パッチの書き出しは不要です)

Electron Node.js アップグレード:フェーズ 3

概要

script/node-spec-runner.js を使って Node.js のテストスイートを実行し、失敗したテストを修正して、すべてのテストが成功するまで修正をコミットします。恒久的に無効化されているテスト(script/node-disabled-tests.json に記載)は実行しないでください。

フェーズ 2 の完了後、すぐにフェーズ 3 を実行します。

完了条件

次の条件を満たしたとき、フェーズ 3 は完了です:

  • node script/node-spec-runner.js --default が失敗数 0 で終了する
  • すべての変更がコミットガイドラインに従ってコミットされている

これらの条件が満たされるまで中断しないでください。

コンテキスト

Electron は、カスタムランナー(script/node-spec-runner.js)を使用して、Node.js の上流テストスイートの一部を実行します。テストは、ELECTRON_RUN_AS_NODE=true を指定してビルド済みの Electron バイナリで実行します。Electron は BoringSSL(OpenSSL ではありません)と Chromium の V8(Node.js にバンドルされた V8 とは異なる場合があります)を使用するため、多くのテストには調整が必要です。

主要なファイル:

  • script/node-spec-runner.js — テストランナースクリプト
  • script/node-disabled-tests.json — 恒久的に無効化されたテスト(修正を試みないでください)
  • ../third_party/electron_node/test/ — Node.js のテストファイル(パッチの適用先)
  • patches/node/fix_crypto_tests_to_run_with_bssl.patch — BoringSSL に対応するための暗号テストの調整
  • patches/node/test_formally_mark_some_tests_as_flaky.patch — 不安定なテストのリスト

ワークフロー

  1. electron リポジトリで node script/node-spec-runner.js --default を実行します
  2. すべてのテストに合格した場合 → フェーズ 3 は完了です
  3. テストに失敗した場合:
    • 出力から失敗したテストファイルを特定します
    • 各失敗を分析します(下記の「よくある失敗パターン」を参照)
    • ../third_party/electron_node/test/... のテストを修正します
    • 特定の失敗したテストを再実行して検証します:node script/node-spec-runner.js {test-path}
      • テストパスは node の test/ ディレクトリからの相対パスです。例:test/parallel/test-crypto-key-objects-raw.js
      • 特定のテストを実行する場合は --default を使用しないでください。スイート全体のフラグが追加されます
      • ELECTRON_RUN_AS_NODE を指定してテストを直接実行しないでください。ランナーが環境設定を処理します(例:package.json を ESM から CommonJS に一時的に切り替えます)
    • fixup ワークフローとコミットガイドラインに従って修正をコミットします
    • 手順 1 に戻ります

コマンドリファレンス

コマンド目的
node script/node-spec-runner.js --defaultNode.js のテストスイート全体を実行
node script/node-spec-runner.js test/parallel/test-foo.js単一のテストを実行
NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjsスナップショットベースのテストのスナップショットを再生成

よくある失敗パターン

BoringSSL との非互換性

Electron は、Node.js に同梱されている OpenSSL ではなく、Chromium の BoringSSL に対して Node.js をビルドします。v24.18.0 のロール時点では、大規模なソースパッチではなく GN 引数を通じて設定されています。

# build/args/all.gn
# Build Node.js against Chromium's BoringSSL instead of node's bundled OpenSSL.
node_openssl_path = "//third_party/boringssl"

上流の Node.js は BoringSSL に対するネイティブビルドをサポートするようになりました(nodejs/node のコミット 677ca7e76c9 と 61b20f60a39 を参照)。そのため、Electron における従来の BoringSSL 対応の回避策の大部分は削除されました。v24.18.0 のロール時には、次のように変更されました。

  • fix_crypto_tests_to_run_with_bssl.patch は約 1100 行から、2 つのテストファイルだけをスキップする内容に縮小されました。
  • fix_handle_boringssl_and_openssl_incompatibilities.patch は約 176 行削減されました。残っているのは、deps/ncrypto/ncrypto.cc、src/crypto/crypto_{common,context,hash}.cc、src/env.h、src/node_metadata.h、src/node_options.h における C++ レベルの互換処理です。

これらの回避策は今後増やすのではなく、削除していくことを想定してください。機能が BoringSSL で本当にサポートされていない場合に限り、ガードを追加してください。上流のテストは process.features.openssl_is_boringssl が設定されている場合に自動でスキップするケースが増えているため、Electron 側での変更は不要です。

まだサポートされていない機能に推奨されるガード — ファイルの先頭でテストファイル全体をスキップし、fix_crypto_tests_to_run_with_bssl.patch に追加してください。

if (process.features.openssl_is_boringssl) {
  common.skip('Skipping unsupported ML-DSA key tests');
}

インラインで適切にガードできないテストについては、代わりにファイル全体を script/node-disabled-tests.json に追加してください。

Chromium の BoringSSL でまだサポートされていない機能(v24.18.0 時点):

機能現在の対応
RSA-PSS 鍵生成(非推奨化の経路)test-crypto-keygen-deprecation でファイル単位の common.skip
ML-DSA キーtest-crypto-pqc-key-objects-ml-dsa でファイル単位の common.skip
ML-KEM キーnode-disabled-tests.json で無効化(test-crypto-pqc-key-objects-ml-kem)
FIPS モード無効化(test-crypto-fips)
セキュアヒープ無効化(test-crypto-secure-heap)
ステートレス DH無効化(test-crypto-dh-stateless)
各種の鍵生成/WebCrypto の鍵生成無効化(test-crypto-keygen、test-webcrypto-keygen、wpt/test-webcrypto)

動作の違い(スキップではなくアサーションの更新) — エラーの形が変わっただけのケースもあります。

  • サポートされていない OKP(Ed448)の JWK から秘密鍵を作成すると、以前の Invalid JWK data ではなく Invalid JWK OKP key がスローされるようになりました。nodejs/node#62499 を参照してください。Electron の spec/node.spec.ts のアサーションは /Invalid JWK/ に緩和されました。

テストをガードする必要がある場合は、機能を直接確認できるときには、process.features.openssl_is_boringssl による一律のチェックではなく、ciphers.includes('aes-128-ccm') のような、機能を正確に判定するチェックを優先してください。

スナップショットテストの不一致

一部のテストでは、コミット済みの .snapshot ファイルと出力を assert.strictEqual で比較しています。これらはワイルドカードによる比較ではありません。Chromium の V8 が異なる出力を生成する場合(たとえば、V8 の機能強化によってスタックトレースが異なる場合)、スナップショットを再生成する必要があります。

NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs

次に差分を確認して、変更が想定どおりであることを検証し、更新したスナップショットを適切なパッチにコミットしてください。

V8 の動作の違い

Chromium の V8 は、Node.js に同梱されている V8 より新しい場合があります。これにより、次のような違いが生じることがあります。

  • スタックトレースの形式が異なる(例:thenable の非同期スタックフレーム)
  • エラーメッセージが異なる
  • 標準の Node.js V8 にはない機能が Chromium の V8 で利用できる(またはその逆)

2 種類のテスト修正

A. パッチ修正 (テスト失敗で最も一般的)

ほとんどのテスト修正は patches/node/ 内の既存パッチに対して行います。fixup ワークフローを使用してください:

  1. ../third_party/electron_node/test/... 内のテストファイルを編集します
  2. 関連するパッチコミットを見つけます: git log --oneline | grep -i "keyword"
    • Crypto/BoringSSL テスト → fix crypto tests to run with bssl
    • スナップショットテスト → 特定のスナップショットパッチ (例: test: accomodate V8 thenable)
    • フレーキーテスト → test: formally mark some tests as flaky
  3. fixup コミットを作成します:
    cd ../third_party/electron_node
    git add test/path/to/test.js
    git commit --fixup=<patch-commit-hash>
    GIT_SEQUENCE_EDITOR=: git rebase --autosquash --autostash -i <commit>^
    
  4. エクスポートします: e patches node
  5. 今すぐ references/phase-three-commit-guidelines.md を読んでください。その後、更新されたパッチファイルをコミットします。
B. 新しいパッチ (まれ)

修正が既存のどのパッチにも属さない場合にのみ、新しいパッチを作成してください。../third_party/electron_node 内の新しいパッチコミットには、そのパッチが存在する理由と削除できるタイミングを説明する記述を含める必要があります — これは lint チェックによって強制されます。

無効化されたテストへの追加

テストを script/node-disabled-tests.json に追加するのは、最後の手段 としてのみ行ってください — テストが Electron のアーキテクチャと根本的に互換性がない場合 (単にガードで対処できる BoringSSL の差異である場合ではありません)。ここで無効化されたテストは完全にスキップされ、実行されることはありません。

重要: コミット前に読むこと

  • フェーズ 1 のコミットを行う前: references/phase-one-commit-guidelines.md を読んでください
  • フェーズ 2 のコミットを行う前: references/phase-two-commit-guidelines.md を読んでください
  • フェーズ 3 のコミットを行う前: references/phase-three-commit-guidelines.md を読んでください

変更頻度の高いパッチ

これらのパッチは、Node.js のアップグレード時に一貫して最も多くの作業を必要とします:

  • fix_handle_boringssl_and_openssl_incompatibilities.patch — Electron は (Chromium 経由で) BoringSSL を使用しますが、Node.js は OpenSSL を想定しています。歴史的に大きく複雑なパッチでしたが、Node.js がネイティブの BoringSSL サポートを獲得した (build/args/all.gn の node_openssl_path = "//third_party/boringssl" で有効化) ことで 大幅に縮小 されました。それでも一部の C++ レベルの差異を shim しており、上流の OpenSSL/ncrypto API の変更によって壊れる可能性があります。
  • fix_crypto_tests_to_run_with_bssl.patch — 上記の補助パッチで、Node.js の crypto テストを BoringSSL 向けに適応させます。上流のテストが BoringSSL で自己スキップするようになったため、これも 大幅に縮小 されました — 主にまだサポートされていない少数のテストファイルをスキップします。上記の「BoringSSL の非互換性」セクションを参照してください。
  • support_v8_sandboxed_pointers.patch — V8 のサンドボックスポインタサポートは、V8 API が変更された際に注意深い適応を必要とします。
  • build_add_gn_build_files.patch — GN ビルドファイルのパッチは大きく、多くのビルドターゲットに影響します。上流のビルドシステムの変更と頻繁に競合します。

メジャーバージョンアップグレード

Node.js のメジャーバージョン移行 (例: v22 → v24) は、パッチの更新よりもはるかに手間がかかります:

  1. パッチの削除を想定してください。 Electron は Chromium の V8 を使用しており、これは Node.js にバンドルされている V8 バージョンよりしばしば先行しています。多くのパッチはこのギャップを埋めるために存在します — Chromium の V8 にはあるが Node.js の古い V8 にはない新しい V8 API を shim するものです。Node.js が新しいメジャーバージョンに上がると、その V8 は Chromium のものに追いつき、それらのブリッジパッチは削除できます。v22 → v24 のアップグレードでは、この理由で 17 個のパッチが削除されました。
  2. package.json の @types/node を更新 して、新しいメジャーバージョンに合わせます。
  3. アップグレード後のリグレッションは想定内です。 アップグレードがマージされた後でも、エッジケース (ESM パス処理、証明書の読み込み、プラットフォーム固有の問題) に対するフォローアップ修正 PR は正常です。

スキルのディレクトリ構造

このスキルには、references/ に追加のリファレンスファイルがあります。

  • patch-analysis.md - パッチの失敗を分析する方法
  • phase-one-commit-guidelines.md - フェーズ 1 のコミット形式
  • phase-two-commit-guidelines.md - フェーズ 2 のコミット形式
  • phase-three-commit-guidelines.md - フェーズ 3 のコミット形式

ワークフローの手順で参照されている場合は、これらを読んでください。

コメント