概要
React を使用して作成したページを Electron で使用する方法について解説します。
本記事で紹介するコードは以下を参照ください。
electron-examples/09_electron-use-react/react-electron
手順
1. React プロジェクトを作成する
React プロジェクトを create-react-app を使用して作成します。
npx create-react-app react-electron --template typescript
npm start で React が正常にインストールできたかどうかを確認します。React のページがブラウザに表示されたら成功です。現時点のディレクトリ構成は以下のようになっています。
react-electron
├── node_modules
├── package-lock.json
├── package.json
├── public
├── README.md
├── src
└── tsconfig.json
2. Electron をインストールする
Electron の他、開発時に必要となるモジュールをインストールします。
npm install -D electron cross-env wait-on concurrently
- electron: Electron
- cross-env: 環境変数を設定してコマンドを実行するのに使用
- wait-on: ページにアクセスできるようになってからコマンドを実行するのに使用
- concurrently: 複数のコマンドを並列に実行できるようにするために使用
electron というディレクトリを作成し、その配下に main.ts 及び tsconfig.json を作成します。
react-electron
├── electron <-- 新規作成
| ├── main.ts
| └── tsconfig.json
├── electron
├── node_modules
├── package-lock.json
├── package.json
├── public
├── README.md
├── src
└── tsconfig.json
main.ts
import { app, BrowserWindow } from "electron";
const createWindow = () => {
const win = new BrowserWindow();
win.loadURL("http://localhost:3000/");
};
app.whenReady().then(createWindow);
- Electron に表示するページを
react-scripts startを実行すると表示される URLhttp://localhost:3000/に設定します。
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"outDir": "../build",
"module": "commonjs",
"strict": true,
"rootDir": "../"
}
}
- ビルド生成物が
react-electron/build/以下になるように、"outDir": "../build"を指定します
3. package.json を編集する
package.json を編集して、以下の2点を追記します。
react-electron/electron/main.tsをコンパイルして生成されるreact-electron/build/main.jsをエントリポイントに指定するため、"main": "build/electron/main.js"を追記します- Electron を起動する
"electron:start": "concurrently \"cross-env BROWSER=none npm start\" \"wait-on http://127.0.0.1:3000 && tsc -p electron && electron .\""を追記します
electron:start では、concurrently を使用して、以下の2つのコマンドを並列実行しています。
"cross-env BROWSER=none npm start"で React アプリを起動し、http://127.0.0.1:3000でアクセスできるようにします- 環境変数
BROWSER=noneを設定すると、react-scripts start時にブラウザが開かれません - 環境変数を指定してコマンドを実行するために
cross-envを使用しています
- 環境変数
wait-on http://127.0.0.1:3000 && tsc -p electron && electron .\で、react-electron/electron配下のファイルをコンパイルし、Electron を起動しますwait-on http://127.0.0.1:3000で、npm startにより React のページにアクセスできるようになるのを待ってから、後続のコマンドを実行します
4. Electron を起動する
Electron を起動し、React のページがウィンドウに表示されたら成功です。
npm run electron:start
パッケージ化する
electron-builder でパッケージ化するための方法を紹介します。
1. electron-builder をインストール
npm install -D electron-builder
2. main.ts を編集する
npm run build (react-scripts build) を実行すると、./build/index.html が生成されます。
パッケージ化されている場合、読み込むファイルは ./build/index.html となるように変更します。
main.ts
import { app, BrowserWindow } from "electron";
const createWindow = () => {
const win = new BrowserWindow();
win.webContents.openDevTools();
if (app.isPackaged) {
win.loadURL(`file://${__dirname}/../index.html`);
} else {
win.loadURL("http://localhost:3000/");
}
};
app.whenReady().then(createWindow);
3. package.json を編集する
ビルド設定を追加する
package.json を編集します。まず、electron-builder のビルド設定を追加します。
"build": {
"files": [
"build/**/*"
],
"extends": null
},
コマンドを追加する
コマンド "electron:build": "npm run build && tsc -p electron && electron-builder" を追加します。
このコマンドは以下の処理を順番に行います。
npm run build(react-scripts build) により、React アプリをビルドする。ビルド結果は./buildに出力される。tsc -p electronにより、./electron以下の Electron 関係のファイルをビルドする。ビルド結果は./buildに出力される。electron-builderでパッケージ化する
リソースファイルを相対パスで記述する
file:// プロトコルのルートは、file:///C: のようにドライブのルートになってしまうため、index.html 内で /statis/sample.js と記述されていても、file:///C:/statis/sample.js を見に行ってしまい、リソースファイルにアクセスできません。
リソースファイルのパスを index.html があるディレクトリからの相対パスにするために、package.json に "homepage": "./", を追加します。
これにより、react-scripts build により生成される index.html が読み込む各種リソースファイルのパスが index.html からの相対パスになります。
変更前に react-scripts build で生成した index.html
<script defer="defer" src="/static/js/main.cc475e7b.js"></script>
<link href="/static/css/main.f855e6bc.css" rel="stylesheet" />
↓
変更後に react-scripts build で生成した index.html
<script defer="defer" src="//static/js/main.cc475e7b.js"></script>
<link href="//static/css/main.f855e6bc.css" rel="stylesheet" />
上記を追記した状態の package.json は以下のようになっているはずです。
{
"name": "react-electron",
"version": "0.1.0",
"private": true,
"main": "build/electron/main.js",
"homepage": "./",
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.73",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"electron:start": "concurrently \"cross-env BROWSER=none npm start\" \"wait-on http://127.0.0.1:3000 && tsc -p electron && electron .\"",
"electron:build": "npm run build && tsc -p electron && electron-builder"
},
"build": {
"files": [
"build/**/*"
],
"extends": null
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"concurrently": "^8.2.2",
"cross-env": "^7.0.3",
"electron": "^28.1.4",
"electron-builder": "^24.9.1",
"wait-on": "^7.2.0"
}
}
4. パッケージ化する
パッケージをビルドします。バイナリファイルは ./dist 以下に生成されます。
npm run electron:build

コメント