electron-vue で生成したプロジェクトで electron-connect を使う

TOC

  1. ソースコード
  2. electron-connect に対応させる
  3. プロジェクトの生成
    1. npm でインストール
    2. tasks/runner.js を変更
    3. package.json を変更
    4. app/src/renderer/main.js を変更
    5. webpack.renderer.config.js を変更
    6. 実行
  4. 改善できる点

こんにちは。

今回は electron-vue で生成したプロジェクトで、
BrowserProcess 側、RendererProcess 側、両方のコードのリロードをさせる方法を紹介します。

コードのリロードは、electron-connect を利用します。
こちらで紹介されていました。すごく便利です。

ソースコード

Github にて公開しています。

electron-connect に対応させる

プロジェクトの生成

electron-vue でのプロジェクトの生成方法は、下の記事がわかりやすかったので参考にしてください。

generate-electron-vue

この記事では、↑の設定で生成しました。

npm でインストール

1
$ npm install --save-dev electron-connect

tasks/runner.js を変更

これは、 npm run dev したときに実行されるファイルです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
--- a/tasks/runner.js
+++ b/tasks/runner.js
@@ -3,6 +3,8 @@
const config = require('../config')
const exec = require('child_process').exec
const treeKill = require('tree-kill')
+const electronConnect = require('electron-connect').server.create()
+const fs = require('fs')

let YELLOW = '\x1b[33m'
let BLUE = '\x1b[34m'
@@ -33,10 +35,14 @@ function run (command, color, name) {
* Start electron after successful compilation
* (prevents electron from opening a blank window that requires refreshing)
*/
- if (/Compiled/g.test(data.toString().trim().replace(/\n/g, '\n' + repeat(' ', command.length + 2))) && !isElectronOpen) {
- console.log(`${BLUE}Starting electron...\n${END}`)
- run('cross-env NODE_ENV=development electron app/src/main/index.dev.js', BLUE, 'electron')
- isElectronOpen = true
+ if (/Compiled/g.test(data.toString().trim().replace(/\n/g, '\n' + repeat(' ', command.length + 2)))) {
+ if (!isElectronOpen) {
+ console.log(`${BLUE}Starting electron...\n${END}`)
+ electronConnect.start()
+ isElectronOpen = true
+ } else {
+ electronConnect.reload()
+ }
}
})

@@ -54,3 +60,7 @@ function exit (code) {

console.log(`${YELLOW}Starting webpack-dev-server...\n${END}`)
run(`webpack-dev-server --hot --colors --config webpack.renderer.config.js --port ${config.port} --content-base app/dist`, YELLOW, 'webpack')
+
+let timeoutId = null
+fs.watch('app/src/main', () => {
+ if (!timeoutId) {
+ electronConnect.restart()
+ timeoutId = setTimeout(() => { timeoutId = null }, 500)
+ }
+})

普段僕はダブルクォーテーション&セミコロンを付けて開発しますが、
ここは合わせます。

変更点としては、

  • isElectronOpen が false のとき、electronConnect を start します。

    *   この時 Electron が勝手に起動されます。
    
    • cross-env の設定をしていないように見えますが、index.dev.js を読み込んだ時に NODE_ENV を production にするようになっているので不要だと思います。
  • isElectronOpen が true のときは、electronConnect を reload します。
  • BrowserProcess 側で動くコードは変更されたら restart します。

package.json を変更

electron-connect では、直接ファイルを指定できないので、
代わりに package.json で指定しましょう。

1
2
3
4
5
6
7
8
9
10
--- a/package.json
+++ b/package.json
@@ -2,6 +2,7 @@
"name": "electron-test",
"version": "0.0.0",
"description": "An electron-vue project",
+ "main": "app/src/main/index.dev.js",
"scripts": {
"build": "node tasks/release.js",
"build:clean": "cross-env PLATFORM_TARGET=clean node tasks/release.js",

main プロパティを指定しました。

app/src/renderer/main.js を変更

次のように変更します。

1
2
3
4
5
6
7
8
9
10
--- a/app/src/renderer/main.js
+++ b/app/src/renderer/main.js
@@ -10,3 +10,7 @@ import App from './App'
new Vue({
...App
}).$mount('#app')
+
+if (process.env.NODE_ENV === 'production') {
+ require('electron-connect').client.create()
+}

webpack.renderer.config.js を変更

依存に指定されていないモジュールによるエラーが起きるので、モジュールを除外します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--- a/webpack.renderer.config.js
+++ b/webpack.renderer.config.js
@@ -16,7 +16,11 @@ let rendererConfig = {
entry: {
renderer: path.join(__dirname, 'app/src/renderer/main.js')
},
- externals: Object.keys(pkg.dependencies || {}),
+ externals: Object.keys(pkg.dependencies || {}).concat([
+ "spawn-sync",
+ "utf-8-validate",
+ "bufferutil"
+ ]),
module: {
rules: [
{

実行

ok-electron-vue

改善できる点

  • BrowserProcess 側で動くコードを、runner.js で watch していますが、これは main ディレクトリ直下のファイルしか監視していません。子ディレクトリも監視するには、glob を使うなどする必要があります。
  • electron-connect には、reload 機能も含まれているので、webpack-dev-server を使う必要がなくなりました。
    • これについては、今度書こうと思います。