Electron是一个基于Chromium和Node.js,可以使用HTML、CSS和JavaScript构建跨平台应用的技术框架,兼容Mac、Windows和 Linux。虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求。受限于浏览器的沙盒限制,网页应用无法满足某些场景下的使用需求,而桌面应用可以方便地读写本地文件、发起跨域请求、调用更多系统资源,再加上Web开发低成本、高效率的优势,这种方式越来越受到开发者的喜爱。
2023年4月,我发布了《2023新春版:手把手教你搭建Electron24+React18+Antd5架构工程》,那篇文章是基于React官方提供的Create-React-App(简称CRA)起步进行构建的。如今CRA已被React抛弃,连新版React官网都没有再提到CRA了。而Vite成为了主流。因此,本系列教程也及时跟进时代的步伐,更新为Vite脚手架工具。综合考虑多方面因素,最终选择electron-vite作为本教程的主角。electron-vite现已推出1.x正式版,虽然没有被Electron和Vite官方提到,但经过实战,体验还是不错的。在省去了手动融合Electron和Vite繁琐过程的同时,还实现了V8字节码、主进程和预加载脚本热更新等非常实用的功能,要比自己从头搭建容易得多。
本教程将electron-vite开发过程详细讲述,希望能够帮助各位省去摸索的时间,少走弯路,快速完成项目开发。React技术栈的小伙伴不要错过哟!
本教程也同步推出《2023金秋版:基于electron-vite构建Vue桌面客户端》,欢迎Vue技术栈的小伙伴来阅读。
先睹为快
先看下目录了解本教程都有哪些内容。
章节目录
css
1 Electron核心概念
• 1.1 主进程(main)
• 1.2 渲染进程(renderer)
• 1.3 预加载脚本(preload)
2 初始化项目
• 2.1 使用electron-vite新建项目
• 2.2 精简项目
• 2.3 去掉renderer的src目录
3 Vite基础配置
• 3.1 配置国内镜像源
• 3.2 支持Sass/Scss/Less/Stylus
• 3.3 设置路径别名
4 项目架构搭建
• 4.1 项目目录结构设计
• 4.2 关于样式命名规范
• 4.3 设置全局公用样式
5 引入Ant Design 5.x
• 5.1 安装Ant Design
• 5.2 设置Antd为中文语言
6 渲染进程页面开发
• 6.1 构建Login页面
• 6.2 构建Home页面
• 6.3 实现页面路由跳转
• 6.4 在React组件中实现页面路由跳转
• 6.5 在非React组件中实现页面路由跳转
7 主进程与渲染进程通信方法一:send与on/once
• 7.1 预加载脚本(preload)开发
• 7.2 主进程开发
• 7.3 继续渲染进程开发
• 7.4 运行效果
• 7.5 关于ipcRenderer.on/once
8 主进程与渲染进程通信方法二:invoke与handle
• 8.1 主进程开发
• 8.2 在渲染进程显示Electron版本号
9 常用配置
• 9.1 设置应用图标
• 9.2 设置APP窗口大小
• 9.3 取消跨域限制
• 9.4 设置DevTools快捷键
• 9.5 禁止build环境的DevTools
10 build项目
• 10.1 执行build命令
• 10.2 解决windows版本编译时无法下载的问题
• 10.3 设置build版应用icon
• 10.4 其他应用信息配置
• 10.5 解决macOS build版本的Coding Siging错误
• 10.6 build后的目录结构
11 其他说明
• 11.1 源代码保护
• 11.2 敏感字符串保护
• 11.3 主进程热更新
• 11.4 禁止同个Electron程序多开
• 11.5 允许windows用户更改安装目录
• 11.6 批量升级全部项目npm依赖包
12 项目Git源码
结束语
本Demo主要依赖包版本
Node.js 18.18.0
electron 26.3.0
electron-builder 24.6.4
vite 4.4.11
react 18.2.0
react-dom 18.2.0
react-router-dom 6.16.0
antd 5.9.4
less 4.2.0
sass 1.69.0
stylus 0.60.0
※注:代码区域每行开头的:
"+" 表示新增
"-" 表示删除
"M" 表示修改
1 Electron核心概念
学习Electron最先要掌握的就是他的主进程与渲染进程概念。网上很多相关教程也进行了详细介绍,又是画关系图又是文字描述的。这里只想把最核心的内容总结一下,以最简单最通俗的方式让各位迅速理解。
掌握三个核心概念即可:
1.1 主进程(main)
每个Electron应用都有一个单一的主进程,作为应用程序的入口点。主进程运行在Node.js 环境,因此可以使用Node.js的所有API能力。主进程并不在浏览器环境中运行,因此不进行页面渲染。
1.2 渲染进程(renderer)
渲染进程说白了就是平时的Web页面前端开发。每个Electron应用都会为每个打开的BrowserWindow生成一个单独的渲染器进程。但是渲染进程是无法直接调用Node.js的API的。
1.3 预加载脚本(preload)
为了让渲染进程与主进程进行通信从而形成一个整体,预加载脚本的作用就是他们之间的桥梁。预加载脚本与渲染进程共享同一个全局window,因此可以通过window来传递数据。但并不是简单地通过给window添加属性就能使用,以下方式是无法把preload.js共享给渲染进程使用的:
javascript
// 预加载脚本(preload.js)
window.myAPI = {
desktop: true
}
javascript
// 渲染进程
console.log(window.myAPI)
// => undefined(获取不到)
这是因为Electron的语境隔离(Context Isolation),使得预加载脚本与渲染进程的主要运行环境是隔离的,以避免将任何API都加入到渲染进程的网页中。
因此,需要使用contextBridge来安全地实现交互:
php
// 预加载脚本(preload.js)
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
desktop: true
})
javascript
// 渲染进程
console.log(window.myAPI)
// => { desktop: true } (成功获取)
以上方式就是通过contextBridge.exposeInMainWorld
将preload.js中的myAPI数据共享给渲染进程的网页使用。
官网详细介绍:
2 初始化项目
2.1 使用electron-vite新建项目
找个合适的目录,执行项目创建命令。
npm命令:
sql
npm create @quick-start/electron
yarn命令:
sql
yarn create @quick-start/electron
pnpm命令:
sql
pnpm create @quick-start/electron
本教程使用yarn,后续不再赘述npm和pnpm的命令。
如果没有安装yarn,可执行以下命令全局安装:
csharp
npm install --global yarn
yarn中文网站:
执行后,会要求填写项目名称,这里我填写的是electron-vite-react-app,可根据情况自定。
yaml
? Project name: electron-vite-react-app
然后,会要求选择框架,选择react:
css
? Select a framework:
vanilla
vue
> react
svelte
solid
最后是几个配置选项:
yaml
? Add TypeScript? >> No / Yes
是否使用TypeScript?选No,本教程使用JavaScript。如果喜欢TypeScript,请选择Yes。
? Add Electron updater plugin? >> No / Yes
是否添加Electron updater插件?选择Yes。
? Enable Electron download mirror proxy? >> No / Yes
是否开启Electron镜像下载代理。在国内网络环境,强烈建议选择Yes。
项目创建完成后,执行以下命令:
bash
cd electron-vite-react-app (进入项目目录)
yarn(安装依赖包)
安装完成后,执行启动命令:
yarn dev
运行效果如下:
2.2 精简项目
接下来,删除用不到的目录和文件,最简化项目。
bash
├─ /.vscode
├─ /build
├─ /node_modules
├─ /out
├─ /resources
├─ /src
| ├─ /main
| ├─ /preload
| ├─ /renderer
| | ├─ /src
- | | | ├─ /assets
| | | ├─ /components
- | | | | └─ Versions.jsx
| | | ├─ App.jsx
| | | └─ main.jsx
| | └─ index.html
├─ .editorconfig
├─ .eslintignore
├─ .eslintrc.cjs
├─ .gitignore
├─ .npmrc
├─ .prettierignore
├─ .prettierrc.yaml
├─ dev-app-update.yml
├─ electron-builder.yml
├─ electron.vite.config.js
├─ package.json
├─ README.md
└─ yarn.lock
2.3 去掉renderer的src目录
以上项目结构有两个src,容易混淆,而且路径表达也略显啰嗦。可以把src/renderer/src目录里的文件放到src/renderer目录中,然后删除src/renderer/src目录。
调整后的renderer目录如下:
bash
...(略)
| ├─ /renderer
| | ├─ /components
| | ├─ App.jsx
| | ├─ index.html
| | └─ main.jsx
...(略)
以上文件删除后,页面会报错。这是因为相应的文件引用已不存在。需要继续修改代码,先让项目正常运行起来。
逐个修改以下文件,最终精简代码依次如下:
src/renderer/App.jsx:
javascript
function App() {
return <div className="App">Electron-Vite-React-App</div>
}
export default App
src/renderer/main.jsx:
javascript
import ReactDOM from 'react-dom/client'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App />)
src/renderer/index.html:
xml
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Electron-Vite-React</title>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
/>
</head>
<body>
<div id="root"></div>
<script type="module" src="/main.jsx"></script>
</body>
</html>
在windows环境中,src/renderer/index.html的<title>
内容将显示在客户端窗口标题栏中。
执行yarn dev,运行效果如下:
3 Vite基础配置
3.1 配置国内镜像源
npm和yarn默认是从国外源站拉取依赖包的,为提高下载速度和稳定性,建议配置为国内镜像源。
yarn registry国内镜像:
arduino
yarn config set registry https://registry.npmmirror.com
npm registry国内镜像:
arduino
npm config set registry https://registry.npmmirror.com
yarn node-sass国内镜像:
arduino
yarn config set SASS_BINARY_SITE https://npmmirror.com/mirrors/node-sass/
npm node-sass国内镜像(仅限于npm < v9的版本):
arduino
npm config set SASS_BINARY_SITE https://npmmirror.com/mirrors/node-sass/
yarn Electron国内镜像:
arduino
yarn config set electron_mirror https://npmmirror.com/mirrors/electron/
npm Electron国内镜像(仅限于npm < v9的版本):
arduino
npm config set electron_mirror https://npmmirror.com/mirrors/electron/
※注: 从npm v9 版本开始,npm 命令限制了npm config set只能设置npm官方规定的config (docs.npmjs.com/cli/v9/usin...%25EF%25BC%258C%25E5%259B%25A0%25E6%25AD%25A4%25E6%2597%25A0%25E6%25B3%2595%25E5%2583%258F%25E6%2597%25A7%25E7%2589%2588%25E6%259C%25AC%25E4%25B8%2580%25E6%25A0%25B7%25E8%25AE%25BE%25E7%25BD%25AE%25E9%2595%259C%25E5%2583%258F%25E7%25AB%2599%25E4%25BA%2586%25EF%25BC%258C%25E4%25B8%258D%25E8%25BF%2587%25E4%25BE%259D%25E6%2597%25A7%25E5%258F%25AF%25E4%25BB%25A5%25E9%2580%259A%25E8%25BF%2587%25E7%25BC%2596%25E8%25BE%2591 "https://docs.npmjs.com/cli/v9/using-npm/config)%EF%BC%8C%E5%9B%A0%E6%AD%A4%E6%97%A0%E6%B3%95%E5%83%8F%E6%97%A7%E7%89%88%E6%9C%AC%E4%B8%80%E6%A0%B7%E8%AE%BE%E7%BD%AE%E9%95%9C%E5%83%8F%E7%AB%99%E4%BA%86%EF%BC%8C%E4%B8%8D%E8%BF%87%E4%BE%9D%E6%97%A7%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E7%BC%96%E8%BE%91") ~/.npmrc 文件的方式实现旧版本npm config set的效果。
如果不清楚本地当前yarn或者npm的配置,可以执行以下命令查看:
yarn查看方法:
arduino
yarn config list
npm查看方法:
arduino
npm config list
如果npm版本在v9及以上的话,需要通过修改项目目录的.npmrc文件来配置镜像源。强烈建议进行以下配置。
修改项目根目录的.npmrc:
ini
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
+ SASS_BINARY_SITE=https://npmmirror.com/mirrors/node-sass/
经过以上配置,Electron依赖包下载就会变得很快。
3.2 支持Sass/Scss/Less/Stylus
Vite本身提供了对.scss/.sass/.less/.styl/.stylus文件的内置支持。无需再安装特定的Vite插件,但必须安装相应的预处理器依赖。
支持Sass/Scss,执行以下命令安装:
csharp
yarn add -D sass
支持Less,执行以下命令安装:
csharp
yarn add -D less
支持Stylus,执行以下命令安装:
csharp
yarn add -D stylus
安装后,就可以直接使用以上对应的CSS预处理语言了,非常方便。
CSS预处理Vite官方说明:
3.3 设置路径别名
electron-vite已经预设了路径别名配置。
例如:src/renderer/App.jsx,可以直接省略成@renderer/App.jsx。
由于本教程已经删除了src/renderer/src目录,因此需要修改对应的预设配置。
修改electron.vite.config.js:
css
...(略)
renderer: {
resolve: {
alias: {
- '@renderer': resolve('src/renderer/src')
+ '@renderer': resolve('src/renderer')
}
},
plugins: [react()]
}
...(略)
4 项目架构搭建
4.1 项目目录结构设计
项目目录结构可根据项目实际灵活制定。这里分享下我常用的结构。重点是renderer目录的结构设计,主要分为公用模块目录、组件模块目录、页面模块目录、路由配置目录等几个部分,让项目结构更加清晰合理。
lua
├─ /.vscode
├─ /build <-- build编译过程性输出目录
├─ /dist <-- 最终build的输出目录
├─ /node_modules
├─ /out <-- dev和build编译过程性输出目录
├─ /resources <-- 主进程和preload的公共资源目录
├─ /src
| ├─ /main <-- 主进程开发目录
| ├─ /preload <-- preload开发目录
| ├─ /renderer <-- 渲染进程开发目录
| | ├─ /api <-- api目录
| | | └─ index.jsx <-- api库
| | ├─ /common <-- 全局公用目录
| | | ├─ /fonts <-- 字体文件目录
| | | ├─ /images <-- 图片文件目录
| | | ├─ /js <-- 公用js文件目录
| | | └─ /styles <-- 公用样式文件目录
| | | | ├─ frame.styl <-- 全部公用样式(import本目录其他全部styl)
| | | | ├─ reset.styl <-- 清零样式
| | | | └─ global.styl <-- 全局公用样式
| | ├─ /components <-- 公共模块组件目录
| | | ├─ /header <-- 头部导航模块(示例)
| | | | ├─ index.jsx <-- header主文件
| | | | └─ header.styl <-- header样式文件
| | | └─ ... <-- 其他模块
| | ├─ /pages <-- 页面组件目录
| | | ├─ /home <-- home页目录
| | | | ├─ index.jsx <-- home主文件
| | | | └─ home.styl <-- home样式文件
| | | ├─ /login <-- login页目录
| | | | ├─ index.jsx <-- login主文件
| | | | └─ login.styl <-- login样式文件
| | | └─ ... <-- 其他页面
| | ├─ /router <-- 路由配置目录
| | | └─ index.jsx <-- 路由配置文件
| | ├─ App.jsx <-- 项目主页面文件(删除)
| | ├─ main.jsx <-- 渲染进程入口文件
| | └─ index.html <-- 渲染进程HTML模板
├─ .editorconfig <-- IDE配置文件
├─ .eslintignore <-- 忽略eslint检查的配置文件
├─ .eslintrc.cjs <-- eslint配置文件
├─ .gitignore
├─ .npmrc <-- npm镜像源配置文件
├─ .prettierignore <-- 忽略prettier代码格式化的配置文件
├─ .prettierrc.yaml <-- prettier代码格式化配置文件
├─ dev-app-update.yml
├─ electron-builder.yml <-- build配置文件
├─ electron.vite.config.js <-- electron-vite配置文件
├─ package.json
├─ README.md
└─ yarn.lock
注意以上项目结构中,由于本教程使用页面路由,src/renderer/App.jsx将在后续章节中被删除。
接下来,就按照上面的目录结构开始构建项目。
4.2 关于样式命名规范
以我多年来的开发经验来讲,合理的样式命名规范对项目开发有很大的帮助,主要体现在以下方面:
(1)避免因样式名重复导致的污染。
(2)从命名上可直观区分"组件样式"、"页面样式"(用于给在此页面的组件样式做定制调整)、"全局样式"。
(3)快速定位模块,便于查找问题。
分享一下本教程的样式命名规范:
G-xx: 表示全局样式,用来定义公用样式。
P-xx: 表示页面样式,用来设置页面的背景色、尺寸、定制化调整在此页面的组件样式。
M-xx: 表示组件样式,专注组件本身样式。
后续教程中,可以具体看到以上规范是如何应用的。
4.3 设置全局公用样式
我个人比较喜欢Stylus简洁的语法,因此本教程以Stylus作为css预处理语言。各位可以根据自己的习惯,自由选择Sass/Scss、Less、Stylus。
新建清零样式文件,src/renderer/common/styles/reset.styl。
由于reset.css代码较多,这里不再放出。非常推荐参考这个reset css,代码比较全面,更新也比较及时(截至本文写作时,是2023年9月20日更新的)。
CSS reset代码详见:github.com/elad2412/th...
新建全局样式文件,src/renderer/common/styles/global.styl:
arduino
html, body, #root
height: 100%
/*清浮动*/
.clearfix:after
content: "."
display: block
height: 0
clear: both
visibility: hidden
.clearfix
display:block
全局样式将应用于项目的所有页面,可根据需要自行补充或调整。
新建全局样式总入口文件,src/renderer/common/styles/frame.styl:
scss
@import './reset.styl';
@import './global.styl';
在frame.styl里引入其他公用样式,就方便一次性全部应用到项目中了。
然后在src/renderer/main.jsx里引入frame.styl:
javascript
import ReactDOM from 'react-dom/client'
import App from './App'
+ // 全局样式
+ import '@renderer/common/styles/frame.styl'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App />)
这样在所有页面里就可以直接使用全局样式了。
现在运行项目,可以发现reset、global中的样式已经生效。
5 引入Ant Design 5.x
Ant Design是一款非常优秀的UI库,在React项目开发中使用非常广泛。Ant Design发布5.x后,使用起来更加快捷,而且在主题换肤方面更加便捷。本次分享也特别说明下如何使用Ant Design(以下简称Antd)。
5.1 安装Ant Design
执行:
csharp
yarn add antd
然后修改src/renderer/App.jsx 来验证下Antd:
javascript
import { Button } from 'antd'
function App() {
return (
<div className="App">
<h1>Electron-Vite-React-App</h1>
<Button type="primary">Button</Button>
</div>
)
}
export default App
执行yarn dev:
可以看到Antd的Button组件正常显示出来了。
※注: Antd 5.x已经没有全局污染的reset样式了。因此不用再担心使用了Antd会影响页面样式。
5.2 设置Antd为中文语言
Antd默认语言是英文,需进行以下设置调整为中文。
修改src/renderer/main.jsx:
javascript
import ReactDOM from 'react-dom/client'
import App from './App'
+ import { ConfigProvider } from 'antd'
+ // 引入Ant Design中文语言包
+ import zhCN from 'antd/locale/zh_CN'
// 全局样式
import '@/common/styles/frame.styl'
const root = ReactDOM.createRoot(document.getElementById('root'))
M root.render(
M <ConfigProvider locale={zhCN}>
M <App />
M </ConfigProvider>
M )
6 渲染进程页面开发
本教程包含Login、Home两个业务页面,使用react-router-dom实现页面跳转。本教程重点讲解Electron,因此不再深入讲解react-router-dom。
工程文件变动如下:
❤️❤️❤️------试读结束------❤️❤️❤️
后续精彩章节
bash
6 渲染进程页面开发
• 6.1 构建Login页面
• 6.2 构建Home页面
• 6.3 实现页面路由跳转
• 6.4 在React组件中实现页面路由跳转
• 6.5 在非React组件中实现页面路由跳转
7 主进程与渲染进程通信方法一:send与on/once
• 7.1 预加载脚本(preload)开发
• 7.2 主进程开发
• 7.3 继续渲染进程开发
• 7.4 运行效果
• 7.5 关于ipcRenderer.on/once
8 主进程与渲染进程通信方法二:invoke与handle
• 8.1 主进程开发
• 8.2 在渲染进程显示Electron版本号
9 常用配置
• 9.1 设置应用图标
• 9.2 设置APP窗口大小
• 9.3 取消跨域限制
• 9.4 设置DevTools快捷键
• 9.5 禁止build环境的DevTools
10 build项目
• 10.1 执行build命令
• 10.2 解决windows版本编译时无法下载的问题
• 10.3 设置build版应用icon
• 10.4 其他应用信息配置
• 10.5 解决macOS build版本的Coding Siging错误
• 10.6 build后的目录结构
11 其他说明
• 11.1 源代码保护
• 11.2 敏感字符串保护
• 11.3 主进程热更新
• 11.4 禁止同个Electron程序多开
• 11.5 允许windows用户更改安装目录
• 11.6 批量升级全部项目npm依赖包
12 项目Git源码
结束语
阅读完整版
📖 完整教程可订阅我的公众号【卧梅又闻花】
《2023金秋版:基于electron-vite构建React桌面客户端》
项目Git源码
本项目已上传至Gitee和GitHub,方便各位下载。
Gitee:
gitee.com/betaq/elect...
GitHub: