Electron + React 技术方案(更新中)

2023-11-26  本文已影响0人  jiansheng

选型

  1. 使用 Electron Forge 创建项目,然后手动安装 react 相关依赖。
    https://www.electronforge.io/guides/framework-integration/react-with-typescript
    其中v6版本的react-router-dom选用 MemoryRouter 或 HashRouter。

  2. electron-react-boilerplate (electron-builder)

进程间通信

Electron 继承了来自 Chromium 的多进程架构。
每个 Electron 应用都有一个单一的主进程,作为应用程序的入口点,运行在 Node.js 环境中。
每个 Electron 应用都会为每个打开的 BrowserWindow 生成一个单独的渲染器进程。
每个进程之间上下文隔离。

渲染进程与渲染进程之前不能直接通信,可以通过主进程通信。

在主进程中,实例化浏览器窗口 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_MIRROR=http://npm.taobao.org/mirrors/electron/
上一篇下一篇

猜你喜欢

热点阅读