ElectronアプリをTypeScriptとReactで作成する


概要

Mac上でelectronアプリを開発するにあたり、まず以下の構成での最小限アプリを作り動作検証を行った。

構成

  • Macintosh (Catalina ver10.15.7)
  • node.js (ver12.13.0)
  • electron (ver13.1.8)
  • typescript (ver 4.0.2)

成果

  • ボタンをクリックするとカウントアップする単純なelectronアプリを構築
  • TypeScript で記述したアプリコードの中でブレークポイントを設定してChromium 内蔵デバッガで停止できることを確認
  • react developer tools により、react component tree を Chromium 内蔵デバッガで表示できることを確認

構築手順

node.js 開発環境

参照: nodebrewでnodeのバージョンを切り替える方法 - Qiita

Mac 上では nodebrew を使って node.js をインストールしておくとよい。今回は ver12.13.0 を利用する。

$ node --version
v12.13.0

Electron (with TypeScript + Webpack) 開発環境

参照: TypeScript + Webpack - Electron Forge

ここでは、今後作ってみるつもりの world clock のためのプロジェクトを作る手順を示していく。
自動生成された Hello World が動作することが確認できる。

$ yarn create electron-app world-clock --template=typescript-webpack
$ cd world-clock
$ yarn start

React の導入

参照: React with TypeScript - Electron Forge

変更手順の詳細は上記のリンク先を参照。以下のようなファイル構成とした。

world-clock/
  +-- README.md
  +-- tsconfig.json                  // JSX サポートを追加
  +-- package.json                   // react, react-dom を追加
  +-- yarn.lock
  +-- webpack.main.config.js         // webpack.* は、自動生成されたまま
  +-- webpack.plugins.js
  +-- webpack.renderer.config.js
  +-- webpack.rules.js
  +-- node_modules/
  |     +-- ....
  +-- src/
        +-- index.ts                 // main process で実行される
        +-- index.html               // ほぼ白紙
        +-- renderer.ts              // renderer process で最初に実行される preload script
        +-- App.tsx           // react
        +-- DumbButton.tsx           // react

ここで実行をすると、以下のようにボタンを押すとカウントアップする electron アプリが起動される。

$ yarn start

コード詳細

コード中でポイントとなる部分を説明しておく。gitlab 上のソースコードはこちら

index.ts

参照: GitHub - MarshallOfSound/electron-devtools-installer: An easy way to ensure Chrome DevTools extensions into Electron

今後の開発の中で react developer tools を使いたいので、electron-devtools-installer を利用することにした。この仕組みにより、renderer process を担う chromium 起動時に指定した拡張機能(今の場合 react developer tools)を自動インストールできる。

index.ts
import installExtension, {
  REACT_DEVELOPER_TOOLS,
} from "electron-devtools-installer";

app.on("ready", () => {
  // For now, I would use React Dev Tools.
  installExtension(REACT_DEVELOPER_TOOLS)
    .then((name) => console.log(`Added Extension:  ${name}`))
    .catch((err) => console.log("An error occurred: ", err));
});

renderer.ts

参照: TypeScript + Webpack - Electron Forge

今回利用したテンプレートでは、renderer.ts というファイルがrenderer process で最初に実行される preload scriptとして指定されている。この renderer.ts に react の JSX 記法を直接記述しようとすると、ファイル名を renderer.tsx に変更する必要があり話が面倒になる。

よって、以下のように実際の react (with JSX) の記述は App.tsx から先のファイル群で行うとし、この renderer.ts はシンプルな1行とした。

renderer.ts
import "./App";

App.ts, DumbButton.ts

ごく普通のサンプルコードで、取り立てて説明する箇所はない。gitlab 上のコードを参照。

今後の開発、デバッグにおいて大事な2つの点を確認した。

(1) Chromium 上のデバッガが利用できること

react を使うということはアプリケーションコードのほとんどが renderer process 上で動くので、renderer process のデバッグがスムーズにできることを確認したい。
ボタンをクリックしたときに起動される onClick() にブレークポイントを設定すると、クリック時にきちんと止まることが確認できた。

(2) react developer tools が利用できること

今回は、この確認のためにあえて App, DumbButton という2つの react component を作成した。
react component tree が構築され、react developer tools がその構造に基づいた情報を表示していることが確認できた。