こんにちは。
今回は electron-vue で生成したプロジェクトで、
BrowserProcess 側、RendererProcess 側、両方のコードのリロードをさせる方法を紹介します。
コードのリロードは、electron-connect を利用します。
こちらで紹介されていました。すごく便利です。
ソースコード
Github にて公開しています。
electron-connect に対応させる
プロジェクトの生成
electron-vue でのプロジェクトの生成方法は、下の記事がわかりやすかったので参考にしてください。
この記事では、↑の設定で生成しました。
npm でインストール
$ npm install --save-dev electron-connect
tasks/runner.js を変更
これは、 npm run dev
したときに実行されるファイルです。
--- 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
で指定しましょう。
--- 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 を変更
次のように変更します。
--- 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 を変更
依存に指定されていないモジュールによるエラーが起きるので、モジュールを除外します。
--- 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: [ {
実行
改善できる点
- BrowserProcess 側で動くコードを、runner.js で watch していますが、これは
main
ディレクトリ直下のファイルしか監視していません。子ディレクトリも監視するには、glob を使うなどする必要があります。 - electron-connect には、reload 機能も含まれているので、webpack-dev-server を使う必要がなくなりました。
- これについては、今度書こうと思います。