Electronの初心者向けTips


2年以上前の資料は参考にしない

Electronは3か月に1度、年4回メジャーバージョンアップがあり、最新3メジャーバージョンまでサポートということになっています。つまりアプリをリリースしても約9か月で必ずElectron自体のサポートが切れるぐらい新陳代謝が早いです。よって(Webフロントエンド界隈全般そうですが)「枯れたバージョン」という概念は存在せず最新のバージョンを使うのが無難です。
またセマンティックバージョニングを採用してるのに、これだけメジャーバージョンアップが早い(=破壊的変更が多すぎる)となると、解説記事の陳腐化も凄まじく、妥協しても参考になるのは2年前ぐらいまでかな……という感触があります。本とかも出てますが2017年発売なので……🙊

(書きかけ)メインプロセスとレンダラープロセスの関係について

Electronとはnode.jsとChromiumを連携して扱えるようにしたものであり、メインプロセスはnode.js、レンダラープロセスはChromiumを担当しています。昔はレンダラープロセスから直接node.jsを叩けたのでそこらへんの境目も曖昧だったし、「初心者相手にそこまではいらんやろ」みたいなノリでnode.js云々の説明すら省いている記事もしばしば見かけました。今はContextBrigeの整備等もあってきっちり二分化されましたし、セキュリティや設計を考える上での大前提なので、はっきり意識しておきましょう。
この辺りの経緯や具体的な設定については既に素晴らしい記事があるのでそっちをご覧ください。
(以下、ContextBridge時代の概要図及びメイン-レンダラー間のやりとりするテンプレ及び検討事項を記載)

(TypeScript導入環境向け)webpack.config.jsも移行した方がいいかも

webpack.config.jsはTypeScript化が可能です。
Electronはelectron-main, electron-renderer,electron-preloadと3種類の設定オブジェクトが必要で、webpack.config.jsの行数が嵩みがち。自分も最初はあんまりビルド部分にがっつりロジック書くのはどうかなと思い、あえてMODE切り替えの統一ぐらいしかしてなかったのですが、200行を超えたあたりで限界を悟りました。😅

キャッシュやWeb Storageのファイルの場所について

両OSとも途中に隠しフォルダを挟んでいるため、ExplorerやFinderで見る際は表示設定が必要。

Windows

C:\Users\【ユーザー名】\AppData\Roaming\【パッケージ名】

macOS

実パス: /Users/【ユーザー名】/Library/Application Support/【パッケージ名】
Finder上: /ユーザ/【ユーザー名】/ライブラリ/Application Support/【パッケージ名】

ショートカットキーが効かない!右クリックメニューが出ない!

残念なことにElectronは初期状態でショートカットキーや右クリックメニュー(ContextMenu)が一切設定されておらず、自分で設定する必要があります。
しかも、これらはブラウザやOS自体の機能に紐づいているので、原理上メインプロセスに設定してレンダラープロセスでのイベントにフックする形となります。普段意識しない所ですが、確かにそうなんですが……。
流石に不便ということでElectronサイドでも色々考慮されていてコピーとかペーストとかよくある機能だったら手軽にできるようになっています。ショートカットに関しては公式ドキュメントをどうぞ。
一方、右クリックメニューに関しても、一応公式ドキュメントにもさらっと記載されていますが、書き方が古いので(レンダラーで直接ipcRenderer触ってる)注意して下さい。

通信はメインプロセスとレンダラープロセス、どっちでやった方がいい?

Electronではnode.js(メインプロセス)とブラウザ(レンダラープロセス)両方からHTTPリクエストを飛ばすことができます。自分が作った時はWebアプリがベースで+αをElectronで実装する形だったので選択の余地がなかったのですが、選べる時の為にメモを残しておきます。

項目 node.js ブラウザ
CORS対応 不要🙌 必要
認証方法 APIキー cookie

