gulpを使ってReact Electron Webpack環境にLiveReloadを!

electron開発してると、毎回トランスパイルして起動というのが面倒だなと思ってくる。
webpackのHot Module Replacementを使えばもっと早くできるようだが、僕には理解できなかった。

だがしかし、gulpを使えばそれなりに実現できる!!
とわかり挑戦してみたので、備忘も込めて投稿しようと思う。

目的

React Electron Webpack環境で、LiveReloadできるようする。

下図は、Electron起動時にデベロッパーツールを起動させる設定にしていたのをコメントアウトして保存すると自動でElectronが再起動してるもの。 f:id:poppon555:20180916115336g:plain

使用環境

以前の記事でReact x Electron開発で構築した以下の環境を利用する。
- node: 7.10.1
- React: 16.2.0
- electron: 1.8.4
- webpack: 4.2.0
webpackの詳細の設定は、前回の記事参照。

ディレクトリ構成

ディレクトリ構成は以下の通り

.
├── dist
├── gulpfile.js
├── package.json
├── node_modules
├── src
│   ├── assets
│   ├── main
│   ├── renderer
│   └── utils
└── webpack.config.js

gulpと関連ツールのインストール

npm install -D gulp webpack-stream  electron-connect

webpack-streamは、gulpとwebpackをつなぐために使用し、
electron-connectは、コンパイル後にelectronを再起動したり、再ロードするなどelectronを制御するために使用する。

gulpの設定

touch gulpfile.jsで設定ファイルを作成する。
main用のrenderer用のwebpackの設定を一度に読み込んで、
wepackStreamメソッドに渡すとエラーになってしまうので 、両方の設定を個別に読み込んでからmain用とrender用のタスクを定義するように記述した。

// gulpfile.js
const gulp = require('gulp');
const webpackStream = require('webpack-stream');
const webpack = require('webpack');
const electron = require('electron-connect').server.create();

// main用とrenderer用の設定ファイルを格納
const [mainConfig, rendererConfig] = require('./webpack.config');

// main用のコンパイルタスクを定義
gulp.task('main', () => (
  webpackStream(mainConfig, webpack)
    .pipe(gulp.dest('./dist/main'))
));

// renderer用のコンパイルタスクを定義
gulp.task('renderer', () => (
  webpackStream(rendererConfig, webpack)
    .pipe(gulp.dest('./dist/renderer'))
));

//  gulp起動時のタスクを定義
gulp.task('default', ['main', 'renderer'], () => {
  // electron開始
  electron.start();

  // main.jsファイルが変更されたら再コンパイル
  gulp.watch('src/main/*.{js,jsx}', ['main']);

  // rendererフォルダ配下のファイルが変更されたら、renderer用のコンパイルを実行
  gulp.watch('src/{renderer,utils}/**/*.{js,jsx}', ['renderer']);

  // mainのコンパイルを終了すると,electronをRestart。
  gulp.watch('dist/main/main.js', electron.restart);

  // rendererコンパイルが終了するとReload。
  gulp.watch('dist/renderer/**/*.{html,js,css}', electron.reload);
});

npm scriptsの修正

npm run gulpと打てば実行されるようにコマンド登録する

{
  "scripts" : {
    "build": "gulp default"
  }
}

npm run gulpでgulpを起動させたときには、defaultタスクが実行される。
はじめにmain, rendererタスクが実行されコンパイルが走る。
コンパイル完了後electronを起動させ、ファイルが更新されるたびに再起動や再ロードが 実行されるように設定している。

index.htmlの修正

gulpで起動したelectron制御サーバと通信するためのクライアントをindex.html側に作成する。 これにより、ファイル変更時にelectronの再起動や再ロードが自動で実行される。

// index.html
<html>
  ...
  <script>require('electron-connect').client.create()</script>
  ...
</html>

以上で設定完了。これでmainファイルやrenderer用のファイルを更新すると、 その度に自動でelectronが再起動したり、最ロードされる。

さいごに

LiveReloadの設定は、gulpを使うとあっという間にできてしまう。
ただ自動とはいえ再ロードには結構時間かかるので微妙ではある。
やっぱりHMRが求められるのだろうな、electron docで紹介されてるelectron-react-boilerplate を理解していきたい!!
ともあれgulpのすごさに感動。

参考サイト