⚛️

[Electron] Linux ビルドでアバウトパネルのアイコンが表示されない

6 min read

モチベーション

electron-builder を使って Linux 向けにビルドした Electron アプリケーションで、ドックアイコンやアバウトパネル内アイコンが表示されない症状を解決します。


Dock (Ubuntu) にアイコンが表示されていない


About パネル ~ アプリアイコンが赤い四角に

https://www.electron.build/

リプロダクション

1. electron-quick-start へ electron-builder をインストール

electron-quick-start を利用して Electron プロジェクトを作成します。

bash
# クイックスタートをダウンロードして zenn というフォルダ名にする
npx degit electron/electron-quick-start zenn

# フォルダへ移動して electron-builder をインストール
cd zenn
npm i -D electron-builder

2. アイコンを準備

カレントディレクトリへ適当なアイコン画像を icon.png の名前で配置します。


右クリック「名前をつけて画像を保存」でダウンロード可

3. メインプロセスでヘルプメニューを作成

Menu モジュールをインポートして、

main.js
  // Modules to control application life and create native browser window
- const { app, BrowserWindow } = require('electron');
+ const { app, BrowserWindow, Menu } = require('electron');

https://www.electronjs.org/ja/docs/latest/api/menu

ファイル最後尾へ以下のコードを追加します。

main.js
// アバウトパネルへ表示する情報を設定
app.setAboutPanelOptions({
  applicationName: app.name,
  applicationVersion: app.getVersion(),
  copyright: '© 2021 Kei Touge',
  // 表示するアイコン
  iconPath: path.join(__dirname, 'icon.png'),
});

// メニューのテンプレート
const template = [
  { role: 'filemenu' },
  { role: 'editmenu' },
  { role: 'viewmenu' },
  { role: 'windowmenu' },
  {
    label: 'Help',
    submenu: [{ label: 'About', click: () => app.showAboutPanel() }],
  },
];

// アプリケーション・メニューを登録
Menu.setApplicationMenu(Menu.buildFromTemplate(template));

app.setAboutPanelOptions({}) を設定しないと、app.showAboutPanel() を実行してもアバウトパネルは表示されません。

https://www.electronjs.org/ja/docs/latest/api/app#appsetaboutpaneloptionsoptions

4. BrowserWindow インスタンスのアイコンを設定

main.js
    // Create the browser window.
    const mainWindow = new BrowserWindow({
      width: 800,
      height: 600,
+     icon: path.join(__dirname, 'icon.png'),
      webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
      },
    });

https://www.electronjs.org/ja/docs/latest/api/native-image

5. ビルド前の状態をチェック

bash
npm start

  • アバウトパネル

  • Dock

6. ビルドしてみる

package.json へ electron-builder の設定を追加して、

package.json
  "build": {
    "linux": {
      "target": "AppImage"
    }
  }

https://www.electron.build/configuration/linux

ビルドします。

bash
npx electron-builder -l

dist ディレクトリへ出力された AppImage ファイルを起動させると・・・

冒頭の状態になってしまいます。

原因と対策

アプリを electron-builder でビルドすると、そのリソースファイルはデフォルトで asar ファイルへとアーカイブされますが、Linux 向け実行バイナリからはこの asar アーカイブ内の画像ファイルへアクセスできないようです。

https://www.electronjs.org/ja/docs/latest/glossary#asar

このため、これらの画像のみを asar のアーカイブ対象から除外し、メインプロセスからはそのファイルパスを指定する必要があります。

asarUnpack オプションを使う

package.json の electron-builder 設定で asarUnpack オプションへ当該画像ファイルを指定します。

package.json
    "build": {
      "linux": {
        "target": "AppImage",
+       "asarUnpack": [
+         "icon.png"
+       ]
      }
    }

https://www.electron.build/generated/platformspecificbuildoptions

メインプロセスでリソースファイルのパスを指定する

開発時またはビルド後のリソースファイルのパスを取得するメソッドを作成し、これを iconPath 等へ指定します。

main.js
// アプリケーションのリソースファイルパスを取得する関数
const getResourceDirectory = () => {
  return process.env.NODE_ENV === 'development'
    ? // 開発時
      path.join(process.cwd(), '.')
    : // ビルド後
      path.join(process.resourcesPath, 'app.asar.unpacked');
};
// アイコンへのファイルパス
const iconPath = path.resolve(getResourceDirectory(), 'icon.png');
  • ドックに表示されるアイコン
main.js
  function createWindow() {
    // Create the browser window.
    const mainWindow = new BrowserWindow({
      width: 800,
      height: 600,
-     icon: path.join(__dirname, 'icon.png'),
+     icon: iconPath,
      webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
      },
    });

    // and load the index.html of the app.
    mainWindow.loadFile('index.html');

    // Open the DevTools.
    // mainWindow.webContents.openDevTools()
  }
  • アバウトパネルのアイコン
main.js
  app.setAboutPanelOptions({
    applicationName: app.name,
    applicationVersion: app.getVersion(),
    copyright: '© 2021 Kei Touge',
-   iconPath: path.join(__dirname, 'icon.png'),
+   iconPath: iconPath,
  });

ビルドふたたび

ふたたびビルドしてみましょう。

bash
npx electron-builder -l

反対に、開発時には以下のようにして Electron を起動します。

bash
NODE_ENV=development npm start

Discussion

ログインするとコメントできます