ElectronでWebアプリをデスクトップ化する|Macで払う費用と、書かずに済む境目
Electronで最初の1本を組むと、20分ほどで窓が開いてWebアプリが表示され、Dockにアイコンが並びます。ここで完成したように見えるのが、この道の入口の特徴です。判断が要るのはその先で、誰かに渡す段になったとき、Chromiumの修正が公開されたとき、そして認証が別のドメインを経由してアドレスバーの無い窓の中で止まったときに、まとめてやってきます。「electron webアプリデスクトップ化」を検討している段階で、その後半戦を先に見ておくと、半日の作業と数か月の仕事のどちらを始めるのかを選べます。
20分で動くところまでの中身
Electronは2種類のプロセスで動きます。1つは主プロセスで、中身はNode.jsです。窓、メニュー、OSに触る処理はここが持ちます。もう1つは窓ごとの描画プロセスで、中身はChromiumです。ページを表示するのはこちらです。
既存のWebアプリを包む作業は、主プロセスの設定ファイルを1つ書いて、窓を1枚作り、行き先を指定するだけで形になります。難しいのはこの部分ではありません。難しいのは、行き先の指定の仕方に2つの形があり、その選択が後の作業量をほぼ決めてしまう点です。
遠隔のURLをそのまま読み込む形にすると、アプリは薄いままです。配布物にはエンジンと設定ファイルしか入らず、Webアプリを更新すればデスクトップ側の表示も同時に新しくなります。アプリは利用者の側に立つだけなので、既存の公開手順に手を入れる必要がありません。
ビルド済みの資源を同梱してローカルから読み込む形にすると、回線が無くても起動できるようになります。その代わりアプリがバージョンを持ちます。画面を1行直すたびに新しい配布物を全員に届ける必要が生まれ、APIの接続先は設定で切り替えられるようにしなければならず、これまで同一オリジンだった通信が別オリジンからの通信に変わるため、サーバー側の許可も要ります。すでに公開されていて常時オンラインのWebアプリなら、後者を選ぶ理由はほとんどありません。
タブのままでは手に入らないもの
独立した窓と専用のアイコンが欲しいだけなら、コードを書かなくてもmacOSとChromeが用意しています。Electronが割に合うのは、ブラウザがWebページには渡さないと決めている機能が要件に入っているときです。
- ネイティブのメニューバーを持ち、ブラウザの操作と衝突しないキーボードショートカットを割り当てられる
- 他のアプリを使っている最中でも効く、システム全体のキーボードショートカットを登録できる
- メニューバーの常駐項目を置ける。窓を閉じても動き続けられる
- 独自のURLスキームを登録して、メールやチャットのリンクから直接開ける。ファイルの関連付けもできる
- 選択ダイアログを経由せず、主プロセスから決まった場所のファイルを読み書きできる
- 窓の大きさを固定する、常に最前面に置く、タイトルバーを消す、前回の位置を復元する、Dockのアイコンに未読の数を出す
この一覧を眺めて、当てはまる項目が1つも無いのであれば、以降に並ぶ費用は見返りの無い支出になります。逆に1つでも当てはまるなら、その項目こそがElectronを選ぶ理由です。
繰り返し発生する費用
費用は作るときではなく、作ったあとに繰り返しやってきます。
配布物はChromiumとNode.jsを丸ごと抱えるため、1ページのアプリでも数百MB規模になります。2つのタブが1つのブラウザを共有するのとは違い、2つのアプリは2つのエンジンを持ちます。ブラウザを開いている端末では、包んだアプリは2つ目のタブというより2つ目のブラウザに近い存在です。
他人に配るには、Apple Developer IDでの署名とAppleの公証が要ります。通っていないと、開発元を確認できないという表示が出て起動できません。署名にはApple Developer Programへの参加が必要で、費用は年額99米ドルです。公証も最初の1回では終わらず、配布するたびに繰り返します。
更新には配る経路が要ります。署名済みの配布物を置く窓口を用意するか、新しい版を毎回手で届けるかのどちらかです。遠隔のURLを読み込む形を選んでいれば、この負担はほとんど発生しません。ページはサーバーの更新で新しくなるためです。
そして最も忘れられるのが、エンジンそのものの更新です。
Electron releases major versions in lockstep with Chromium so you get security fixes as soon as they are available. 出典: electronjs.org
修正が速く出ること自体は、この記述のとおりです。ただしそれは、Electronという土台に修正が届くという意味であって、すでに配ったアプリに届くという意味ではありません。同梱されたエンジンは、作られた日の版のまま止まります。修正が利用者の手元に反映されるのは、誰かが新しい版で作り直し、それを配り直したときだけです。作ったきりアプリケーションフォルダに置かれている入れ物は、その日のブラウザのまま動き続けます。
初期値のうち確かめておく4点
遠隔のページを読み込む入れ物は、ブラウザのタブより強い権限で、ネットワーク越しに届いたコードを動かしています。近年の版は安全側の初期値になっていますが、古い記事から写した設定はその限りではないため、次の4点だけは自分の手元で確かめる価値があります。
1つ目は、描画側のNode連携を切ったままにすること。2つ目は、コンテキストの分離を有効なままにすること。3つ目は、サンドボックスを有効にすること。OSの機能がどうしても要る場合は、preloadの層で名前を付けた関数だけを渡し、モジュールの読み込み機構やファイル操作の全体をそのまま渡さない形にします。
4つ目が、行き先の制御です。何も指定しないと、外部サイトへのリンクがアプリの窓の中で開きます。アドレスバーが無い窓なので、利用者からは今どこを見ているのか分かりません。新しい窓の要求と画面遷移の要求を受け止めて、想定したドメインだけを窓の中に残し、それ以外を既定のブラウザへ送り出す。この処理は数行で、アドレスバーの無いブラウザが1つ増える状態を防ぎます。自分で管理しているサイトであっても、そこから外へ出るリンクの先までは管理下にないため、入れておく意味があります。
配り始める前に確かめておく項目がもう1つあります。認証です。認証が別のドメインを経由する仕組みだと、窓の中で行き先を見失って戻れなくなることがあります。まず1台で作り、セッションが切れて再ログインするところまで通してから広げると、ここで詰まりません。14日目に切れる認証は、初日に落ちる不具合よりも見つけにくいためです。
配布物を作る工程は別の仕事
手元で窓が開く状態と、他人が二重クリックできるファイルの間には、見た目より広い隔たりがあります。日程の多くはここで消えます。
その間を埋めるために、Electron Forgeやelectron-builderといった梱包の道具があります。原本から配布物を組み立て、署名と公証の手順まで1つの命令の中に入れられます。ここを最初に整えておくと、公開作業が数分で終わるか、手順を思い出しながら半日かけるかが分かれます。
この段階になって初めて出てくる論点もあります。現行のMacにはApple SiliconとIntelの2つの系統があるため、配布物はどちらかに合わせるか、両方を含む形にするかを決める必要があります。片方だけで確認していると、もう片方で起動しない不具合が隠れます。公証にはhardened runtimeが要り、通常と違う動きをする部分についてはentitlementsの宣言も要ります。宣言が足りないと、分かりやすい説明ではなく起動時の異常終了として現れます。アイコンは複数の大きさをまとめたicnsの形式が要り、PNGを1枚置いただけではDockでぼやけます。ダウンロードした配布物には隔離の属性が付くため、同僚の端末での初回起動は、作った端末での起動と挙動が違います。
署名と公証まで通した配布物は、その企画を一度も置いていない別の端末で試してください。作った端末でしか動かない配布物は、この種の作業で最も多い落とし穴で、しかも誰かに渡した瞬間という最悪の場面で見つかります。
Electronと他の道を並べる
| Electron | Tauri | SafariのDockに追加 | 専用の道具 | |
|---|---|---|---|---|
| 表示エンジン | Chromiumを同梱 | macOSのWebKitを使う | macOSのWebKitを使う | 道具による |
| 書くコード | 主プロセスの設定 | 設定とRustの環境 | 不要 | 不要 |
| 配布物の大きさ | 数百MB規模 | 数MB規模 | 増えない | 小さい |
| Cookieの分離 | できる | できる | できる | たいていできる |
| メニュー・常駐・全体ショートカット | できる | できる | できない | 限定的 |
| 回線なしでの起動 | 同梱すれば可能 | 可能 | 不可 | 不可 |
| 署名と公証 | 配布するなら必要 | 配布するなら必要 | 不要 | 道具の側で済む |
| エンジンを更新する人 | アプリを作った人 | macOSの更新 | macOSの更新 | 道具の更新 |
判断を分けるのは最後の行です。エンジンを同梱する道は、ブラウザの脆弱性対応の責任が作った側へ移ります。OSのエンジンを使う道は、その責任がOSの側に残り、利用者が何もしなくても追随します。
3つの問いで決める
1つ目。他の人に配りますか。配るなら署名と公証は避けて通れず、そこを引き受けてくれる道具があるかどうかが実務の分かれ目になります。どこまでコードなしで届くのかは対応サービス一覧に並ぶ雛形の幅と、できることに書かれた設定項目を見比べると判断できます。
2つ目。回線が無い場所で起動する必要がありますか。必要なら資源を同梱する形になり、アプリはバージョンを持ちます。この時点でElectronかTauriが妥当な答えになります。
3つ目。ページのままでは持てない機能が要りますか。常駐、全体のショートカット、URLスキーム、決まった場所のファイル監視。3つとも「いいえ」なら、残っている要件は独立した窓と専用のアイコンとセッションの分離だけです。それはmacOS Sonoma 14以降のSafariが、コードを書かずに用意しています。
対応表と料金表から読み取れること
自分で書くか道具に任せるかを決める前に、見ておくと早い材料が2つあります。
1つは、想定されている使い方の幅です。この種の道具の一覧には300を超える雛形が並ぶものもあり、その並びを見れば偏りが分かります。チャットとメールだけが並ぶ一覧であれば、社内の管理画面を包む用途は想定の外かもしれません。手順の細かさは使い方ガイドで見当が付きます。
もう1つは費用の形です。買い切りか継続課金か、対応するmacOSの版はどこまでかを料金で先に確かめておくと、あとで乗り換える手間が減ります。判断に迷いやすい点はよくある質問にまとまっています。年額99米ドルの署名の費用と、更新のたびに発生する作り直しの手間を並べたうえで、それでも自分で書く理由が残るかどうかが判断の軸になります。
この2つの道は排他ではありません。常駐やファイル監視が要る1本だけを自分で書き、残りは道具で作る。実際に長く残っている構成は、この混在型がほとんどです。
よくある質問
既存のWebアプリをElectronで包むのに、コードの書き換えは要りますか?
公開中のURLをそのまま読み込む形なら不要です。ページはブラウザで開いたときと同じように動きます。書き換えが要るのは資源をアプリに同梱する場合で、APIの接続先を設定で切り替えられるようにし、別オリジンからの通信をサーバー側で許可する作業が発生します。
Electronのアプリはなぜ数百MBにもなるのですか?
配布物ごとにChromiumとNode.jsを同梱するため、大きさの正体はページではなくエンジンです。TauriはmacOSに元から入っているWebKitを使うので数MB規模に収まりますが、表示は利用者のOSが持つエンジンの版に従うことになります。
作ったアプリを社内の同僚に配るには何が要りますか?
Apple Developer IDでの署名とAppleの公証が要ります。通っていないと、開発元を確認できないという表示が出て起動できません。参加費は年額99米ドルで、公証は配布のたびに繰り返します。あわせて、新しい版を届けるための更新の窓口も用意しておくと運用が続きます。
タブから出したいだけでもElectronを使うべきですか?
その目的だけなら他の道で足りることが多くなります。SafariはmacOS Sonoma 14以降でページを独立したアプリとしてDockに追加でき、Cookieも通知の設定も分かれます。Chromeもページをアプリとして導入できます。メニュー、常駐、全体のショートカット、ファイルの読み書き、回線なしでの起動が要件に入ってから検討する順序が無駄になりません。