Electron开发时热加载

electron-reloader

1
npm install electron-reloader --save-dev

添加下面代码到main.js的最下面

1
2
3
4
5
6
7
8
const {app} = require("electron");
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
try {
require('electron-reloader')(module);
} catch (err) {
}
}

electron-reload(推荐)

添加依赖

1
npm install electron-reload --save-dev

添加下面代码到main.js的最下面

1
2
3
4
5
const {app} = require("electron");
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
require('electron-reload')(path.join(__dirname, "build"));
}

这个插件跟上面的区别在于我们可以指定自动刷新所监听的文件夹

gulp+electron-connect

gulp官方文档:https://www.gulpjs.com.cn/docs/getting-started/quick-start/

添加依赖及配置

安装模块

1
2
npm install gulp --save-dev
npm install electron-connect -save-dev

项目根目录添加gulpfile.js文件

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
const gulp = require('gulp');
const electron = require('electron-connect').server.create();

gulp.task('watch:electron', function () {
electron.start();
gulp.watch(['./src/**/*.{js,vue}'], function (done){
const exec = require('child_process').exec;
const cmdStr = 'npm run webpack';
exec(cmdStr, (err, stdout, stderr) => {
if (err){
console.log(err);
console.warn(new Date(),'Webpack命令执行失败');
} else {
console.log(stdout);
console.warn(new Date(),'Webpack命令执行成功');
}
done();
});
});
gulp.watch(['./main.js'], function (done){
electron.restart();
done();
});
gulp.watch(['./build/**/*.{js,css}', './v_login.html'], function (done){
electron.reload();
done();
});
});

添加启动项

修改package.json文件

在文件中添加脚本命令

1
2
3
"scripts": {
"hot": ".\\node_modules\\.bin\\gulp watch:electron",
},

添加客户端(注意二选一)

客户端可以在主进程或渲染进程中添加,但是注意不要同时在主进程和渲染进程添加。

如果在主进程添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
const net = require('net');
const sock = new net.Socket();
sock.setTimeout(200);
sock.on('connect', () => {
console.log("connect");
sock.destroy();
require('electron-connect').client.create(win);
}).on('timeout', (e) => {
console.log("timeout");
}).on('error', (e) => {
console.log("error");
}).connect(30080, "127.0.0.1");
}

为什么要判断端口通不通呢?

这个组件的是通过websocket建立服务端和客户端的连接的,但是它没有监听error事件,如果我们不开启服务端,只是单纯的运行项目,不好意思它就连不上服务端就报错了!

如果在渲染进程中添加

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

官方是这么说的

Do you want to use this tool for only develop environment ? You can remove the <script> block in your gulpfile using gulp-useref.

所以推荐在主进程中添加,判断时候是开发环境来实现是否调用创建客户端的代码。

运行

使用npm run hot即可运行项目

1
npm run hot

经测试

修改主进程文件,会自动重启窗体;

修改HTML/CSS文件,会自动刷新页面;

gulp+electron-reload(推荐)

相比直接使用electron-reload,这个增加了监听源代码变化自动webpack的功能。

安装依赖

1
2
npm install gulp --save-dev
npm install electron-reload --save-dev

添加下面代码到main.js的最下面

1
2
3
4
5
const {app} = require("electron");
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
require('electron-reload')(path.join(__dirname, "build"));
}

项目根目录添加gulpfile.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const gulp = require('gulp');

gulp.task('watch:electron', function () {
gulp.watch(['./src/**/*.{js,vue}'], function (done){
const exec = require('child_process').exec;
const cmdStr = 'npm run webpack';
exec(cmdStr, (err, stdout, stderr) => {
if (err){
console.log(err);
console.warn(new Date(),'Webpack命令执行失败');
} else {
console.log(stdout);
console.warn(new Date(),'Webpack命令执行成功');
}
done();
});
});
});

修改package.json文件

在文件中添加脚本命令

1
2
3
4
"scripts": {
"start": "webpack --mode development && cross-env ELECTRON_DISABLE_SECURITY_WARNINGS=true electron .",
"hot": ".\\node_modules\\.bin\\gulp watch:electron",
},

运行项目

1
2
npm run start
npm run hot

我们分别运行项目的启动和自动webpack的脚本

这样的好处

需要热加载的时候我们再启动npm run hot

不同逐个添加要更新的窗口

当然我们也可以在gulp中启动electron,可以使用electron-connect或自己实现

自己实现的效果不是特别好,比如显示的log会在弹出的命令框中,停止项目,窗口依旧不会关闭,所以还是推荐使用electron-connect

启动Electron的示例代码:

1
2
3
4
5
6
7
8
9
function start_electron() {
if (process.platform.match(/^win.*/)) {
const cmd = `start cmd /c electron "${__dirname}/main.js"`;
child_process.exec(cmd);
} else if (process.platform.match(/^linux.*/)) {
const cmd = `bash -c 'electron "${__dirname}/main.js"'`;
child_process.exec(cmd); // Linux可以使用"pkill -ef electron"命令
}
}