Help us understand the problem. What is going on with this article?

Electron + React + TypeScript で簡易 Hot Reloading する(改)

はじめに

必要なパッケージ

プロジェクト・ディレクトリの準備

bash
$ mkdir sample && cd $_
$ npm init -y

Electron 関連

bash
$ npm install -D electron electron-connect

TypeScript 関連

bash
$ npm install -D typescript
  • electron-connect には @types が用意されていないので自前で *.d.ts を用意(ただしすべて any 型になる)
@types/electron-connect.d.ts
declare module 'electron-connect';
  • tsconfig.json の例
tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["@types/*"]
    },
    "target": "es2015",
    "module": "es2015",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "lib": [
      "dom",
      "esnext"
    ],
    "sourceMap": true,
    "strict": true,
    "jsx": "react"
  }
}

React 関連

bash
$ npm install -D react react-dom
$ npm install -D @types/react @types/react-dom

Webpack 関連

bash
// 本体
$ npm install -D webpack webpack-cli

// webpack.config.js で補完を効かせるための型定義ファイル
$ npm install -D @types/webpack

// 各種ローダー
$ npm install -D ts-loader

// 今回の本丸プラグイン
$ npm install -D electron-reload-webpack-plugin

その他

  • 必須ではありませんが、現状では以下の3つがないと webpack が幾つかの Warning: *** を吐きます
bash
$ npm install -D bufferutil spawn-sync utf-8-validate

webpack.config.js

webpack.config.js
const path = require('path');

// プラグインのインポート
const createElectronReloadWebpackPlugin = require('electron-reload-webpack-plugin');

// プロジェクト直下のディレクトリを監視させる
const ElectronReloadWebpackPlugin = createElectronReloadWebpackPlugin({
  path: './',
});

// メインプロセス
/** 補完が効きます! */
/** @type import('webpack').Configuration */
const main = {
  target: 'electron-main',
  mode: 'development',
  resolve: {
    extensions: ['.js', '.ts'],
  },
  entry: './src/main.ts',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'main.js',
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: 'ts-loader',
      },
    ],
  },
  // プラグイン起動
  plugins: [ElectronReloadWebpackPlugin()],
  devtool: 'inline-source-map',
};

// レンダラープロセス
/** @type import('webpack').Configuration */
const app = {
  target: 'electron-renderer',
  mode: 'development',
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx'],
  },
  entry: './src/renderer.tsx',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'app.js',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader',
      },
    ],
  },
  plugins: [ElectronReloadWebpackPlugin()],
  devtool: 'inline-source-map',
};

module.exports = [main, app];

Electron App に electron-connect を組み込む

  • メインプロセス
src/main.ts
import { app, BrowserWindow } from 'electron';
import { client } from 'electron-connect';

let win: BrowserWindow | null = null;

app.once('ready', (): void => {
  win = new BrowserWindow({});
  win.loadFile('build/index.html');

  win.on('closed', (): void => {
    win = null;
  });

  // 'ready' イベント内で BrowserWindow オブジェクトを渡す
  client.create(win);
});

app.once('window-all-closed', (): void => app.quit());
  • レンダラープロセスの例
build/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
    <title>Electron App</title>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/javascript" src="app.js"></script>
  </body>
</html>
src/renderer.tsx
import React from 'react';
import ReactDOM from 'react-dom';

const App = (): JSX.Element => {
  return (
    <div>
      <h1>Hello Electron!</h1>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));

実行

  • webpack--watch オプション付きで起動します
package.json
{
  "main": "build/main.js",
  "scripts": {
    "start": "webpack --watch"
  }
}
bash
$ npm start
  • src フォルダ以下のファイルを編集するとリロードされます
  • html-webpack-plugin を用いて HTML ファイルも src 以下に置けるようにしておけば便利かもしれません
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away