mcpField
E
electron-wrapper

electron-wrapper

github.com/brianlovin開発379120 回インストール31 週間前に更新
リポジトリ

electron-wrapper について

既存の Bun Web アプリを Electron デスクトップアプリとして構成するための実装ガイドです。メインプロセス、プリロードブリッジ、Web アプリの適応、ビルドとリリースを扱い、サーバーロジックを保ちながらデスクトップ機能を追加したい開発者向けです。

主な機能

  1. 01Electron と Bun の二つのランタイム構成
  2. 02Bun サーバー起動とローカルページ読み込み
  3. 03プリロードブリッジと IPC 管理
  4. 04Electron 環境向けの Web アプリ適応
  5. 05ビルド、署名、CI リリースの手順

活用シーン

  1. 01既存の Bun Web サーバーをデスクトップアプリ化
  2. 02ウィンドウ管理やネイティブメニューの追加
  3. 03Electron のビルドとリリース手順の設定

インストール

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

$npx skills add https://github.com/brianlovin/agent-config --skill electron-wrapper

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

同梱ファイル

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

references/
build-and-distribute.md
main-process.md
pitfalls.md
project-setup.md
web-adaptation.md

詳細

Bun Web アプリ向け Electron ラッパー

このスキルでは、既存の Bun ウェブサーバーを Electron を使ってネイティブデスクトップアプリにラップする方法を説明します。主要な統合上の課題をすべて解決した、実績のある実装に基づいています。

アーキテクチャ

「Electron はクローム、Bun はサーバー」 — 2 つのランタイムが連携します。

  • Electron/Node.js はウィンドウ管理、ネイティブメニュー、自動更新、IPC を処理します
  • Bun はすべてのアプリケーションロジックを含む実際のウェブサーバーを実行します

Electron のメインプロセスがバンドル済みの Bun バイナリを起動してサーバーを実行し、その後 http://localhost:{port} を BrowserWindow に読み込みます。ウェブアプリは Electron 内で動作していることを認識する必要も、気にする必要もありません。ネイティブ機能向けのオプションの window.electronAPI ブリッジを備えた、通常のウェブページとして動作します。

このアーキテクチャには次の利点があります。

  • サーバーコードを一切変更する必要がありません(標準的な Bun HTTP サーバーのままです)
  • ウェブアプリはブラウザーでも Electron でも同じように動作します
  • Electron が処理するのは、ブラウザーでは対応できない機能だけです。ウィンドウのクローム、システムトレイ、自動更新、ファイルシステムへのアクセスなどです
  • node_modules は 2 つに分かれています。Electron は npm を、ウェブアプリは Bun を使用します

フェーズ 1:プロジェクトのセットアップ

既存の Bun ウェブアプリと並ぶ場所に Electron サブプロジェクトを作成します。

作成するもの:

  • 独自の package.json(Bun ではなく npm を使用)、2 つの tsconfig(メインプロセス用の ESM、プリロード用の CJS)、electron-builder.yml、macOS のエンタイトルメントを含む electron/ ディレクトリ
  • サーバーをバンドルする scripts/build-server.ts
  • プラットフォーム固有の Bun バイナリをダウンロードする scripts/download-bun.ts
  • 親プロジェクトの変更:新しいスクリプト、tsconfig の除外設定、.gitignore のエントリー

リファレンス: project-setup.md

フェーズ 2:メインプロセス

エントリーポイント、サーバーの起動、ウィンドウ管理、自動更新、プリロードブリッジを担う Electron メインプロセスを構築します。

作成するファイル:

ファイル目的
electron/src/main/index.tsアプリのライフサイクル、開発/本番モード、単一インスタンスのロック、IPC ハンドラー
electron/src/main/bun-server.tsバンドル済み Bun の起動、ポート選択、ヘルスチェックのポーリング、環境変数の注入
electron/src/main/window.tsBrowserWindow の設定、ウィンドウ境界の永続化、セキュリティ設定、ナビゲーションガード
electron/src/main/updater.tselectron-updater のセットアップ、レンダラーへのイベント転送
electron/src/preload/index.tsinvoke/on パターンと購読解除をサポートする contextBridge API

主な判断事項:

  • 開発モードでは ELECTRON_DEV_URL 環境変数を使って外部の開発サーバーに接続します(内部で Bun を起動しません)
  • autoDownload: false — 更新をダウンロードするタイミングはユーザーが選べるようにします
  • プリロードでは特定のメソッドのみを公開し、生の ipcRenderer は公開しません
  • electron-store を使ってウィンドウ境界を永続化します

リファレンス: main-process.md

フェーズ 3:ウェブアプリの適応

既存のウェブアプリを、単独のウェブアプリとして完全に機能する状態を保ちながら、Electron 環境を検出して対応できるようにします。

ウェブアプリへの変更:

変更詳細
Electron 検出ユーティリティisElectron()、getElectronPlatform()、isMacElectron()、applyElectronDocumentAttributes()
型宣言すべてのプロパティをオプションにした window.electronAPI
CSS のドラッグ領域.app-window-drag/.app-window-no-drag クラス。インタラクティブ要素は自動的に除外
トラフィックライトの余白--electron-traffic-left CSS 変数(macOS では 72px、それ以外では 0px)
ストレージパスデータディレクトリ用の環境変数。設定されていない場合は CWD にフォールバック
静的アセットの配信本番モードで静的ディレクトリを指定する環境変数
自動更新フックダウンロード/インストール制御を備えた useElectronUpdater() React フック
更新通知利用可能 → ダウンロード中 → 準備完了の状態を表示するピルコンポーネント
機能の制御Electron 内ではデモモードとホスト型機能を無効化

