Electron入门篇

2,096 阅读8分钟

关于electron

Electron 是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架。它完全兼容 Mac、Windows 和 Linux,真正实现了跨平台的桌面端应用解决方案。

技术架构

Electron的核心技术架构是由 Chromium + Node.js + Native APIs 组成的。 avatar

接下来,我们简单介绍一下它的三大核心武器:

  • 首先是 Chromium,我们可以把它理解为是一个拥有最新版浏览器特性的一个 Chrome 浏览器,它带给我们的好处就是在开发过程中无需考虑浏览器的兼容性,我们可以使用一些 ES6、ES7 最新的语法,可以放心的使用 Flex 布局,以及浏览器的最新特性,都可以尝试,不需要考虑兼容性的问题。
  • Node.js 则是提供了一个文件读写、本地命令调用、以及第三方扩展的能力,并且基于 Node.js 整个强大的生态,将近几十万的 Node.js 模块都可以在整个客户端内使用。
  • Native APIs 提供了一个统一的原生界面的能力,还包括一些系统通知、快捷键,还可以通过它来获取一些系统的硬件信息。还提供了桌面客户端的基础能力,像更新机制、崩溃报告这样的能力。

Chromium和chrome浏览器的区别

Chromium是google开源的浏览器项目,由开源社区维护,它支持Windows、Mac、Linux等多种操作系统,国内的大多数双核浏览器都是基于它进行开发的。

Chrome浏览器也是基于Chromium进行的二次开发。在Chromium的基础上,chrome提供了额外的高阶功能:

  • 对特殊音频格式的支持,如AAC, H.264和MP3编码
  • 内置Flash插件
  • 自动更新: Chrome的Windows和Mac用户可获得额外的后台应用,可自动让Chrome保持最新版本
  • 扩展限制:对于Chrome,Google会停用未在Chrome网上应用商店中托管的扩展程序。
  • 崩溃和错误报告:Chrome用户可以选择将有关崩溃和错误的统计信息发送给Google进行分析。

快速开始

安装electron应用

可以参考官方文档-打造你的第一个electron应用,大家也可以直接copy下面的代码在命令行执行,就可以立马体验一个electron应用的demo了。

git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start

引入react

渲染层面的技术架构你可以选择自己需要的,不一定是react,也可以vue、angular等,这里我以react为例子,这里直接用react的官方脚手架即可。

npx create-react-app electron-quick-start
cd electron-quick-start
npm start

我们把react的脚手架也安装在了electron的目录里面,因此需要做些调整和改动。首先需要对electron项目和react项目的两个package.json进行合并,将启动electron的命令改为npm run electron;其次是将electron的入口文件main.js里面加载视图的文件路径改为http://localhost:3000/,main.js的部分代码如下:

const isDev = require('electron-is-dev')

function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
	if(isDev){
    mainWindow.loadURL('http://localhost:3000/') // 这里改为react的启动目录
  } else {
    mainWindow.loadFile(path.join(__dirname, '/../build/index.html')) // 加载打包后的html
  }
}

至此,我们就可以愉快的在electron项目中使用react了。显而易见,这里的缺点是需要同时启动两个命令,你如果想要一个命令启动,安装对应的工具库即可。

当然,如果要在正式项目中使用,可以安装 electron-forge,这是一个成熟的脚手架,集成了打包、发布功能,还可以选择模板(如React、Vue、Angular 等)作为渲染层框架。

进程间通信

要了解什么是进程间通信,首先要了解electron中的两个重要的概念,就是关于主进程和渲染进程。

主进程

  • Electron中运行package.json中的main脚本的进程被称为主进程,即main.js就是运行在主进程
  • 一个electron应用有且只有一个主进程。
  • 只有主进程可以直接进行GUI相关的原生API操作。

渲染进程

  • 运行在Chromium的web页面姑且叫渲染进程,即运行index.html的环境就是渲染进程。
  • 一个electron应用可以有多个渲染进程。
  • 渲染进程在引入Node.js 模块的前提下,可以在页面中和操作系统进行一些底层交互(如fs模块)。

如何通信

知道什么是主进程和渲染进程以后,接下来就介绍一下主进程和渲染进程之间是如何通信的呢?

主进程和渲染进程之间是通过ipcRenderer 和 ipcMain 模块通信的。具体API文档可以参考官方示例,这里举一个渲染进程向主进程通信的例子。

举例:页面中有一个textarea输入框,用户输入内容以后点击“保存到本目录”,即可保存输入框内容到本目录的msg.txt文件夹中。 avatar 这样一个简单的通信过程就完成了,当然主进程也可以主动向渲染进程通信,以及渲染进程之间的通信,这里不再赘述,原理也是类似的。

打包

打包是开发桌面端应用最后一步,也是必不可少的一步,目前市面上比较常用的electron打包工具有两种,electron-packagerelectron-builder,我们项目中采用是比较简单的第一种打包工具。

