Electron アプリ TypeScript + preload の実例付きテンプレート
はじめに
Electron アプリは、Windows / macOS などクロスプラットフォーム向けのデスクトップアプリを、JavaScript をベースに作れる非常に有名なフレームワークです。
内部は、画面表示にブラウザ(Chromium)、アプリ自体の操作は Node.js と棲み分けがされており、画面表示は React や Vue、ファイル操作を伴う処理は Node.js のように分散して開発を行うことができます。
ただ、このブラウザとNode.js を結びつける部分は preload という仕組みで双方向の通信を行うのですが、簡単なサンプルはあっても、管理方法についてあまり実用的なサンプルがなかった印象です。
そこで、自分がいつも使っているパターンをサンプルにしてみました。
GitHub | electron-typescript-preload-example
前提
- Node.js v20.11.1
サンプルの動かし方
1 | git clone https://github.com/niroro/electron-typescript-preload-example.git |
これだけで以下のアプリが起動します

4つのボタンがついていますが、それぞれ Node.js で書かれた処理を呼び出します
また、実際に実行ファイルを作りたいときは以下のコマンドで作成できます
1 | npm package |
out ディレクトリ以下に実行形式のファイルが展開されます
Windows 環境下なら、out/electron-typescript-preload-example-win32-x64 に展開されます
この動作は Electron Forge のテンプレートを使っているので、公式ドキュメントを確認してください
コード解説
main / renderer のディレクトリ自体の分離
Node.js (main プロセス) とブラウザ上の JavaScript (renderer プロセス) では挙動が異なります。
過去にはインテグレーションが標準で使われていましたが、挙動の違い以外にもセキュリティの問題などがあり、preload という仕組みを使うのが推奨されています。
簡単なサンプルでは、一つのディレクトリにまとめているケースも多いですが、初めから分けておいたほうが望ましいと思います。
1 | src |
動作の順序としては、main/index.ts にてウィンドウの立ち上げ処理を行い、それを受けてウィンドウ内として起動するブラウザ内で renderer/index.ts を実行していく手順となります
IPC通信 と preload
この2つのプロセスの通信には IPC通信 が用いられます
main プロセスでは ipcMain / renderer プロセスでは、ipcRenderer を用いて、双方向にデータのやり取りを行いますが、ipcRenderer のスコープを秘匿化するために、prelaod/preload.ts を用意します
なお、IPC通信では、独自クラスのインスタンスを渡すことができないなど制限があります
JSONメッセージで表せるようなデータを送るものと割り切って使う必要があります
IPC通信での処理実装例
今回はウィンドウクローズを行う処理の流れを説明します
renderer プロセスからの main プロセスへ指示を送る場合に、双方で共通に使う名称を決めます
1 | /** |
preload/preload.ts には、その処理を呼び出す処理を記述します
(戻り値も受け取れますが、今回は void です)
1 | /** |
main プロセス内では、すでに ハンドルされています (main/ipcHandler.ts#addHandler が呼び出し済み)
そのため、ipcMain.handle(Channels.Close, this.close.bind(this)) で定義された close() が呼び出され、ウィンドウクローズ操作が行われます
1 | /** |
この仕組みで、複雑化しやすい IPC 処理もわかりやすく管理することができます
