概要
前回作成した Electron のサンプルコードでは、main.cjs や index.html を変更した場合、一度アプリを終了し、再度起動する必要がありました。これでは、開発中は不便です。 今回は、ファイルの変更を監視し、変更を検知した場合に自動で再起動を行うライブラリ electron-reload について紹介します。自動で再起動を行うことをホットリロード (hot reload) といいます。
インストール
electron-reload をインストールします。
npm install -D electron-reload
使い方
コード全体は以下を参照ください。
electron-examples/04_electron-tutorial-hot-reload
main.cjs を以下のように変更します。
main.cjs
const { app, BrowserWindow } = require("electron");
const electronReload = require("electron-reload");
const path = require("path");
// 開発環境かどうか
const idDev = !process.env.NODE_ENV || process.env.NODE_ENV === "development";
const createWindow = () => {
const win = new BrowserWindow();
win.loadFile("index.html");
if (idDev) {
// パッケージ化されていない場合
const electronPath = path.join(
__dirname,
"node_modules",
".bin",
"electron" + (process.platform === "win32" ? ".cmd" : "")
);
electronReload(__dirname, {
electron: electronPath,
forceHardReset: true,
});
}
};
app.whenReady().then(createWindow);
変更点は、以下です。
開発環境かどうかを const idDev = !process.env.NODE_ENV || process.env.NODE_ENV === "development"; で判定し、開発環境の場合は、electronReload(paths, options) を呼び出し、ホットリロードを設定します。
electronReload() の paths には、監視対象のファイルまたはディレクトリを指定します。options には、Electron の実行ファイルのパスなどを設定します。
// node_modules にインストールされている Electron の実行ファイルのパス
// Windows の場合、node_modules/.bin/electron.cmd にある
const electronPath = path.join(
__dirname,
"node_modules",
".bin",
"electron" + (process.platform === "win32" ? ".cmd" : "")
);
electronReload(__dirname, {
electron: electronPath,
forceHardReset: true,
});
options に指定できるパラメータ
forceHardReset: デフォルトでは、エントリポイントのファイルmain.cjsが変更された場合のみ、ホットリロードが実行され、index.htmlなど他のファイルの変更では再起動が行われません。forceHardReset: trueを指定することで監視対象のすべてのファイルが変更された場合、再起動するようになります。
TypeScript で使用する場合
1. main.ts を変更する
Typescript で Electron を使用する場合、実際に実行されるのは、main.ts ではなく、tsc コマンドでコンパイル後に出力される ./build/main.js であるため、Electron の実行ファイルの相対パスを指定する際の起点が変わります。
electron-examples
├── build
| └── main.js
├── index.html
├── main.ts
├── package-lock.json
├── package.json
└── tsconfig.json
main.ts
import { app, BrowserWindow } from "electron";
import * as path from "path";
// 開発環境かどうか
const idDev = !process.env.NODE_ENV || process.env.NODE_ENV === "development";
const createWindow = () => {
const win = new BrowserWindow();
win.loadFile("index.html");
if (idDev) {
// バイナリ化されていない場合
const electronPath = path.join(
__dirname,
"..",
"node_modules",
".bin",
"electron" + (process.platform === "win32" ? ".cmd" : "")
);
require("electron-reload")(__dirname, {
electron: electronPath,
forceHardReset: true,
});
}
};
app.whenReady().then(createWindow);
2. package.json のコマンドを変更する
.ts ファイルが変更された場合に、ホットリロードを実現するには、以下の2段階の手順を踏む必要があります。
main.tsが変更されたら、自動でtscによるコンパイルを行い、./build/main.jsを出力する./build/main.jsが変更されたら、electron-reloadによるホットリロードを行う
1に関しては、tsc コマンドを実行する際に -w オプションを使用すると、コンパイル対象のファイルが変更された場合に自動で再コンパイルが行われます。
ただし、tsc -p . -w && electron . としても tsc -p . -w で処理が止まってしまうため、これら2つのコマンドは並列して実行する必要があります。
そのため、concurrently というライブラリをインストールします。
npm install -D concurrently
concurrently は、引数にコマンドを複数渡すと、それらを並列で実行してくれます。
よって、npm start 時のコマンドは、tsc -p . -w\" \"tsc -p . && electron .\" になります。
並列実行のため、コンパイル後に electron コマンドを実行することを保証するため、
tsc -p . && electron . として最初に1回コンパイルしてから electron コマンドを実行しています。
package.json
{
"name": "electron-example",
"version": "1.0.0",
"description": "Electron example",
"main": "./build/main.js",
"scripts": {
"start": "concurrently \"tsc -p . -w\" \"tsc -p . && electron .\""
},
"author": "papillon",
"license": "MIT",
"devDependencies": {
"concurrently": "^8.2.2",
"electron": "^28.1.3",
"electron-reload": "^2.0.0-alpha.1",
"typescript": "^5.3.3"
}
}

コメント