はじめに
こちらの記事 の環境を構築したあとで、webpackの設定をElectron向けに見直したときのメモです。この記事では、メインプロセス・レンダラープロセス関連のモジュールをwebpackで処理するように設定を見直しています。
上記記事では、レンダラープロセス関連のモジュールのみをwebpackの処理対象としていました。記事を書いた時点ではそれで十分だと思ったのですが、メインプロセス関連のモジュールが膨らむ未来が見えたので、早期に設定を見直すこととしました。
Electronの2種類のプロセス
Electronは、メインプロセスとレンダラープロセスという2種類のプロセスから構成されています。これらの2つのプロセスはそれぞれ異なる役割を持ちます。webpackの設定にも関わるので、まずこれらのプロセスについて整理しておきます。メインプロセスとレンダラープロセスが提供しているAPIは、公式ドキュメントで確認できます。中には、双方のプロセスが提供しているAPIもあります。APIの一覧からもなんとなく役割の違いが理解できるので、一度目を通して見ると良いです。
メインプロセス
OSレベルの処理を主に取り扱い、アプリケーションのライフサイクルを管理するプロセスです。デスクトップアプリケーションに不可欠なGUIの作成も担当しています。つまり、このメインプロセスがウィンドウを作成しています。ウィンドウの作成だけでなく、最大化/最小化、リサイズ、閉じるといった各種イベントをハンドリングします。アプリケーションメニューやショートカットの定義、アップデート処理などもメインプロセスで取り扱われています。メインプロセスの役割はウィンドウを作るところまでです。
レンダラープロセス
メインプロセスによって作られたウィンドウは、Webページとして作られたUIを持ちます。このWebページを描画しているプロセスが、レンダラープロセスです。ウィンドウがHTMLファイルをロードしてWebページを表示する際に、レンダラープロセスが作成されます。メインプロセスは1つしか存在しませんが、レンダラープロセスはWebページごとに存在します。1つのウィンドウの中に複数のWebviewがある場合、それぞれ対応するレンダラープロセスが存在することになります。
webpackの設定
以上のように、メインプロセスとレンダラープロセスは明確に役割が区別されています。また、メインプロセスはエントリーポイントとして実行されるのに対し、レンダラープロセスはWebページが作成されたタイミングで実行されます。処理内容も読み込みのタイミングも違うので、この2つのプロセスで扱うモジュールを1つにバンドルする意味はありません。
以上から、2種類のプロセスに応じた2つのバンドルファイルを出力するように設定します。バンドルファイルの名前はそれぞれ、メインプロセスは main.js
とし、レンダラープロセスは renderer.js
とします。
フォルダ構成
以下のようなフォルダ構成を前提とします。ソースコードはsrc以下に作成し、バンドルファイルをdistに置きます。src以下のディレクトリをプロセスで分けて、その中にエントリーポイントとして index を名前に含んだファイルを作成しています。
. ├── dist # バンドルファイルの出力先 ├── index.html ├── package.json ├── src │ ├── main # Main Process関連のファイル置き場 │ │ └── index.js │ └── renderer # Renderer Process関連のファイル置き場 │ └── index.jsx └── webpack.config.js
メインプロセスに関するモジュールを追加したい場合は src/main
以下に、レンダラープロセスに関するモジュールを追加したい場合は src/renderer
以下に配置するようにします。そうするとなんとなく綺麗な感じがします。
Targets について
JavaScriptはバックエンド、フロントエンドの双方を記述でき、デスクトップアプリケーションも作成できる言語です。webpackの target
オプションは、どの環境に向けて書かれたソースコードであるかを示すものです。 指定された環境に応じて色々と裏側で設定してくれます。
デフォルト値は web
です。 web
はブラウザ向けであることを示しています。Electron向けには、 electron-main
と electron-renderer
の2つの値が存在します。その名の通り、前者がメインプロセス、後者がレンダラープロセスのための設定値です。そのほかの設定値については、公式ドキュメント を参照してください。
Electron関連のバンドルファイルを作成する際には、target
にこれら2つの値を指定すればよいです。しかしながら、 target
には複数の値を設定できません。targetごとに設定を作成しなければなりません。
const mainConfig = { target: 'electron-main', ... } const rendererConfig ={ target: 'electron-renderer', ... } module.exports = [ mainConfig, rendererConfig ]
わざわざ mainConfig などの変数に格納する必要もありませんが、個人的にはこちらの方が読みやすくて好きです。公式ドキュメント - Targets にも同じように書かれています。
設定例
以上を踏まえて、webpack.config.js は以下のようにしました。Webページの描画を担当するRenderer Process側の設定には .jsx
と css
を、Main Process側の設定には js
のみを含めています。
rulesオプションの中を test: /\.(js|jsx)$/
として、メインプロセスとレンダラープロセスで設定を使いまわしてもよかったのですが、今回は別々に設定を作成しました。「メインに画面描画に関するモジュールを混ぜない!」という意思表示のためです。