Electronの常駐アプリでハマったこと5つ

2026.09.08 09:00
2026.08.30 00:36
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から使うアプリとして動く保証にはなりません。パッケージ版を普段と同じ方法で起動し、終了と再起動、ログ、データの残り方まで一度通しておくと、公開後の調査がずっと楽になります。

今回は以上です。