LoginSignup
2
1

More than 1 year has passed since last update.

Electron+Vite(Electron, React)でHMR環境を用意する。

Last updated at Posted at 2022-10-23

できたもの

https://github.com/satoc0629/ts_electron_on_vite_template
テンプレートプロジェクト。
一応、Windows、Macそれぞれでビルドもできた。

構成

パッケージ管理

バンドル、ビルド

満足ポイント

ルートからpackage.jsonで1コマンド起動するだけで、Electron側と画面(React)側のViteによるHMRを活用できるようにした。

参照サイト

https://zhuanlan.zhihu.com/p/377697508
https://zhuanlan.zhihu.com/p/497638546
こちらのサイトの記事をベースに作成

構成に至るまで

参照サイトを丸パクリした構成を用意する。
それで問題なく構築できる方もいるかも・・・。

参照サイトのアイディア

Renderer側は、React+Viteでポート固定で起動する。
Electron側は、これに対してloadURLを行う。
Electron側は、NodeJSのHMRは対応していないため、プラグインを自作し、処理を適用する。

Electron HMR

インラインPlugin部分を以下のように記述。

{
            name: 'vite-plugin-electron-main-starter',
            // 最初のコンパイル、リコンパイル後にトリガーされます。
            writeBundle() {
                if (electronProcess) {
                    // 現在実行中のエレクトロンプログラムを終了させてからリブートする。
                    electronProcess.kill()
                }
                // スタート、リスタートエレクトロン
                electronProcess = spawn(
                    // オフィシャルエレクトロンに相当する . 起動方法
                    electronPath,
                    ['../dist/main/main.cjs'],
                    {
                        stdio: 'inherit'
                    })
            },
        }

watch.mjsでelectronの起動

参照サイトの記事では、viteのbuildおよびpluginで有効となる記述だが、うまく動かず原因究明も難しかったため、以下で代替した。
子プロセスを起動する部分は同じ。
watch.mjs内でviteのbuildを直接呼び出すのはやめた。
代わりに、コマンドベースでelectron_srcのpackage.jsonからviteのbuild(watch付き)を起動し、インラインpluginのelectronの起動につなげる形とした。

import {spawn} from 'child_process'
import {createServer, build} from 'vite'

// ---- レンダリング処理部 ----
const server = await createServer({configFile: 'renderer/vite.config.ts'})
await server.listen()
console.log(`renderer process port:${server.config.server.port}`)

// ---- メインプロセス部 ----
const electronProcess = spawn("pnpm", ["--prefix", "electron_src/", "build"], {stdio: 'inherit'})
console.log(`electron process start.`)

electronProcess.on("open", () => {
    electronProcess.stderr.on('data', data => {
        console.error(data.toString())
    })
    electronProcess.stdout.on('data', data => {
        console.log(data.toString())
    })
})

ディレクトリ構成

.
├── LICENSE
├── README.md
├── dist
├── electron_src
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── src
│   │   ├── main.ts
│   │   └── vite-env.d.ts
│   ├── tsconfig.json
│   ├── vite.config.static_build.ts
│   └── vite.config.ts
├── package.json
├── pnpm-lock.yaml
├── renderer
│   ├── index.html
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── public
│   │   └── vite.svg
│   ├── src
│   │   ├── App.css
│   │   ├── App.tsx
│   │   ├── assets
│   │   │   └── react.svg
│   │   ├── index.css
│   │   ├── main.tsx
│   │   └── vite-env.d.ts
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   ├── vite.config.static_build.ts
│   └── vite.config.ts
└── scripts
    ├── build.mjs
    └── watch.mjs


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