LoginSignup
1
0

More than 1 year has passed since last update.

ReactのチュートリアルをElectronで動かす

Posted at

はじめに

「チュートリアル:Reactの導入」を一通り終えたとき、完成したコードをElectronで動かしたくなった。そこで、Parcelを使ってシンプルに構成してみる。webpack.config.jsは書きたくない。:angry:

完成品

ビルドはしていない。
https://github.com/Hellokichi/electron-react-tutorial

環境

  • windows 11 Pro
  • node.js 16.15.0
  • electron 19.0.0
  • react 18.1.0
  • parcel-bunlder 1.12.5

ディレクトリ構成

./
├ node_modules/
├ parceled/
│  ├ index.html
│  ├ src.js
│  └ src.css
├ dist/
│  └ react_tutorial 1.0.0.exe
├ electron/
│  ├ main.js
│  └ preload.js
└ react/
  ├ public/
  │  └ index.html
  └ src/
     ├ index.js
     └ index.css

最終的なディレクトリ構成(一部省略)。
ParcelでビルドしたHTMLファイル、JSファイル、CSSファイルをparceledに出力して、それらをelectron-builderでビルドしてdistに実行ファイル形式で出力するイメージ。

パッケージのインストール

npm i -D react react-dom
npm i -D electron electron-builder
npm i -g parcel-bundler

レンダラープロセス(React)側

まず、Reactのチュートリアルで作成したindex.jsindex.cssreact/src/にそれぞれ配置する。

└ react/
  ├ public/
  │  └ index.html
  └ src/
     ├ index.js <= ここ
     └ index.css <= ここ

その際、index.jsの先頭に以下のコードを追加する。既にローカル環境で開発していればコードの追加は不要。コードは割愛。

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

次に、react/public/index.htmlを作成する。

└ react/
  ├ public/
  │  └ index.html <= ここ
  └ src/
     ├ index.js
     └ index.css
index.html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> 
  <title>React Tutorial</title>
</head>
<body>
  <div id="root"></div>
  <script src="../src/index.js"></script>
</body>

</html>

こちらはReactのチュートリアルで作成したものではなく、Electronのクイックスタートで掲載されているコードを流用し、<script src="../src/index.js"></script>を追加した。Parcelでトランスパイルする際は、このreact/public/index.htmlがターゲットとなる。

メインプロセス側

main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
  // ビルド後のindex.htmlを読み込む
  win.loadFile('parceled/index.html')
  //win.webContents.openDevTools()
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

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

エントリーポイントとなるelectron/main.jsを作成。

├ electron/
│  ├ main.js <= ここ
│  └ preload.js

これもほとんどElectronのクイックスタートと変わらないが、win.loadFile('parceled/index.html')として、ビルド後のHTMLファイルを読み込むように変更した。

electron/preload.jsも作成したが、今回はメインプロセスとレンダラープロセスで通信を行わないので、中身は空っぽ。

├ electron/ここ
│  ├ main.js
│  └ preload.js <= ここ今回は空

Parcelでビルド

parcel build --out-dir parceled --public-url ./ react/public/index.html --no-minify

electron-builderの出力先と被らないようにビルドしたファイルの出力先を変更し、--public-url ./index.htmlが読み込むJSファイルのパスを指定した。また、--no-minifyでビルド時のサイズ圧縮を無効にしている。最初は有効だったけれど、Parcelの依存パッケージであるcssnanoにエラーがでてやむなく無効化。ダウングレードすればいけるっぽいけど未検証。

electron-builderでビルド

package.jsonの編集

package.json
{
  "name": "react_tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "electron/main.js",
  "scripts": {
    "electron": "electron .",
    "build-win": "electron-builder --win --x64"
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "electron": "^19.0.0",
    "electron-builder": "^23.0.3",
    "react": "^18.1.0",
    "react-dom": "^18.1.0"
  },
  "build": {
    "appId": "react.tutorial",
    "win": {
      "target": "portable"
    }
  }
}

package.jsonにビルド用のコマンドと、buildセクションを追加した。今回はインストールする必要はないので、ポータブル版を設定。

ビルド

npm run build-win

しばらく待つとdistreact_tutorial 1.0.0.exeが出力される。

実行

出力された実行ファイルをたたいてみると、、、
electron

無事にElectron上でReactのチュートリアルが再現できた。
あとはウィンドウサイズを変更したり、メニューバー消したり好きにできる。

さいごに

Electron上でReactを使うのって結構めんどくさいけど、Parcelがないともっとめんどくさかったはず。Parcelは偉大。

参考文献

1
0
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
1
0