Electronの常駐アプリでハマったこと5つ
Electronでメニューバー常駐アプリを作りました。画面部分は普段のWeb制作に近く、最初は順調だったのですが、パッケージ化してFinderから起動したあたりで問題が続きました。
データの保存先、GUIアプリのPATH、終了時の挙動、見えなくなるエラー。どれもHTMLやCSSではなく、デスクトップアプリとして動かしたときに初めて見える問題です。実際にハマった5つを残しておきます。
1. データをappバンドル内へ保存しない
相対パスで ./data へ保存すると、パッケージ版では .app 内へ書かれ、次のビルドで消えることがあります。書き込み可能なルートをモジュールのimportより前に設定します。
process.env.APP_DATA_ROOT = app.getPath('userData');
const { store } = await import('./store.mjs');
2. Finder起動時のPATHに依存しない
GUIアプリからはHomebrewやnvmのNodeが見えない場合があります。Electron同梱の実行ファイルをNodeとして使います。
spawn(process.execPath, [scriptPath], {
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
});
3. OSの終了を妨げない
閉じる操作を常にキャンセルしてhideすると、ログアウトやシャットダウンまで止めます。
app.on('before-quit', () => { app.isQuitting = true; });
mainWindow.on('close', (event) => {
if (app.isQuitting) return;
event.preventDefault();
mainWindow.hide();
});
4. 失敗ログの出口を作る
Finder起動では console.error が見えません。機密情報を除き、時刻、処理名、終了コード、標準エラー末尾などをファイルへ残します。
5. リセット範囲を決める
開発用の data/ と ~/Library/Application Support/<app>/ は別物です。タスクDB、カーソル、セッション、アーカイブ、ログのうち何を削除し、接続設定や認証情報のうち何を残すかを明文化します。
振り返ると、ハマったのはどれもWeb画面の外側でした。保存先、PATH、プロセスのライフサイクル、ログの出口は、画面ができてから考えるものではなく、常駐アプリの土台として先に決めておくものだったと思います。
開発中にターミナルから起動できたことだけでは、Finderから使うアプリとして動く保証にはなりません。パッケージ版を普段と同じ方法で起動し、終了と再起動、ログ、データの残り方まで一度通しておくと、公開後の調査がずっと楽になります。
今回は以上です。