ビルドに含めないローカルファイルをレンダラーに取り込む
Electron内で使用する頻繁に更新されるデータ(例えばjsonファイル)を
アプリのビルドをせずに、対象のファイルの差し替えで済むようにしました。
フローとしては、レンダラープロセスが読み込む準備ができたら、メインプロセスへリクエストを送り、メインプロセスでローカルファイルのデータを返します。
レンダラープロセスとメインプロセスの双方向通信には ipcMain.handle
と ipcRenderer.invoke
を使います。
例えば、Mac用にビルドされるアプリと同じ階層にdata.jsonを設置し、そのデータをアプリ内に取り込む場合はこのようになります。
メインプロセスでは ipcMain.handle
でイベントのコールバックを設定します。
app.on("ready", async () => { ... ipcMain.handle("load:data", (_event) => { const data = fs.readFileSync(join(app.getAppPath(), "../../../../data.json"), { encoding: "utf-8", }); return data; }); })
app.getAppPath()
は現在のアプリケーションのディレクトリを返すメソッドです。
MacとWindowsで階層が異なるので、Win用が必要であれば出しわけが必要です。
レンダラープロセスは ipcRenderer.invoke
でイベントを呼び出し、先程メインプロセスで指定したコールバックの返り値を受け取ります。
useEffect(() => { async function getData() { try { const data = await global.ipcRenderer.invoke("load:data"); console.log(JSON.parse(data)); } catch (e) { console.error(e); } } getData(); }, []);
global.ipcRenderer
は preload.ts
で定義しています。