2023新春版:手把手教你搭建Electron24+React18+Antd5架构工程
Electron是一个基于Chromium和Node.js,可以使用HTML、CSS和JavaScript构建跨平台应用的技术框架,兼容Mac、Windows和 Linux。虽然B/S是目前开发的主流,但是C/S仍然有很大的市场需求。受限于浏览器的沙盒限制,网页应用无法满足某些场景下的使用需求,而桌面应用可以方便地读写本地文件、发起跨域请求、调用更多系统资源,再加上Web开发低成本、高效率的优势,这种方式越来越受到开发者的喜爱。
2022年2月,我发布了《2022新春版:手把手教你搭建Electron17+React17+Antd架构工程》,时隔一年,Electron24已经发布,React18、Antd5等很多前端框架、UI库、依赖包都有不同程度的更新,使用方法也发生了变化。因此再次更新一版,希望能够帮助各位省去摸索的时间,少走弯路,快速完成项目开发。
本文主要分享如何使用Electron和Create-React-App开发跨平台桌面客户端。React技术栈的小伙伴不要错过哟!
先睹为快
先看下目录了解本教程都有哪些内容。
1 Electron核心概念
• 1.1 主进程
• 1.2 渲染进程
• 1.3 预加载脚本(preload.js)
2 初始化项目
• 2.1 使用create-react-app新建项目
• 2.2 精简项目
3 Webpack配置
• 3.1 配置国内镜像源
• 3.2 暴露Webpack
• 3.3 支持Sass/Scss
• 3.4 支持Less
• 3.5 支持Stylus
• 3.6 设置路径别名
• 3.7 禁止build项目生成map文件
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 集成Electron
• 7.1 通过国内镜像加速安装Electron
• 7.2 配置Electron
• 7.3 启动Electron dev热更新模式
• 7.4 禁止开发环境启动时同时打开浏览器
8 主进程与渲染进程通信方法一:send与on/once
• 8.1 主进程开发
• 8.2 preload.js开发
• 8.3 入口文件配置
• 8.4 渲染进程开发
• 8.5 打开Electron的DevTools
• 8.6 运行效果
• 8.7 关于ipcRenderer.on/once
• 8.8 为什么必须在preload里定义ipcRenderer.on/once
9 主进程与渲染进程通信方法二:invoke与handle
• 9.1 主进程开发
• 9.2 入口文件配置
• 9.3 渲染进程开发
• 9.4 运行效果
10 打包Electron
• 10.1 安装electron-builder
• 10.2 配置electron-builder
• 10.3 配置build版本的主入口
• 10.4 解决elecron-build编译过程中下载慢的问题
• 10.5 build Electron应用
• 10.6 解决nsis无法下载问题
• 10.7 build后的目录结构
11 常用配置
• 11.1 设置开发环境应用icon
• 11.2 设置build版应用icon
• 11.3 设置APP窗口大小
• 11.4 取消跨域限制
• 11.5 取消菜单栏
• 11.6 设置DevTools快捷键
• 11.7 禁止同时运行多个Electron程序
12 项目源码git
结束语
本次分享Demo的主要依赖包版本:
Node.js 18.15.0
antd 5.4.0
create-react-app 5.0.1
react 18.2.0
react-router-dom 6.10.0
sass-loader 13.2.2
webpack 5.77.0
webpack-dev-server 4.13.2
concurrently 8.0.1
electron 24.0.0
electron-builder 23.6.0
less 4.1.3
less-loader 11.1.0
node-sass 8.0.0
stylus 0.59.0
stylus-loader 7.1.0
wait-on 7.0.1
※注:
代码区域每行开头的:
"+" 表示新增
"-" 表示删除
"M" 表示修改
1 Electron核心概念
学习Electron最先要掌握的就是他的主进程与渲染进程概念。网上很多相关教程也进行了详细介绍,又是画关系图又是文字描述的。这里只想把最核心的内容总结一下,以最简单最通俗的方式让各位最快理解。
掌握三个核心概念即可:
1.1 主进程
每个Electron应用都有一个单一的主进程,作为应用程序的入口点。主进程运行在Node.js 环境,因此可以使用Node.js的所有API能力。主进程并不在浏览器环境中运行,因此不进行页面渲染。
1.2 渲染进程
渲染进程说白了就是平时的Web页面前端开发。每个Electron应用都会为每个打开的BrowserWindow生成一个单独的渲染器进程。但是渲染进程是无法直接调用Node.js的API的。
1.3 预加载脚本(preload.js)
为了让渲染进程与主进程进行通信从而形成一个整体,预加载脚本的作用就是他们之间的桥梁。预加载脚本与渲染进程共享同一个全局window,因此可以通过window来传递数据。但并不是简单地通过给window添加属性就能使用,以下方式是无法把preload.js共享给渲染进程使用的:
// 预加载脚本(preload.js)
window.myAPI = {
desktop: true
}
// 渲染进程
console.log(window.myAPI)
// => undefined(获取不到)
这是因为Electron的语境隔离(Context Isolation),使得预加载脚本与渲染进程的主要运行环境是隔离的,以避免将任何API都加入到渲染进程的网页中。
因此,需要使用contextBridge来安全地实现交互:
// 预加载脚本(preload.js)
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
desktop: true
})
// 渲染进程
console.log(window.myAPI)
// => { desktop: true } (成功获取)
以上方式就是通过contextBridge.exposeInMainWorld
将preload.js中的myAPI数据共享给渲染进程的网页使用。
官网详细介绍:
2 初始化项目
2.1 使用create-react-app新建项目
找个合适的目录,执行:
npx create-react-app electron-cra
命令最后的electron-cra是项目的名称,可以自行更改。
编写教程时,create-react-app已经发布了5.0.1,如果一直报错:
you are running create-react-app 4.0.3 which is behind the latest release (5.0.1)
说明你还在使用旧版本的create-react-app,需要先清除npx缓存,执行:
npx clear-npx-cache
然后再执行之前的命令创建项目:
npx create-react-app electron-cra
稍等片刻即可完成安装。安装完成后,可以使用npm或者yarn启动项目。
进入项目目录,并启动项目:
cd electron-cra
yarn start (或者使用npm start)
如果没有安装yarn,可执行以下命令全局安装:
npm install --global yarn
yarn中文网站: yarn.bootcss.com/
启动后,可以通过以下地址访问项目:
2.2 精简项目
接下来,删除用不到的文件,最简化项目。
├─ /node_modules
├─ /public
| ├─ favicon.ico
| ├─ index.html
- | ├─ logo192.png
- | ├─ logo512.png
- | ├─ mainfest.json
- | └─ robots.txt
├─ /src
- | ├─ App.css
| ├─ App.js
- | ├─ App.test.js
- | ├─ index.css
| ├─ index.js
- | ├─ logo.svg
- | ├─ reportWebVitals.js
- | └─ setupTests.js
├─ .gitignore
├─ package-lock.json
├─ package.json
└─ README.md
现在目录结构如下,清爽许多:
├─ /node_modules
├─ /public
| ├─ favicon.ico
| └─ index.html
├─ /src
| ├─ App.js
| └─ index.js
├─ .gitignore
├─ package-lock.json
├─ package.json
└─ README.md
以上文件删除后,页面会报错。这是因为相应的文件引用已不存在。需要继续修改代码,先让项目正常运行起来。
逐个修改以下文件,最终精简代码依次如下:
src/App.js:
function App() {
return <div className="App">React-App</div>
}
export default App
src/index.js:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App />)
public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
运行效果如下:
3 Webpack配置
3.1 配置国内镜像源
npm和yarn默认是从国外源站拉取依赖包的,为提高下载速度和稳定性,建议配置为国内镜像源。
yarn registry国内镜像:
yarn config set registry https://registry.npmmirror.com
npm registry国内镜像:
npm config set registry https://registry.npmmirror.com
yarn node-sass国内镜像:
yarn config set SASS_BINARY_SITE https://npmmirror.com/mirrors/node-sass/
npm node-sass国内镜像(仅限于npm < v9的版本):
npm config set SASS_BINARY_SITE https://npmmirror.com/mirrors/node-sass/
※注: 从npm v9 版本开始,npm 命令限制了npm config set只能设置npm官方规定的config (docs.npmjs.com/cli/v9/usin… ~/.npmrc 文件的方式实现旧版本npm config set的效果。
据淘宝官方声明,原先的 npm.taobao.org 和 registry.npm.taobao.org 域名于2022年5月31日零时起停止服务。新域名如下:
【Web 站点】npmmirror.com
【Registry Endpoint】registry.npmmirror.com
官方公告原文:《【望周知】淘宝 NPM 镜像站喊你切换新域名啦》(zhuanlan.zhihu.com/p/430580607)
如果不清楚本地当前yarn或者npm的配置,可以执行以下命令查看:
yarn查看方法:
yarn config list
npm查看方法:
npm config list
3.2 暴露Webpack
create-react-app默认情况下未暴露配置文件。如果要更灵活地配置项目,需要将配置文件暴露出来。
执行以下命令,暴露配置文件:
yarn eject
eject之前必须确保当前工程所有文件已提交git,否则会报以下错误:
Remove untracked files, stash or commit any changes, and try again.
需要先在项目根目录下执行提交git:
git add .
git commit -m "初始化项目(备注)"
然后再执行:
yarn eject
即可完成Webpack的暴露,这时项目里会多出来两个目录和若干个文件。具体变化如下:
+ ├─ /config
├─ /node_modules
├─ /public
+ ├─ /scripts
├─ /src
├─ .gitignore
M ├─ package-lock.json
M ├─ package.json
└─ README.md
3.3 支持Sass/Scss
eject后,虽然package.json以及webpack.config.js里有了sass相关代码,但是要正确使用Sass/Scss,还要再安装node-sass。
执行以下命令:
yarn add node-sass --dev
安装完成后,项目已支持Sass/Scss。
3.4 支持Less
支持Less稍微多一点步骤,首先安装less和less-loader,执行:
yarn add less less-loader --dev
然后修改config/webpack.config.js:
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
+ const lessRegex = /\.less$/;
+ const lessModuleRegex = /\.module\.less$/;
...(略)
// Opt-in support for SASS (using .scss or .sass extensions).
// By default we support SASS Modules with the
// extensions .module.scss or .module.sass
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
},
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'local',
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
+ // 支持Less
+ {
+ test: lessRegex,
+ exclude: lessModuleRegex,
+ use: getStyleLoaders(
+ {
+ importLoaders: 3,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
+ modules: {
+ mode: 'icss',
+ },
+ },
+ 'less-loader'
+ ),
+ sideEffects: true,
+ },
+ {
+ test: lessModuleRegex,
+ use: getStyleLoaders(
+ {
+ importLoaders: 3,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
+ modules: {
+ mode: 'local',
+ getLocalIdent: getCSSModuleLocalIdent,
+ },
+ },
+ 'less-loader'
+ ),
+ },
其实就把上面sass配置代码复制一遍,改成less。按照以上操作后,项目已支持Less。
3.5 支持Stylus
支持Stylus跟Less完全一样,首先安装stylus和stylus-loader,执行:
yarn add stylus stylus-loader --dev
安装完成后,按照上一小节支持Less的方法,修改config/webpack.config.js:
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
+ const stylusRegex = /\.styl$/;
+ const stylusModuleRegex = /\.module\.styl$/;
...(略)
+ // 支持stylus
+ {
+ test: stylusRegex,
+ exclude: stylusModuleRegex,
+ use: getStyleLoaders(
+ {
+ importLoaders: 3,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
+ modules: {
+ mode: 'icss',
+ },
+ },
+ 'stylus-loader'
+ ),
+ sideEffects: true,
+ },
+ {
+ test:stylusModuleRegex,
+ use: getStyleLoaders(
+ {
+ importLoaders: 3,
+ sourceMap: isEnvProduction
+ ? shouldUseSourceMap
+ : isEnvDevelopment,
+ modules: {
+ mode: 'local',
+ getLocalIdent: getCSSModuleLocalIdent,
+ },
+ },
+ 'stylus-loader'
+ ),
+ },
完成以上操作后,项目已支持Stylus。
3.6 设置路径别名
为了避免使用相对路径的麻烦,可以设置路径别名。
修改config/webpack.config.js:
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
+ '@': path.join(__dirname, '..', 'src'),
},
这样在js代码开头的import路径中,直接使用@表示“src根目录”,不用去自己去数有多少个"../"了。
例如,src/app.js:
// 表示该文件当前路径下的app.styl(相对路径)
import './app.styl'
// 表示src/app.styl,等价于上面的文件地址(绝对路径)
import '@/app.styl'
3.7 禁止build项目生成map文件
map文件,即Javascript的source map文件,是为了解决被混淆压缩的js在调试的时候,能够快速定位到压缩前的源代码的辅助性文件。这个文件发布出去,会暴露源代码。因此,建议直接禁止build时生成map文件。
修改config/webpack.config.js,把shouldUseSourceMap的值改成false:
// Source maps are resource heavy and can cause out of memory issue for large source files.
- // const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
+ const shouldUseSourceMap =false;
4 项目架构搭建
4.1 项目目录结构设计
项目目录结构可根据项目实际灵活制定。这里分享下我常用的结构,主要分为公用模块目录、组件模块目录、页面模块目录、路由配置目录等几个部分,让项目结构更加清晰合理。
├─ /config <-- webpack配置目录
├─ /node_modules
├─ /public
| ├─ favicon.ico <-- 网页图标
| └─ index.html <-- HTML页模板
├─ /scripts <-- node编译脚本
├─ /src
| ├─ /api <-- api目录
| | └─ index.js <-- api库
| ├─ /common <-- 全局公用目录
| | ├─ /fonts <-- 字体文件目录
| | ├─ /images <-- 图片文件目录
| | ├─ /js <-- 公用js文件目录
| | └─ /styles <-- 公用样式文件目录
| | | ├─ frame.styl <-- 全部公用样式(import本目录其他全部styl)
| | | ├─ reset.styl <-- 清零样式
| | | └─ global.styl <-- 全局公用样式
| ├─ /components <-- 公共模块组件目录
| | ├─ /header <-- 头部导航模块(示例)
| | | ├─ index.js <-- header主文件
| | | └─ header.styl <-- header样式文件
| | └─ ... <-- 其他模块
| ├─ /pages <-- 页面组件目录
| | ├─ /home <-- home页目录
| | | ├─ index.js <-- home主文件
| | | └─ home.styl <-- home样式文件
| | ├─ /login <-- login页目录
| | | ├─ index.js <-- login主文件
| | | └─ login.styl <-- login样式文件
| | └─ ... <-- 其他页面
| ├─ /router <-- 路由配置目录
| | ├─ index.js <-- 路由配置文件
| ├─ index.js <-- 渲染进程入口文件
| ├─ main.js <-- 主进程入口文件
| ├─.gitignore
| ├─ package.json
| ├─ README.md
| └─ yarn.lock
注意以上项目结构,已经没有src/App.js了,现在先不用删除,随着后续章节的讲解再删除。
接下来,就按照上面的目录结构开始构建项目。
4.2 关于样式命名规范
以我多年来的开发经验来讲,合理的样式命名规范对项目开发有很大的帮助,主要体现在以下方面:
(1)避免因样式名重复导致的污染。
(2)从命名上可直观区分“组件样式”、“页面样式”(用于给在此页面的组件样式做定制调整)、“全局样式”。
(3)快速定位模块,便于查找问题。
分享一下本教程的样式命名规范:
G-xx: 表示全局样式,用来定义公用样式。
P-xx: 表示页面样式,用来设置页面的背景色、尺寸、定制化调整在此页面的组件样式。
M-xx: 表示组件样式,专注组件本身样式。
后续教程中,可以具体看到以上规范是如何应用的。
4.3 设置全局公用样式
我个人比较喜欢Stylus简洁的语法,因此本教程以Stylus作为css预处理语言。各位可以根据自己的习惯,自由选择Sass/Scss、Less、Stylus。
新建清零样式文件,src/common/styles/reset.styl。
由于reset.css代码较多,这里不再放出。非常推荐参考这个reset css,代码比较全面,更新也比较及时(截至本文写作时,是2023年2月14日更新的)。
CSS reset代码详见:github.com/elad2412/th…
新建全局样式文件,src/common/styles/global.styl:
html, body, #root
height: 100%
/*清浮动*/
.clearfix:after
content: "."
display: block
height: 0
clear: both
visibility: hidden
.clearfix
display:block
全局样式将应用于项目的所有页面,可根据需要自行补充或调整。
新建全局样式总入口文件,src/common/styles/frame.styl:
@import './reset.styl';
@import './global.styl';
在frame.styl里引入其他公用样式,就方便一次性全部应用到项目中了。
然后在src/index.js里引入frame.styl:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
+ // 全局样式
+ import '@/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
执行:
yarn add antd
然后修改src/App.js 来验证下Antd:
import { Button } from 'antd'
function App() {
return (
<div className="App">
<h1>Electron-CRA</h1>
<Button type="primary">Button</Button>
</div>
)
}
export default App
执行yarn start:
可以看到Antd的Button组件正常显示出来了。
※注: Antd 5.x已经没有全局污染的reset样式了。因此不用再担心使用了Antd会影响页面样式。
5.2 设置Antd为中文语言
Antd默认语言是英文,需进行以下设置调整为中文。
修改src/index.js:
import React from 'react'
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。
工程文件变动如下,请先创建好对应的目录和文件:
├─ /config
├─ /public
├─ /scripts
├─ /src
+ | ├─ /pages
+ | | ├─ /home
+ | | | ├─ index.js
+ | | | └─ home.styl
+ | | ├─ /login
+ | | | ├─ index.js
+ | | | ├─ login.styl
+ | | | └─ logo.png
| ├─ App.js
| ├─ index.js
└─ package.json
6.1 构建Login页面
页面构建代码不再详述,都是很基础的内容了。
准备一张图片,放置于src/pages/login/logo.png。
新建src/pages/login/index.js:
import { Button, Input } from 'antd'
import imgLogo from './logo.png'
import './login.styl'
function Login() {
return (
<div className="P-login">
<img src={imgLogo} alt="" className="logo" />
<div className="ipt-con">
<Input placeholder="账号" />
</div>
<div className="ipt-con">
<Input.Password placeholder="密码" />
</div>
<div className="ipt-con">
<Button type="primary" block={true}>
登录
</Button>
</div>
</div>
)
}
export default Login
新建src/pages/login/login.styl:
.P-login
position: absolute
top: 0
bottom: 0
width: 100%
background: #7adbcb
.logo
display: block
margin: 50px auto 20px
.ipt-con
margin: 0 auto 20px
width: 400px
text-align: center
暂时修改入口文件代码,把原App页面换成Login页面。
修改src/index.js:
- import App from './App'
+ import App from '@/pages/login'
执行yarn start,看看效果:
6.2 构建Home页面
直接上代码。
新建src/pages/home/index.js:
import { Button } from 'antd'
import './home.styl'
function Home() {
return (
<div className="P-home">
<h1>Home Page</h1>
<div className="ipt-con">
<Button>返回登录</Button>
</div>
</div>
)
}
export default Home
新建src/pages/home/home.styl:
.P-home
position: absolute
top: 0
bottom: 0
width: 100%
background: linear-gradient(#f48c8d,#f4c58d)
text-align: center
h1
margin-top: 50px
color: #fff
.ipt-con
margin: 20px auto 0
text-align: center
暂时修改入口文件代码,把初始页面换成Home页面。
src/index.js:
- import App from '@/pages/login'
+ import App from '@/pages/home'
执行yarn start,看看效果:
6.3 实现页面路由跳转
为了实现页面的跳转,需要安装react-router-dom。
执行:
yarn add react-router-dom
接下来进行路由配置,新建src/router/index.js:
import { createHashRouter, Navigate } from 'react-router-dom'
import Login from '@/pages/login'
import Home from '@/pages/home'
// 全局路由
export const globalRouters = createHashRouter([
// 对精确匹配"/login",跳转Login页面
{
path: '/login',
element: <Login />,
},
// 精确匹配"/home",跳转Home页面
{
path: '/home',
element: <Home />,
},
// 如果URL没有"#路由",跳转Login页面
{
path: '/',
element: <Login />,
},
// 未匹配,,跳转Login页面
{
path: '*',
element: <Navigate to="/login" />,
},
])
接下来应用以上路由配置,修改src/index.js:
import React from 'react'
import ReactDOM from 'react-dom/client'
+ import { RouterProvider } from 'react-router-dom'
+ import { globalRouters } from '@/router'
- import App from '@/pages/home'
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'))
root.render(
<ConfigProvider locale={zhCN}>
- <App />
+ <RouterProvider router={globalRouters} />
</ConfigProvider>
)
这里使用了<RouterProvider>
实现路由跳转。同时,为了减少项目文件的依赖层级深度,也删除了<App>
,从此与App.js文件告别了。
记得删掉src/App.js。
执行yarn start启动项目,输入对应的路由地址,可以正常显示对应的页面了。
Login页面:http://localhost:3000/#/login
Home页面:http://localhost:3000/#/home
6.4 在React组件中实现页面路由跳转
下面要实现的功能是,点击Login页面的“登录”按钮,跳转至Home页面。
修改src/pages/login/index.js:
+ import { useNavigate } from 'react-router-dom'
import { Button, Input } from 'antd'
import imgLogo from './logo.png'
import './login.styl'
function Login() {
+ // 创建路由钩子
+ const navigate = useNavigate()
return (
...(略)
<div className="ipt-con">
M <Button type="primary" block={true} onClick={()=>{navigate('/home')}}>登录</Button>
</div>
...(略)
同样的方法,再来实现点击Home页面的“返回登录”按钮,跳转至Login页面。
修改src/pages/home/index.js:
+ import { useNavigate } from 'react-router-dom'
import { Button } from 'antd'
import './home.styl'
function Home() {
+ // 创建路由钩子
+ const navigate = useNavigate()
return (
<div className="P-home">
<h1>Home Page</h1>
<div className="ipt-con">
M <Button onClick={()=>{navigate('/login')}}>返回登录</Button>
</div>
</div>
)
}
export default Home
现在,点击按钮进行页面路由跳转已经实现了。
6.5 在非React组件中实现页面路由跳转
在实际项目中,经常需要在非React组件中进行页面跳转。比如,当进行API请求的时候,如果发现登录认证已失效,就直接跳转至Login页面;当API请求失败时,进行统一的报错提示。
以上这些情况的统一处理,当然是封装成公用的模块最合适。但往往这些纯功能性的模块都不是React组件,也就是纯原生js。所以就没办法使用useNavigate()了。
下面介绍一下如何实现在非React组件中进行页面路由跳转。
修改src/api/index.js:
import {globalRouters} from '@/router'
export const goto = (path) => {
globalRouters.navigate(path)
}
以上代码在非React组件中引入全局路由,并封装了goto函数。
在src/pages/home/index.js里调用goto方法:
import { useNavigate } from 'react-router-dom'
import { Button } from 'antd'
+ import { goto } from '@/api'
import './home.styl'
function Home() {
// 创建路由钩子
const navigate = useNavigate()
return (
<div className="P-home">
<h1>Home Page</h1>
+ <div className="ipt-con">
+ <Button onClick={()=>{goto('/login')}}>组件外跳转</Button>
+ </div>
<div className="ipt-con">
<Button onClick={()=>{navigate('/login')}}>返回登录</Button>
</div>
</div>
)
}
export default Home
在Home页点击“组件外跳转”按钮,可以正常跳转至Login页面了,而实际执行跳转的代码是在src/api/index.js(非React组件)中,这样就非常适合封装统一的处理逻辑。
到这里,React+Antd的部分基本介绍完了,接下来就是Electron主进程部分了。
❤️❤️❤️------试读结束------❤️❤️❤️
后续精彩章节
7 集成Electron
• 7.1 通过国内镜像加速安装Electron
• 7.2 配置Electron
• 7.3 启动Electron dev热更新模式
• 7.4 禁止开发环境启动时同时打开浏览器
8 主进程与渲染进程通信方法一:send与on/once
• 8.1 主进程开发
• 8.2 preload.js开发
• 8.3 入口文件配置
• 8.4 渲染进程开发
• 8.5 打开Electron的DevTools
• 8.6 运行效果
• 8.7 关于ipcRenderer.on/once
• 8.8 为什么必须在preload里定义ipcRenderer.on/once
9 主进程与渲染进程通信方法二:invoke与handle
• 9.1 主进程开发
• 9.2 入口文件配置
• 9.3 渲染进程开发
• 9.4 运行效果
10 打包Electron
• 10.1 安装electron-builder
• 10.2 配置electron-builder
• 10.3 配置build版本的主入口
• 10.4 解决elecron-build编译过程中下载慢的问题
• 10.5 build Electron应用
• 10.6 解决nsis无法下载问题
• 10.7 build后的目录结构
11 常用配置
• 11.1 设置开发环境应用icon
• 11.2 设置build版应用icon
• 11.3 设置APP窗口大小
• 11.4 取消跨域限制
• 11.5 取消菜单栏
• 11.6 设置DevTools快捷键
• 11.7 禁止同时运行多个Electron程序
12 项目源码git
结束语
完整教程可订阅我的公众号**【卧梅又闻花】**
2023新春版:手把手教你搭建Electron24+React18+Antd5架构工程
项目源码git
本项目已上传至Gitee和GitHub,方便各位下载。
Gitee:
Github:
转载自:https://juejin.cn/post/7218766396963143737