electron-forgeのビルドプロセスに割り込む

はじめに

この記事は、electron-forgeのビルドプロセスに、hooksで割り込む方法を記録、共有するためのものです。

electron-forgeには、Electronアプリケーションのビルドに割り込む方法が用意されています。これがhooksです。この割り込み処理をつかえば、任意のnodeモジュールや静的ファイルをElectronアプリケーションパッケージに挿入できます。

electron-forgeには、ビルドプロセスにwebpackを使うテンプレートがあります。しかしnodeモジュールの中には、webpackでバンドルされることを想定していないものがあります。こうしたwebpackと相性の悪いパッケージはwebpackの対象から外し、割り込み処理でパッケージにコピーします。

想定する読者

この記事はすでにElectronで開発をしているユーザーに向けて書かれています。そのため、Electron自体の解説やインストール、開発環境構築に関する内容は取り扱いません。

想定する環境

  • node.js : 14.15.0
  • yarn : 1.22.5
  • electron : 11.1.1
  • electron-forge : 6.0.0-beta.54

バージョンが異なる場合、この記事の内容はそのまま適用できない場合があります。お手元の環境のバージョンを確かめてからお読みください。

electron-forgeの構成

electron-forgeは以下のパッケージで構成されています。

  • Electron
  • electron-packager : 指定されたプラットフォームごとにElectronアプリケーションをパッケージングする
  • electron-rebuild : native nodeモジュールをElectronのバージョンに合わせてリビルドする

hooks

electron-forgeのhooksは、electron-packagerのビルドプロセス割り込み処理ラッパーです。hooksを設定すると、ビルドプロセスの任意のタイミングでnode.jsのスクリプトを呼び出せます。

hooksの設定はpackage.jsonのconfig.forgeオブジェクト内か、config.forgeに設定したjsファイルに記述します。この記事ではconfig.forge.jsというファイルで設定します。

▼package.json

{
  "config": {
    "forge": "./config.forge.js"
  }
}

▼config.forge.js

module.exports = {
  packagerConfig: {},
  hooks: {
    packageAfterCopy: async (forgeOption, resourcePath, electronVersion, platform, arch) => {
       ...ここに処理を書く...
    }
  ...
}

electron-forgeのhooks関数はasyncでなければいけません。

packageAfterCopyにhookを設定する

hooksに設定する関数は、node.js上で実行されます。そのため、必要に応じてnodeモジュールを導入できます。

▼config.forge.js

const path = require("path");
const cpx = require("cpx");

module.exports = {
  hooks: {
    packageAfterCopy: async (forgeOption, resourcePath, electronVersion, platform, arch) => {
      //pathモジュールを使ったパス解決
      const resourceModulePath = path.join(resourcePath, "node_modules");
      //cpxモジュールを使って、nodeモジュールをリソースディレクトリにコピー
      cpx.copySync("./node_modules/iconv/**/*",  path.join(resourceModulePath, "iconv"));
    },
  },

モジュールの導入はpackage.jsonでは難しいため、hooksを利用する場合は設定をjsファイルに切り分けるべきです。

packageAfterCopyの第二引数にはパス./out/{アプリケーション名}/resources/appが渡されます。このディレクトリはElectronアプリケーションから呼び出せますので、静的ファイルが格納できます。また、./out/{アプリケーション名}/resources/app/node_modulesにnodeモジュールを格納すると、Electron内のnode.jsがモジュールとして認識し、メインプロセスから呼び出せます。

以上、ありがとうございました。