セットアップ(2)
プリロードスクリプトを作成する
Electronはセキュリティ改善のため、バージョンアップのたびにセキュリティ要件が厳しくなっています。
Electronバージョン5より前では、nodeIntegraion
という、レンダラープロセスにそのままNode.jsを統合する機能がデフォルトで有効でした。
レンダラープロセスはWebブラウザの技術で作られており、元々利便性のためにNode.jsも一緒に組み込んでいましたが、動作するマシンの全てのリソースに簡単にアクセスできセキュリティリスクが高かったため、バージョン5ではデフォルトで無効化されました。
ところがElectronの機能を初期化するときに不都合があるため、プリロードという、レンダラープロセスでありながらNode.jsの機能も使える特権的なスクリプトが登場しました。
プリロードが使われ始めたころはwindow
グローバル変数を書き換えていましたが、これもセキュリティリスクが高いため、contextIsolation
というオプションが追加されました。contextIsolation
が有効になると、プリロードスクリプトと、レンダラープロセスのアプリケーションはwindow
などを共有しません。
それらを踏まえて、プリロードスクリプトを見てみましょう。
// public/preload.js const { contextBridge, ipcRenderer } = require("electron"); //(1)contextBridgeを使って、メインプロセスの機能をレンダリングプロセスに提供する contextBridge.exposeInMainWorld("ipc", { test: (message) => { ipcRenderer.invoke("test", message); //(2)IPC通信を送信する }, });
(1)で使っているcontextBridge
はcontextIsolation
が有効な場合でも、安全に処理をやりとりするためのオブジェクトです。
contextBridge.exposeInMainWorld
の第1引数は、レンダラープロセスのwindow
の下に新たに生やすオブジェクトの名前です。第2引数はオブジェクトで実際の機能を定義します。
(2)で使われているipcRenderer.invoke
はIPC通信を行うものです。古い資料にはipcRenderer.send
が使われる事例がありますが、現在ではipcRenderer.invoke
が推奨されています。
このプリロードスクリプトにより、レンダラープロセスはwindow.ipc.test('message')
によって、メインプロセスにテストメッセージを送信できるようになります。
TypeScriptでIPC通信をできるようにする
TypeScriptに関しての詳細は後編で書きますが、IPC通信のためにwindow
を拡張する場合、専用の定義が必要です。
まずsrc/@types/global.d.ts
に定義します。
// src/@types/global.d.ts interface Window { //(1)対象はWindowというインターフェース ipc: { test: (message: string) => void; //(2)test関数の型定義 }; }
(1)の Window
というインターフェースは、Webブラウザのwindow
オブジェクトの型を定義するものです。ここに追加で、IPCの為のオブジェクトを追加します。
(2)のtest: (message: string) => void
は、ipc
オブジェクトの中にtest
という関数を定義しています。引数にstring
型を受け取り、戻り値がないを意味するvoid
を指定しています。
これにより、window.ipc.test
が使えるようになりました。
Electronアプリを開発モードで起動する
ここまでの工程によって、npm run dev
でElectronアプリとして起動できるようになりました。
# npmの場合 npm run dev
IPC送信を試す
起動したままソースコードを書き換えることもできます。さっそくApp.tsx
を書き換えてみましょう。
// src/App.tsx import React from "react"; function App() { return ( <button onClick={() => window.ipc.test("Hello, Electron Main World.")}> テストメッセージ送信 </button> ); } export default App;
こちらはボタンを押すと、window.ipc.test
でメッセージを送信するコードです。
Starting the development server... Compiled successfully! You can now view wijmo-example in the browser. Local: http://localhost:3000 On Your Network: http://192.168.1.7:3000 Note that the development build is not optimized. To create a production build, use npm run build. test message: Hello, Electron Main World. Compiling... Files successfully emitted, waiting for typecheck results... Compiled successfully! test message: Hello, Electron Main World.
メインプロセスの管轄である、コンソールにテストメッセージが表示されました。