electronでリリース用パッケージを作る

先日書いたとおり,electronでMastodonクライアントを作ったのだが,パッケージ化に関してかなり迷走したので,最近のelectron事情を書いておく.

electronに関しては,「ほら,こうしたら簡単に作れるでしょ?」といういわゆるHello World系の記事が非常に多く,細かい困りごとやリリースに必要な情報はあまり出てこない. また,2015年くらいの,electronが流行り始めた時期の記事は結構あるものの,最近はそこまで記事が多くないこともあり,最近のリリース事情がよくわからなかった.

アイコンを作る

アイコンは,どのようなビルド手段を使うにしてもおそらく同じセットが必要になる. これに関してはあまり変更されておらず,古い記事でもかなり役に立った.

とりあえず大本となるpng画像かなにかを手元に用意しておく.

Mac

icnsファイルを用意し,それをelectron-builderやelectron-packagerのオプションに渡すだけでアイコンが設定できる. プログラム本体でアイコン画像を参照したりする必要はない.

icnsを作るために,一応公式では

icon_16x16.png
icon_16x16@2x.png
icon_32x32.png
icon_32x32@2x.png
icon_128x128.png
icon_128x128@2x.png
icon_256x256.png
icon_256x256@2x.png
icon_512x512.png
icon_512x512@2x.png

が必要になると書かれている.このサイズをいちいち用意するのはめんどくさいのだが,なんかよさ気なリサイズサービスとかを使って,画像を用意しよう.

icnsへの変換自体は iconutilコマンドでできる. 詳しくはこのへんが参考になった.

hacknote.jp

Windows

Windowsicoファイルが必要になる. これをelectron-builderやelectron-packagerのオプションに渡すだけで良い.

プログラム内でアイコン画像を読み込む必要はない.

Linux

Linux用のアイコンというのは特別に用意する必要はないのだが(Mac用のicnsをそのまま流用できる),Linuxはちょっと特殊で,パッケージインストール時のアイコンは確かにelectron-builderやelectron-packagerのオプションとして渡す. しかし,アプリケーション起動した際に表示されるアイコンは,electronのプロセス内で指定する必要がある.

github.com

というわけで,アイコンを特別に用意する必要はないのだが,アイコン画像のpngMac用のicnsを用意しておこう.

electron-builderの設定は次章でやるとして,起動後のアプリアイコンの読み込みを書いてやる必要がある.

src/main/index.js あたりでwindowを作る処理がある.その付近で,

mainWindow = new BrowserWindow({
  titleBarStyle: 'hidden',
  width: 640,
  height: 480,
  useContentSize: true,
  icon: path.join(__dirname, '../../build/icons/256x256.png')
})

とかやってアイコン画像を読みだしてやる.ちなみに相対パスを解決させているが,これがビルド後にしっかり読み出せるのかどうかは,次章の方法で実際にビルドしてみて,どんなディレクトリ構成のものが出来上がるのかを観察してみるしかない. とりあえずWhalebirdの場合は,上記パスで解決できた.

ビルドする

ビルドツールとして,electron-packagerの情報が非常に多く出てくる. しかし,2018年4月現在,mac, windows, linux用のバイナリをつくるのにelectron-packagerを使うメリットは殆ど無い.

明らかにelectron-builderを使うほうが楽だ(masについてはelectron-builderでうまく行かなかったけど,これについては後日書こう).

というわけでelectron-builderを使ったビルド方法を説明する.

ちなみに公式が非常に参考になる.

Introduction · electron-builder

electron-builderのインストールは終わっている前提で,package.jsonにビルド設定を書いて,scriptsにビルドコマンドを記述していこう.

{
  "name": "Whalebird",
  "version": "0.4.0",
  ...
  "build": {
    "productName": "Whalebird for Mastodon",
    "appId": "org.whalebird.desktop",
    "directories": {
      "output": "build"
    },
    "files": [
      "dist/electron/**/*",
      "build/icons/*"
    ],
    "dmg": {
      "contents": [
        {
          "x": 410,
          "y": 150,
          "type": "link",
          "path": "/Applications"
        },
        {
          "x": 130,
          "y": 150,
          "type": "file"
        }
      ]
    },
    "mac": {
      "icon": "build/icons/icon.icns",
      "target": [
        "dmg"
      ],
      "category": "public.app-category.social-networking"
    },
    "win": {
      "icon": "build/icons/icon.ico",
      "target": "nsis"
    },
    "linux": {
      "icon": "build/icons",
      "target": [
        "deb",
        "rpm"
      ],
      "category": "Network"
    }
  }
}

build節にビルド設定を書く.

大事なポイント: files

これはビルド対象となるファイルを指定する. npm run buildの結果が格納されるdistディレクトリはもちろんのこと,忘れてはいけないのはアイコンが入っている build/iconsだ.

前述の通り,linuxではプロセス起動時にアイコンファイルの読み込みを行う.そのため,ビルドの成果物にアイコンファイルが含まれている必要がある. そのために,filesにアイコンが格納されているディレクトリを記述しておく必要がある.

ビルドコマンド

package.jsonのscriptsで,

{
  "name": "Whalebird",
  "version": "0.4.0",
  "scripts": {
    "build:mac": "node .electron-vue/build.js && electron-builder --mac --x64",
    "build:windows": "node .electron-vue/build.js && electron-builder --win --x64",
    "build:linux": "node .electron-vue/build.js && electron-builder --linux --x64"
  }
}

とか定義しておくと,このスクリプトを動かすだけでビルドしてくれる.

証明書とかどうするの?

WindowsLinuxは適当にバイナリを作っても動くんだけど,Macだけは証明書をちゃんと設定しておかないと,AppStore配布ではないMacアプリとしても動かない.

というわけで証明書を用意する. Macのアプリを作ったことがある人ならわかるだろうけれど,証明書を作ったりするのは結構めんどくさい.

※以降の操作をするには,Appleデベロッパープログラム(有料)に登録している必要がある

必要になる証明書は,

  • Developer ID Application
  • Developer ID Installer

の2つだ.

キーチェーンアクセス -> 証明書アシスタント -> 証明局に証明書を要求

として,CertificateSigningRequestを作成しよう.

そしたら,developer.apple.comのCertificates, Identifiers & Profilesに行く. で,macOSのCertificatesとして,Developer ID ApplciationとDeveloper ID Installerを作成し,これをダウンロードしておこう

ダウンロードした2ファイルをダブルクリック(もしくはドラッグアンドドロップ)してキーチェーンに登録する.

この,キーチェーンに2つの鍵が登録された状態で,npm run build:mac すると,electron-builderが登録されている鍵を使ってビルドしてくれる.

音声ファイル等を埋め込みたい

効果音のファイルだったり,画像等のリソースを使いたい場合がある.

しかし,electron-builderは基本的にasarという形式にバイナリを圧縮してしまう. すると,メインプロセス内でファイルパスを指定して開こうとしても,asar内のファイルであるために開けないことがよくある(asar圧縮しなければ開ける,もちろん開発時もasarになっていないのでちゃんと動く).

そういう場合には,asarを諦めてもいいんだけど,リソースファイルだけasarしないという手段が選べる.

package.jsonのbuildに,extraResourcesという項目を追加する.

  "build": {
    "productName": "Whalebird for Mastodon",
    "appId": "org.whalebird.desktop",
    "directories": {
      "output": "build"
    },
    "extraResources": [
      "build/sounds/*"
    ],

ここに,指定したファイルはasarに圧縮されることはないが,ちゃんとビルド後のパッケージに含まれる.

場所はこちらに記載されている通り.

Application Contents · electron-builder