Electron+React(create-react-app)のビルドでつまづいたこと


はじめに

この記事ではElectron+create-react-appをelectron-builderでパッケージ化した時につまづいたところを紹介する記事。
似たような環境で作成する際は、一度目を通すと良い。

2021年

electronでアプリケーションを開発する場合は、electron-react-boilerplateがお勧めです。

環境

  • Electron(7.1.10)
  • react(16.12.0)
  • electron-builder(22.2.0)
  • fs

NodeのモジュールをReactから呼び出す。

デスクトップアプリケーションを作成する際、ファイル操作を扱いたいことがよくある。しかし、ReactはWEBのフレームワークでありNodeのモジュールをrequireするとエラーを吐かれる。
そのような場合は、

  • nodeIntegration: trueを設定する。
electron.js
 mainWindow = new BrowserWindow({
        width: 400, 
        height: 600,
        minWidth: 400,
        maxWidth: 400,
        webPreferences: {
            nodeIntegration: true,
        }
    });
  • Reactでrequireをする。
react
import React from 'react';

const remote = window.require('electron').remote;
const fs = remote.require('fs');

electronを通してrequireする際は必ずelectronをrequireし、remoteを使用する。

パスの設定

ビルド後、パスがずれてしまう問題。
主にwebpackの設定がよろしくない。
例えばReact側で次のように記述した後、ビルドする

react
...
fs.existsSync('../src/scraping/subjects.json');
...

しかし、パスが通らない場合がある。

絶対パスを指定する

requireをする際は絶対パスを設定することで解決することができる。
また、絶対パスの方が個人的に良い気がする。

...
fs.existsSync(__dirname+'/src/scraping/subjects.json');
...

また、create-react-app側のwebpackがビルド後__dirnameのパスを'/'と出力する場合がある。
これは、reactをbuildする際に使用するreact-scriptというモジュールのwebpack.config.jsに__dirname:falseを設定することで解決できる。

node_module/react-scripts/config/webpack.config.js
//一番最後の部分
   node: {
      module: 'empty',
      dgram: 'empty',
      dns: 'mock',
      fs: 'empty',
      http2: 'empty',
      net: 'empty',
      tls: 'empty',
      child_process: 'empty',
      __dirname: false,//<-ココ
      __filename: false,//<-ココ
    }

ビルド後のファイル操作(書き込みが?)できない。

fsモジュールなどを使用する際ファイル操作の書き込みができない場合がある。
ビルド後のディレクトリ構造を見てみると、アプリの本体はproject/dist/mac/Contentes/Resources/app.asarに置いてある。asarは読み込みだけを許可する仕組みになっていることから、書き込みができないことがある。
electron-builderにビルド設定を記述することができる。

package.json
"build": {
    "asar": false
    }