LoginSignup
43
58

More than 3 years have passed since last update.

create-react-appとelectron-builderでTypeScriptとHot Reloadに完全対応したElectronアプリ開発環境を作成する

Last updated at Posted at 2019-09-23

create-react-appで楽にReact+Electronアプリを書けるようになりました。("How to build an Electron app using Create React App and Electron Builder")

それをさらに推し進め、より安全・快適なReact+Electronアプリ開発環境を構築してみます。(長い)タイトルにある通り、目標は以下の通りです。

  • create-react-appでTypeScript対応プロジェクトをさくっと生成
  • Main Processでも、すべてのコードをTypeScriptを書く
  • Main Processでも、Hot Reloadで生産性をアップ
  • パッケージングはelectron-builderで簡単に

手順

プロジェクトの作成

npx create-react-app my-app --typescript
yarn add electron-is-dev electron-reload
yarn add -D concurrently electron electron-builder wait-on

Main Process

ディレクトリの作成

mkdir electron

tsconfig.json

create-react-app付属の yarn buildスクリプトと同様、buildディレクトリに生成物を出力するようoutDirを設定します。

electron/tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "sourceMap": true,
    "strict": true,
    "outDir": "../build",
    "rootDir": "../",
    "noEmitOnError": true,
    "typeRoots": [
      "node_modules/@types"
    ]
  }
}

main.ts

基本的にElectronのサイトにあるサンプルをTypeScript化し、Hot Reloadのコード追加します。

electron/main.ts
import { app, BrowserWindow } from 'electron';
import * as path from 'path';
import * as isDev from 'electron-is-dev';

let win: BrowserWindow | null = null;

function createWindow() {
  win = new BrowserWindow({ width: 800, height: 600 })

  if (isDev) {
    win.loadURL('http://localhost:3000/index.html');
  } else {
    // 'build/index.html'
    win.loadURL(`file://${__dirname}/../index.html`);
  }

  win.on('closed', () => win = null);

  // Hot Reloading
  if (isDev) {
    // 'node_modules/.bin/electronPath'
    require('electron-reload')(__dirname, {
      electron: path.join(__dirname, '..', '..', 'node_modules', '.bin', 'electron'),
      forceHardReset: true,
      hardResetMethod: 'exit'
    });
  }
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});

以下の部分がHot Reloadの対応コードです。

  // Hot Reloading
  if (isDev) {
    // 'node_modules/.bin/electronPath'
    require('electron-reload')(__dirname, {
      electron: path.join(__dirname, '..', '..', 'node_modules', '.bin', 'electron'),
      hardResetMethod: 'exit'
    });
  }

package.jsonの調整

Electron化に必要なプロパティの追加

package.json
  "homepage": ".",
  "main": "build/electron/main.js",

homepageでRender Process内のpath指定をrelativeにし、mainでMain Processのエントリポイントを指定。

Electron Builderに必要なプロパティの追加

package.json
  "author": "Your Name",
  "description": "...",
  "build": {
    "extends": null,
    "files": [
      "build/**/*"
    ],
    "directories": {
      "buildResources": "assets"
    }
  },

create-react-appはMain Processのエントリポイントを強制的にpublic/electron.jsに変更してしまうので、extendsnullをセットして無効化します。(https://github.com/electron-userland/electron-builder/issues/2030)

create-reac-appはビルド結果をbuildディレクトリに出力しますが、 electoron-builderもリソースファイルをbuildディレクトリに保存しようとします。それでbuildResourcesを指定して保存先を変更します。

npm scriptの追加

package.json
  "scripts": {
    "postinstall": "electron-builder install-app-deps",
    "electron:dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:3000 && tsc -p electron -w\" \"wait-on http://localhost:3000 && tsc -p electron && electron .\"",
    "electron:build": "yarn build && tsc -p electron && electron-builder",

electron:devが開発用スクリプトで、Main/Render Process共にHot Relaodに対応しています。まずReactプロジェクトをビルドし、開発用サーバーを立ち上げます。その後Main Processのコードをビルドし、開発モードのelectronアプリを起動します。またHot Reloadのためにtscをwatchモードで起動します。

electron:buildでDistribution Packageをビルドします。生成されたパッケージはdistディレクトリに保存します。パッケージ化されていないアプリそのものだけをビルドしたい場合は、yarn electron:build --dirとします。

postinstallは直接起動することはありません。yarn install後に、インストールされているElectronが使用するのと同じバージョンのNativeモジュールをインストールします。

ディレクトリ構成の概要

my-app/
├── package.json
│
## render process
├── tsconfig.json
├── public/
├── src/
│
## main process
├── electron/
│   ├── main.ts
│   └── tsconfig.json
│
## build output
├── build/
│   ├── index.html
│   ├── static/
│   │   ├── css/
│   │   └── js/
│   │
│   └── electron/
│      └── main.js
│
## distribution packges
└── dist/
    ├── mac/
    │   └── my-app.app
    └── my-app-0.1.0.dmg

まとめ

以下が今回のコード(+α)です。
https://github.com/yhirose/react-typescript-electron-sample-with-create-react-app-and-electron-builder

TypeScriptの安心感とHot Reloadの快適さで、さらに楽しく開発しましょう!

43
58
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
58