Electronではじめる
このガイドでは、ElectronアプリにZeltアプリケーションを組み込む手順を説明します。
前提条件
Electronでは追加で以下が必要です:
- Electron — 最小バージョンは
@zeltjs/adapter-electronのpeer dependencyを参照してください - electron-vite(推奨)
インストール
pnpm add @zeltjs/core @zeltjs/adapter-electron
pnpm add -D electron electron-vite
アーキテクチャ概要
サーバーベースのadapter(Node.js、Bun)とは異なり、Electron adapterはHTTPソケットの代わりにIPCで通信します。あなたのZeltアプリはmain processで動作し、rendererはIPCブリッジを通じてそれを呼び出します:
必要なのは3つの要素です:
- Main process —
onElectron(app)がZeltを起動し、IPCハンドラを登録します - Preloadスクリプト —
exposeIpc()がIPCをrendererへブリッジします - Renderer process —
ipcFetch()がブリッジ経由でリクエストを送信します
プロジェクト構成
my-electron-app/
├── src/
│ ├── main/
│ │ ├── entry/
│ │ │ └── hello.controller.ts
│ │ ├── app.ts # Zeltアプリ定義
│ │ └── index.ts # Electron mainエントリ
│ ├── preload/
│ │ └── index.ts # IPCブリッジのセットアップ
│ └── renderer/
│ └── src/
│ └── api/
│ └── zeltFetch.ts # IPC fetchラッパー
├── electron.vite.config.ts
├── package.json
└── tsconfig.json
Hello World
Step 1: Controllerを作成する
src/main/entry/hello.controller.ts を作成します:
@Controller('/hello')
export class HelloController {
@Get('/:name')
greet(req = request()) {
const name = req.pathParam('name');
return { message: `Hello, ${name}!` };
}
}
Step 2: アプリケーションを作成する
src/main/app.ts を作成します:
export const app = createApp([http({
controllers: [HelloController],
})]);
Step 3: Main Processで初期化する
src/main/index.ts を作成します:
const bootstrap = async () => {
const electronZelt = await onElectron(app, {
ipcChannel: 'http://zelt-app',
});
const win = new BrowserWindow({
width: 900,
height: 670,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
contextIsolation: true,
sandbox: true,
},
});
win.loadFile(join(__dirname, '../renderer/index.html'));
};
void bootstrap();
onElectron() はZeltランタイムを起動し、指定されたchannelのIPCハンドラを自動的に登録します。返されるのは:
http.fetch(request)—Requestを処理してResponseを返します(設定された各featureはそのkeyでnamespace化されます。デフォルトはhttp)shutdown()— アプリケーションをgracefulにシャットダウンしますget<T>(Class)— DIコンテナからserviceを解決します
important
webPreferences.preload のパスは、コンパイル済みのpreloadスクリプトを指している必要があります。指定しないと exposeIpc() が実行されず、rendererはZeltアプリに到達できません。
Step 4: Preloadスクリプトをセットアップする
src/preload/index.ts を作成します:
exposeIpc({ channel: 'http://zelt-app' });
exposeIpc() はElectronの contextBridge を使って、IPC senderをrendererへ安全に公開します。
Step 5: RendererからAPIを呼び出す
src/renderer/src/api/zeltFetch.ts を作成します:
export const zeltFetch = (input: RequestInfo | URL, init?: RequestInit): Promise<Response> =>
ipcFetch(input, init, { channel: 'http://zelt-app' });
標準の fetch() と同じように使います:
const response = await zeltFetch('http://zelt-app/hello/world');
const data = await response.json();
console.log(data.message); // "Hello, world!"
important
channel文字列(例: 'http://zelt-app')は、main・preload・rendererの3層すべてで一致している必要があります。
次のステップ
- Electron — IPC Bridge — IPCブリッジの詳しい仕組み
- Electron — Window Management — Zelt DIを通じたBrowserWindowの管理
- Controllers — ルーティングとHTTPメソッド
- Services — ビジネスロジックと依存性注入