Electron + React 技术方案(更新中)
2023-11-26 本文已影响0人
jiansheng
选型
-
使用
Electron Forge
创建项目,然后手动安装react
相关依赖。
https://www.electronforge.io/guides/framework-integration/react-with-typescript
其中v6版本的react-router-dom
选用 MemoryRouter 或 HashRouter。
进程间通信
Electron 继承了来自 Chromium 的多进程架构。
每个 Electron 应用都有一个单一的主进程,作为应用程序的入口点,运行在 Node.js 环境中。
每个 Electron 应用都会为每个打开的 BrowserWindow 生成一个单独的渲染器进程。
每个进程之间上下文隔离。
- IPC (Inter-process communication)
主进程与渲染进程之间通过IPC
进行通信,主进程使用ipcMain
,渲染进程使用ipcRenderer
。
渲染进程与渲染进程之前不能直接通信,可以通过主进程通信。
- Preload 脚本中使用 context-bridge
在主进程中,实例化浏览器窗口 BrowserWindow
时,可以传入一个 Proload
脚本。通过这种方式,可以在渲染进程中的 window
对象上注入自定义变量、自定义方法,可以使主进程与渲染进程进行通信。
// main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
webPreferences: {
preload: 'path/to/preload.js'
}
})
// preload.js
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
desktop: true
})
// 渲染进程中
console.log(window.myAPI) // { desktop: true }
网络请求
在网页端发送请求可能会碰到跨域问题,可以在主进程的 Node.js 侧发送请求。
先在 preload.js
注入 request
方法。
// preload.js
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
import { ApiGateway, RequestOptions } from '../types/request';
export type Channels = 'ipc-example';
const electronHandler = {
request: async (options: RequestOptions): Promise<ApiGateway> => {
return await ipcRenderer.invoke('request', options);
},
};
contextBridge.exposeInMainWorld('electron', electronHandler);
export type ElectronHandler = typeof electronHandler;
新建文件 request.ts
,在 main.js
中引入。
// request.ts
import axios from 'axios';
import { ipcMain } from 'electron';
import { ApiGateway, RequestOptions } from '../../types/request';
const axiosInst = axios.create();
export async function request({
url,
method,
params,
data,
}: RequestOptions): Promise<ApiGateway> {
try {
const res = await axiosInst({
method,
url,
params,
data,
});
return {
code: 0,
data: res.data,
};
} catch (error: any) {
return {
code: 1,
message: 'unknow error',
};
}
}
ipcMain.handle('request', async (event, options: RequestOptions) => {
const result = await request(options);
return result;
});
渲染进程中,通过 electron.request
发送请求。
// react 组件中
export function Hello() {
const fetchData = async () => {
console.log('window.electron', window.electron);
const res = await window.electron.request({
method: 'get',
url: 'https://dev.usemock.com/6291d29996fcf94db80ebb34/api/list',
});
console.log('fetchData', res);
};
useEffect(() => {
fetchData();
}, []);
return <div>hello</div>;
}
请求结果
自动更新
遇到的问题
- Electron 下载依赖慢
.npmrc 配置
ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/
- electron-react-boilerplate 启动慢,多次超时
网络问题,下载 devtool 的一些扩展慢,可以网络代理,或者暂时把下图61这一行注释掉。