まずCORS対応の有無はデカいですね。これを利用してるっぽい実例があって、Postmanという、Electron製で自由にHTTPリクエストを飛ばせるツールがあります。バックエンドでAPIを作る際のテストによく使われてます。このツールが、どうもリクエストをメインプロセスで飛ばしてるらしくて、CORSを気にせず気軽にテストできる反面、フロントエンジニア的にはCORS周りのチェックは出来ないというハマりポイントがあります😅
次に認証方法について。node.jsから通信するとなるとAPIキーを利用することになるんですが、Electronの場合だとアプリ内にキー埋め込んでユーザーに渡しちゃう形になるんですよね。ユーザーごとの判別ができないし、アプリを解析されたら即流出なので、ちょっとねぇ……。マイナーアプリで、想定利用者のリテラシーも低くて、難読化かけてて、漏れても何とかなるとかならワンチャン……いや、ないか。
あと観点が変わりますが「取得した情報の利用場所(出力場所)」も判断に関わってきますね。工数的にも心情的にもプロセス間通信あんまりしたくないですしね。

便利なモジュール一覧

Electronアプリ開発で使えそうなモジュールをご紹介。

役割 名前
node.jsのデフォルトモジュールの型定義 @types/node
実行ファイル/インストーラー作成 electron-builder
ロギング electron-log
JSONファイル読み書き electron-store
ソースコード難読化 javascript-obfuscator
システム情報取得 systeminformation

electron-builder関係

⚠️情報収集と設定に時間取られるので注意!

Windows,macOSアプリのリリース周りをやったことない人向けの警告となります。
歴史的な経緯と昨今のセキュリティ的な要請もあり、アプリをインストールし動かすには、広範かつ複雑怪奇な仕様を理解する必要があります。そして対応するelectron-builderの設定が必要です。アプリの生成まではまだ何とかなると思いますが、特に両OSのインストーラー周り、macOSの公証回りまでやろうとすると、必要な知識量や扱う設定ファイルが一気に増え、かなり厄介です。
よって、未経験者は仕様の情報収集とelectron-builderの設定を詰めるだけで最低1か月(注:業務で週40時間やれる計算)は見といた方がいいと思います。もし他言語でのアプリ開発環境があってInstallShieldとか自動化shファイル等の環境が整ってるのであれば、一旦electron-builderでアプリの生成だけして、そっちでやるのも全然アリです。

設定ファイル周りの注意事項

型をつけたい

設定オブジェクトの項目が多岐に渡るため、補完機能が欲しい=型が欲しくなると思います。
最初webpack.config.tsみたいなノリでTypeScript使って何とかならんかな~と検索して回ったんですが、ビルドプロセス自体のTS化が面倒なので、設定ファイルを「設定オブジェクトを返すJSファイル」にして、JSDocから型情報の読み込みを行う形がセオリーのようですね。

//electron-builder.js
/**
 * @type {import('electron-builder').Configuration}
 * @see https://www.electron.build/configuration/configuration
 */
const config = {
    //補完が効く
    "appId": "jp.co.hoge",
    "productName": "私の凄いアプリ",
}
module.exports = config

JSDocから型情報を読み込みできることを知らなかったので最初は驚きましたが、お手軽だし十分かと思います。

asarについて

現在のWebフロントエンドって極小のJSファイルを数千ファイル以上扱う必要がありますが、これをそのままコピーしたり別ドライブに移動したりすると、極端に速度が遅いという問題があります。このため普通のWeb開発でも、Gitのリモートリポジトリ環境を整備したり、アナログですがzipに固めたりすると思います。
Electronも内部にファイルを抱え込む以上、この問題とは無縁ではいられず、圧縮率と利便性に考慮しながら独自に作り出したファイル圧縮形式がasarとなります。標準設定だとWebアプリ本体の全ファイルが1つの.asarファイルに固められます。
ただ生成の過程で圧縮対象となるファイル内のパス表記を書き換えるため、書き換えに失敗して、画像が表示されないとかのトラブルが発生する場合があります。 どうも"baseDir"プロパティを設定してるとそういうことがある(すいません調査しきれてません)みたいなので、お気をつけ下さい。
asarを使わなかった場合、macは.appファイル自体がパッケージなのでそう問題にはならないのですが、Windowsへのインストールに時間かかりすぎて問題になります。私はインストールに1時間かかるインストーラーを作ったことがあります😵 cabに固めてインストールする設定にすると、多少は緩和できます。

後書き

ElectronをやるってことはTypeScript+SPAフレームワーク系もほぼセットだし、そこらの設定周り含めて、Webpack職人🔧、設定ファイル職人になることと同義ですね……😅 Next.jsにElectron向けサンプル設定があってかなり楽になるらしいんで、使える環境の方は試すのもいいんじゃないでしょうか。