Electron结合React和TypeScript进行开发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Electron结合React和TypeScript进行开发相关的知识,希望对你有一定的参考价值。

参考技术A

electron是使用javascripthtml和CSS构建 跨平台 桌面应用程序 。我们可以使用一套代码打包成Mac、Windows和Linux的应用,electron比你想象的更简单,如果把你可以建一个网站,你就可以建一个桌面应用程序,我们只需要把精力放在应用的核心上即可。

工程架构

index.html

App.tsx

index.tsx

将 electron 包安装到您的应用程序的 devDependencies .

main.js

Angular和Electron这样结合,开发效率直接拉满

公司使用Angular+Electron进行PC端应用开发,使用开源项目angular-electron作为模板(https://github.com/maximegris/angular-electron ),但随着项目的进行,被如下的几个痛点折磨得不行:

  • 使用tsc编译主进程的代码,无法让主进程的代码热更新(需要重启,非常麻烦+耗时)
  • 主进程和渲染进程的启动没有结合好,以至于在关闭应用的时候,渲染进程需要另外去杀死(不方便)
  • 渲染进程没有添加HMR,每次代码变更,导致整个项目Reload(非常耗时)

Attention: 本文对照源码食用更佳 : https://github.com/simo-an/ng-electron 😁

接下来我们在上班摸鱼时间写一个打包脚本来解决上述的问题


启动渲染进程,使用angular-cli的命令

import NgCli from "@angular/cli";
import * as WaitOn from "wait-on";

function startRenderer(): Promise<void> 
  NgCli( cliArgs: ['serve', '--configuration', 'development'] );

  return WaitOn( resources: ['tcp:4200'] ); // 监听默认 4200 端口


编译主进程,我们使用Webpack对其打包

Webpack的配置代码详细见 https://github.com/simo-an/ng-electron/blob/master/scripts/app-runner/webpack.main.config.ts

🙄 那我们怎样做到主进程的热更新呢?

  • 启动主进程,并记录其进程信息
  • Webpack检查到有代码更新时,根据进程ID杀死原进程
  • 重新启动主进程,更新记录的进程信息

这样是不是就很完美(思路来自electron-vue😛)

编译打包主进程的代码如下

import * as webpack from 'webpack';
import mainConfig from './webpack.main.config'; // 获取 Webpack 配置文件

let electronProcess = null;  // 记住的主进程信息
let manualRestart = false; // 记录主进程被杀死是不是手动杀死的(即是不是热启动)

function startMain(): Promise<void> 
  return new Promise<void>((resolve, reject) => 
    const compiler = webpack.webpack(mainConfig);

    compiler.watch(, (err, stats) => 
      if (err)  return ;  // 出错
      if (!electronProcess || electronProcess.kill) return resolve();  // 进程已经杀死

      // 手动重启,对于上面的三个步骤  
      manualRestart = true;
      process.kill(electronProcess.pid);
      electronProcess = null;
      startElectron();    // 启动 Electron

      setTimeout(() => manualRestart = false, 5000);
    );
  );

启动应用的代码如下startElectron(),注意🧐下面我们开始启动Electron

let electronProcess = null;  // 记住的主进程信息
let manualRestart = false; // 记录主进程被杀死是不是手动杀死的(即是不是热启动)

function startElectron(): void 
  const args = [
    '--inspect=5858',
    path.join(__dirname, '../../dist/electron-main/main.js') // 主进程入口文件
  ];

  // 记住主进程(下次有代码更新时就杀死)
  electronProcess = spawn(require('electron'), args); 

  electronProcess.on('close', () =>   if (!manualRestart) process.exit(); );

这部分的代码里,我如果主动退出应用,会将整个Process全部杀死,解决了主进程关闭,渲染进程还在运行的问题。

最后,启动,运行

Promise.all([ startRenderer(), startMain() ]).then(startElectron)

撒花,完结,我们上面的两个痛点解决啦 😆

  • 使用webpack打包编译主进程代码并添加热启动(无需重启,简单+省时)
  • 主、渲染进程相互配合,同生同死(方便)

然而最后一个问题在Webpack11 + 变得非常容易解决啦,只需要在angular.json中配置模块热更新即可 🤒


// ...
    "serve": 
        "development": 
          "hmr": true,
          "browserTarget": "ng-electron:build:development"
        
      
      // ...
    
// ...


至此,我们项目中的三个痛点全部解决

  • 使用webpack打包编译主进程代码并添加热启动(无需重启,简单+省时)
  • 主、渲染进程相互配合,同生同死(方便)
  • 渲染进程添加HMR,每次代码变更,只重新渲染相应模块(省时)

😋😋😋😋😋😋😋😋😋😋😋😋😋小黄人分割线😋😋😋😋😋😋😋😋😋😋😋😋😋


看到这里你会不会有疑问😐

  • 你用 ts 写的代码,怎么可以当作脚本用node运行呢?
  • 那我要怎样使用electron-builder打包呢?
  • 你这个真的比老外写的那个开源的有4k+ star 的更好用吗?

clone下来看看代码,在电脑上跑一下,上面的疑惑就全解啦

欢迎访问,star or fork: https://github.com/simo-an/ng-electron

以上是关于Electron结合React和TypeScript进行开发的主要内容,如果未能解决你的问题,请参考以下文章

Springboot + mybatis + React+redux+React-router+antd+Typescript: React+Typescrip项目的搭建

Electron Forge使用

electron和vue的关系

如何使用 React 和 TypeScript 设置 Electron?

Node.js实现PC端类微信聊天软件

使用一个 NPM 命令启动 react-create-app 和 Electron.js