electron-vite
pnpm create @quick-start/electron electron-vite-windows --template react-ts
github搜索关键词:
declare const MAIN_WINDOW_VITE_DEV_SERVER_URL: string;
渲染进程 HMR
热重载
热重载是指在主进程或预加载脚本模块发生变化时快速重新构建并重启 Electron 程序。 事实上,并不是真正的热重载,而是类似的。它为开发者带来了很好的开发体验。
electron-toolkit
https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
提示
一定要多使用错误提示 dialog.showErrorBox(标题,内容),不然的话,当程序运行不起来时你根本不知道什么错误
electron-devtools-installer
electron-devtools-installer 是一个用于在应用程序中安装和使用开发者工具的工具。 它可以方便地安装和使用 Chrome 开发者工具、React 开发者工具、Redux 开发者工具等常用的开发者工具,从而帮助开发者更方便地进行开发和调试。
Electron:热更新/热加载
https://www.jianshu.com/p/7ae7dfff8ed8 基于项目每次修改都需要重新运行npm start才能生效,这样的开发效率很低,这里通过第三方配置可以解决自动加载更新electron
方案一:electron-reloader
1、安装:
npm install electron-reloader --save-dev
2、主进程文件中配置(main.js/index.js)
try {
require('electron-reloader')(module, {});
}
catch (_) {
}
3、重启测试 更改js css html等文件都能自动加载更新electron
方案二:electron-reload(推荐)
添加依赖
npm install electron-reload --save-dev
添加下面代码到main.js的最下面
const { app } = require('electron');
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
require('electron-reload')(path.join(__dirname, 'build'));
}
这个插件跟上面的区别在于我们可以指定自动刷新所监听的文件夹
方案三:nodemon
1、安装:
npm install --save-dev nodemon
2、package.json文件中配置
"script": {
"start": "nodemon --watch main.js --exec electron ."
},
// electron . 的意思是监听main.js文件 3、重启测试 这里监听的是main.js文件,所以更改了其他文件之后,还需要再重新保存(ctrl+s)main.js文件, 并且html页面刷新需要在electron应用页面 ctrl+r或点击菜单view-reload进行刷新
方案四:使用gulp、electron-connect、webpack等工具进行热加载
gulp官方文档:https://www.gulpjs.com.cn/docs/getting-started/quick-start/
安装
npm install gulp --save
npm install electron-connect -save
创建gulpfile.js文件
const gulp = require('gulp');
const electron = require('electron-connect').server.create();
gulp.task('watch:electron', () => {
electron.start();
gulp.watch(['./index.js'], electron.restart);
gulp.watch(['./ui/**/*.{js,css},./ui/index.html'], electron.reload);
});
或项目根目录添加gulpfile.js文件
const gulp = require('gulp');
const electron = require('electron-connect').server.create();
gulp.task('watch:electron', () => {
electron.start();
gulp.watch(['./src/**/*.{js,vue}'], (done) => {
const exec = require('node: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'], (done) => {
electron.restart();
done();
});
gulp.watch(['./build/**/*.{js,css}', './v_login.html'], (done) => {
electron.reload();
done();
});
});
添加启动项
修改package.json文件
"scripts": {
"hot":".\\node_modules\\.bin\\gulp watch:electron"
},
添加客户端(注意二选一)
提示
客户端可以在主进程或渲染进程中添加,但是注意不要同时在主进程和渲染进程添加。
- 修改主进程文件
const { app, Menu, BrowserWindow } = require('electron');
const client = require('electron-connect').client;
// 保持一个对于 window 对象的全局引用,不然,当 JavaScript 被 GC,
// window 会被自动地关闭
let mainWindow = null;
// 当 Electron 完成了初始化并且准备创建浏览器窗口的时候
// 这个方法就被调用
app.on('ready', function() {
// 创建浏览器窗口。
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegrationInWorker: true//支持多线程
}
});
// 加载应用的 index.html
mainWindow.loadURL('file://' + __dirname + '/ui/index.html');
// 打开开发工具
mainWindow.openDevTools();
// 当 window 被关闭,这个事件会被发出
mainWindow.on('closed', function() {
// 取消引用 window 对象,如果你的应用支持多窗口的话,
// 通常会把多个 window 对象存放在一个数组里面,
// 但这次不是。
mainWindow = null;
});
client.create(mainWindow);
});
修改渲染进程文件 在index.html文件中添加
// 创建 client
require('electron-connect').client.create();
提示
如果在主进程添加
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
const net = require('node: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事件, 如果我们不开启服务端,只是单纯的运行项目,不好意思它就连不上服务端就报错了!
如果在渲染进程中添加
<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即可运行项目
注意:修改主进程文件,后自动重启窗体;修改html、css文件存在无效的情况,可以使用ctrl+r快捷键刷新
方案五:gulp+electron-reload(推荐)
相比直接使用electron-reload,这个增加了监听源代码变化自动webpack的功能。
安装依赖
npm install gulp --save-dev
npm install electron-reload --save-dev
添加下面代码到main.js的最下面
const { app } = require('electron');
const isDevelopment = !app.isPackaged;
if (isDevelopment) {
require('electron-reload')(path.join(__dirname, 'build'));
}
项目根目录添加gulpfile.js文件
const gulp = require('gulp');
gulp.task('watch:electron', () => {
gulp.watch(['./src/**/*.{js,vue}'], (done) => {
const exec = require('node: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文件
在文件中添加脚本命令
"scripts": {
"start": "webpack --mode development && cross-env ELECTRON_DISABLE_SECURITY_WARNINGS=true electron .",
"hot": ".\node_modules\.bin\gulp watch:electron",
},
运行项目
npm run start
npm run hot
我们分别运行项目的启动和自动webpack的脚本
这样的好处 --- 需要热加载的时候我们再启动npm run hot 不同逐个添加要更新的窗口
当然我们也可以在gulp中启动electron,可以使用electron-connect或自己实现
自己实现的效果不是特别好,比如显示的log会在弹出的命令框中,停止项目,窗口依旧不会关闭,所以还是推荐使用electron-connect
启动Electron的示例代码:
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"命令
}
}
方案六:使用webpack-dev-server
webpack 热加载 使用module.hot.accept和不使用的区别 https://blog.csdn.net/qq_32019935/article/details/125602845
假定我们需要对lib1.js文件进行更新监听,那么我们有两种实现方式
1.在父级文件中进行指定监听
//parent.js
import lib from "./lib.js";
if (module.hot) {
module.hot.accept(
"./lib.js",
() => {
console.log("更新后如何处理")
},
(err) => {
console.log("错误处理")
}
)
}
2.本身内部监听
//lib.js
if (module.hot) {
module.hot.accept(
//"./lib.js",
() => {
console.log("更新后如何处理")
},
(err) => {
console.log("错误处理")
}
)
}
远程模式
该模式可加载web地址,而且可以使用框架中的功能
使用场景
对于web项目,并且希望拥有软件客户端的用户来说,十分有用
/**
* 远程模式-web地址
*/
config.remoteUrl = {
enable: true,
url: 'http://electron-egg.kaka996.com/'
};
判断当前(前端)页面环境是在服务器,还是用户电脑
const isEE = (window.require && window.require('electron')) ? true : false;
发挥你的想象
虽然它是一个远程地址,但是它却可以发消息到主进程,发挥你的想象,创造出有趣软件。
注意路径
windows下,若是 '' 需要转义为 '\' 推荐统一使用 '/'