リファレンス: web-adaptation.md

フェーズ 4:ビルドと配布

すべてをバンドルし、CI/CD をセットアップして、コード署名に対応します。

ビルドパイプライン:

  1. Web アプリをビルドします(bun run build)
  2. サーバーを単一ファイルにバンドルします(Bun.build() → resources/server/index.js)
  3. プラットフォーム固有の Bun バイナリをダウンロードします → resources/bun/{platform}-{arch}/
  4. Electron の TypeScript をコンパイルします(2 回に分けて実行:main は ESM、preload は CJS)
  5. electron-builder が extraResources を使ってすべてをパッケージ化します

CI/CD:

  • バージョンタグ(例:v*、clippy-v*)によって GitHub Actions が起動します
  • マトリックスビルド:macos-14 で macOS arm64/x64、windows-latest で Windows x64
  • ビルドステップでは --publish never を指定し、別の publish ジョブで GitHub のドラフトリリースを作成します
  • CI で Apple の証明書をインポートし、公証を行います

コード署名:

  • macOS:Developer ID Application 証明書を base64 形式の .p12 としてエクスポートします
  • Apple ID とアプリ固有のパスワードを使って公証します
  • 必要な GitHub シークレットは 5 つです:APPLE_CERTIFICATE、APPLE_CERTIFICATE_PASSWORD、APPLE_ID、APPLE_PASSWORD、APPLE_TEAM_ID

アイコン:

  • macOS:ソース PNG から sips と iconutil を使って .icns を作成します
  • Windows:png-to-ico npm パッケージを使って .ico を作成します

参考: ビルドと配布

リリースの作成

リリース用の成果物をローカルでビルドしないでください。 署名証明書と公証用の認証情報は CI にあります。ローカルでビルドしたアプリには署名がなく、macOS Gatekeeper によってブロックされます。

リリースの手順:
  1. electron/package.json の バージョンを更新し、コミットして main にマージします
  2. CI ワークフローで指定されているタグのパターンを確認します:
    grep -A2 'tags:' .github/workflows/*.yml
    
  3. main にマージされたコミットにタグを付けます:
    git tag <pattern><version> origin/main
    git push origin <pattern><version>
    
  4. CI を監視します:
    gh run list --workflow=<workflow>.yml --limit=1
    
  5. GitHub でドラフトリリースを確認して公開します
よくある間違い:
  • ローカルで electron-builder --publish always を実行する — 公証されません
  • ローカルの成果物を使って gh release create を実行する — 署名されていません
  • バージョン更新のマージ前にタグを付ける — ビルドのバージョンが誤ります
  • origin/main ではなく、機能ブランチにタグを付ける

詳細は pitfalls.md §13 を参照してください。

重大な落とし穴

クイックリファレンスです。症状とコード例を含む詳細は pitfalls.md を参照してください。

#落とし穴1 行での修正方法
1ESM/CJS の競合"type": "module" と、CJS パッケージ用のデフォルトインポートパターンを使用します
2Preload は CJS である必要があります"module": "CommonJS" を指定した別の tsconfig を用意します
3__dirname が利用できませんfileURLToPath(import.meta.url) のポリフィルを使用します
4開発モードで MIME エラーが発生しますELECTRON_DEV_URL を使って外部の開発サーバーに接続します
5Bun のバージョンが一致しませんダウンロードスクリプトでバージョンを固定し、開発環境のバージョンと一致させます
6nvm の PATH に関する問題起動するプロセスには bash -lc を使用します
7ストレージのパスが誤っています環境変数と app.getPath("userData") を使用します
8開いたときに白く点滅しますshow: false と ready-to-show を使い、backgroundColor を暗色に設定します
11${platform} と process.platform は異なりますBun の extraResources を darwin-/win32- のプレフィックスとともに mac:/win: セクションに配置します
12Bun のワークスペースによって依存関係がルートに集約されますesbuild と createRequire バナーで main をバンドルするか、electron ディレクトリで npm を使用します
13ローカルビルドは公証されませんリリースは必ず CI タグ経由で行い、ローカルで electron-builder --publish を実行しないでください

開発ワークフロー

electron:dev コマンドで開発環境全体を起動します:

npm run dev
  ├── concurrently
  │   ├── dev:web    → cd .. && bun run dev          (Bun dev server with HMR)
  │   └── dev:electron
  │       ├── wait-on http://localhost:3005           (wait for dev server)
  │       ├── npm run build                           (compile TS)
  │       └── ELECTRON_DEV_URL=... electron .         (launch Electron)
  • Web 開発サーバーは HMR で動作し、変更は即座に反映されます
  • Electron は独自の Bun を起動せず、開発サーバーに接続します
  • Preload と main プロセスの変更を反映するには、electron:dev を再起動する必要があります
  • Web アプリの変更は自動的にホットリロードされます

本番に近い動作をローカルでテストするには:

bun run electron:pack    # builds everything, packages without installer
# Output in electron/release/

カスタマイズチェックリスト

新しいプロジェクトに合わせて変更する場合は、次のプロジェクト固有の値を更新してください。

  • electron-builder.yml のアプリ名(productName、appId)
  • window.ts のウィンドウタイトル
  • dev:electron スクリプトと dev スクリプトの開発サーバーポート
  • 環境変数名(例:APP_DATA_DIR、APP_STATIC_DIR)
  • アプリのテーマに合わせたウィンドウ設定の backgroundColor
  • electron-builder.yml の mac セクションにある category
  • electron/package.json のリポジトリ URL
  • download-bun.ts の Bun バージョン
  • electron/assets/ のアイコンアセット

コメント