electron-packager

这个打包工具的特点如下:

  • 可以直接生成.app.exe 等可执行的文件,用户无需安装,打开即可使用
  • 配置简单,通常一句命令行就可搞定

下面是一个例子,package.json的部分代码:

"scripts": {
  "start": "electron .",
  "packageOS": "electron-packager . DMS企业版 --platform=mas --arch=x64 --icon=dms --out=./dist --asar --app-version=1.0.0",
  "packageWin64": "electron-packager . 'DMS企业版 --platform=win32 --arch=x64 --icon=dms --out=./dist --asar --app-version=1.0.0",
  "packageWin32": "electron-packager . DMS企业版 --platform=win32 --arch=ia32 --icon=dms --out=./dist --asar --app-version=1.0.0"
},

具体的参数含义大家可以参考开发文档,需要注意的是不同平台打包所需要的图片格式也是不一样的,mac的直接是png格式的图片就可以,而windows的是icns格式图片。

electron-builder

electron-builder不仅可以打包为可执行文件,还可以打包为可安装程序,功能与electron-packager相比也要丰富一些,所以打包的配置也是更为繁琐。从github数据来看 electron-builder 比 electron-packager 多2000+颗星,由此可见electron-builder应用会更广泛一些。

热更新

CDN资源更新

在某些场景下(如:一般在web页面开发的时候我们的静态资源都是CDN化的,为了和web共用一套代码,我们可以在APP端直接引用这些静态资源,另外就是增量更新的场景),我们的UI视图层代码是托管在CDN上的,为了实现这时候如果用户一直不重启或者刷新APP,那么这些静态资源也是不会主动更新的;这个时候我们常见的做法是通过轮询调用接口或者服务端推送,来获取是否更新的通知,如果发现有更新,则弹窗提醒用户,让用户重载整个页面,达到刷新的目的。

应用包更新

除了上面CDN的情况,还有一种情况是所有的资源都被打包在了APP,这个时候如果系统有更新要怎么办呢? 此时要分两种情况,一是能够直接使用update.electronjs.org的情况,另外一种是使用自己的更新服务器。

1)使用 updata.electronjs.org 更新 能够直接使用该工具库的前提是:

  • 应用运行在 macOS 或者 Windows
  • 应用有公开的 GitHub 仓库
  • 编译的版本发布在 GitHub Releases
  • 编译的版本已代码签名

在具备了该前提的情况下直接安装update-electron-app使用即可

npm install update-electron-app

从你的应用的 main process 文件调用这个更新:

require('update-electron-app')()

默认情况下,这个模块会在应用启动的时候检查更新,然后每隔十分钟再检查一次。 当发现了一个更新,它会自动在后台下载。 当下载完成后,会显示一个对话框以允许用户重启应用。

2)部署更新服务器 如果你开发的是一个私有的 Electron 应用程序,或者你没有在 GitHub Releases 中公开发布,你可能需要运行自己的更新服务器。 根据你的需要,你可以从下方选择:

  • Hazel – 用于私人或开源应用的更新服务器,可以在 Now 上免费部署。 它从GitHub Releases中拉取更新文件,并且利用 GitHub CDN 的强大性能。
  • Nuts-同样使用GitHub Releases, 但得在磁盘上缓存应用程序更新并支持私有存储库。
  • electron-release-server – 提供一个用于处理发布的仪表板,并且不需要在GitHub上发布发布。
  • Nucleus – 一个由Atlassian维护的 Electron 应用程序的完整更新服务器。 支持多种应用程序和渠道; 使用静态文件存储来降低服务器成本。

更新服务器部署好以后,你就可以直接调用electron的 autoUpdater 模块进行更新通知了

const { app, autoUpdater, dialog } = require('electron')

// 构建更新服务器的URL并且通知autoUpdater
const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}`

autoUpdater.setFeedURL({ url })

// 轮询检查更新
setInterval(() => {
  autoUpdater.checkForUpdates()
}, 60000)

检测到更新后通知用户代码:

// 成功通知
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
  const dialogOpts = {
    type: '消息',
    buttons: ['立即重启', '稍后再试'],
    title: '更新通知',
    message: process.platform === 'win32' ? releaseNotes : releaseName,
    detail: 'A new version has been downloaded. Restart the application to apply the updates.'
  }

  dialog.showMessageBox(dialogOpts).then((returnValue) => {
    if (returnValue.response === 0) autoUpdater.quitAndInstall()
  })
})

// 失败通知
autoUpdater.on('error', message => {
  console.error('There was a problem updating the application')
  console.error(message)
})

更多内容你也可以参考官方文档更新应用程序部分。

参考文档:

www.electronjs.org/docs github.com/electron cnodejs.org/topic/57812… www.electronjs.org/docs/tutori…