本文由蘑菇街前端技术团队分享。原标题“电子从零到一”已修改更改。
1.介绍

在上一篇文章《新一代跨平台桌面技术快速了解——电子》中,我们已经对电子的跨端框架有了基本的了解。
本文将带你通过电子框架开发一个跨平台的桌面,包括一个快速入门的例子,跨进程通信的原理,封装和分发,以及一些典型的技术践踏等。希望能给你启发。
沟通:
-移动IM开发入门:“初学者一个入门就够了:从零开始开发移动IM”
详细说明:开源IM框架源代码:https://github.com/JackJiang2011/MobileIMSDK
2.系列文章
本文是系列文章的第二篇。该系列的总目录如下:
IM跨平台技术学习:快速了解新一代跨平台桌面技术-电子
IM跨平台技术学习:电子第一体验
IM跨平台技术学习:vivo的电子等详细的技术栈选择和踩坑总结。
IM跨平台技术学习:蘑菇街基于电子开发IM客户端的技术实践
IM跨平台技术学习——融云基于电子的IM跨平台SDK改造实践总结
IM跨平台技术学习:网易云信电子版IM消息全文检索技术实践
3.电子导论
Electron是一个支持前端跨平台开发的框架,允许开发人员使用Javascript、HTML和CSS等前端技术构建跨平台的桌面应用程序。
电子把Chromium和Node.js组合到同一个运行时环境中,打包成Mac、Windows、Linux系统下的应用,而开发者只需要专注于前端代码的开发。
▲上图引自《快速了解下一代跨平台桌面技术——电子》
Chromium、Node.js和Native API有以下功能:
1)Chromium:为Electron提供了强大的UI能力,可以利用强大的Web生态来开发界面,无需考虑传统浏览器的兼容性;
2)Node.js:使电子具备底层运营能力,可以使用大量开源的npm包完成开发需求。
3)原生API:原生API使Electron具备跨平台、跨桌面的原生能力。
电子是三者的巧妙结合,这使得我们开发跨平台应用程序的效率非常高。
本质上是chromium浏览器,所有最新的东西都会在chromium中测试,所以电子可以体验最新的api,这也是好处之一。
这里不再重复电子的基本介绍。如果你还不知道,你可以看看这篇文章的第一部分。
4.快速开始
4.1数据准备
电子官方提供了一个名为电子快速启动的项目,可以克隆并作为模板使用。本文使用create-react-app一步步学习。
其他重要的电子开发资源:
1)电子官网:https://electronjs.org;
2)电子Github:https://github.com/electron;
3)电子开发手册:https://www.electronjs.org/zh/docs/latest/.
4.2创建react项目
#安装create-react-app命令,如果已经安装,请忽略。
npm安装-g创建-反应-应用程序
#创建电子反应项目
创建-反应-应用电子-反应
#开始项目
cd电子反应 npm启动
4.3配置电子环境1)在公共文件夹下新建一个index.html,随便写点东西:
...
你好世界
...2)接下来,创建电子主线程文件。建议写在公共路径下:const{app,BrowserWindow} =要求
//创建全局变量并在下面引用它们以避免被GC
让我们赢
函数createWindow {
//创建一个浏览器窗口并设置其宽度和高度
win = newBrowserWindow
//加载页面
win.loadFile
//打开开发者工具
win.webContents.openDevTools
//添加窗口关闭触发事件
win.on => {
Win = null//取消引用
})
}
//初始化后调用函数
app.on
//关闭所有窗口后退出。
app.on => {
//在macOS上,除非用户明确用Cmd+Q注销,
//否则,大多数应用程序及其菜单栏将保持活动状态。
如果{
app.quit
}
})
app.on => {
//在macOS上,点击dock图标,没有打开其他窗口时,
//通常在应用程序中重新创建一个窗口。
如果{
创建窗口
}
})
3)然后修改package.json中main字段对应的路径,添加start命令:{
...
" main": "main.js ",
“剧本”:“电子。”
}
4)执行npm start,会弹出如下操作界面:以上是我写的一个简单的页面。也可以写一些自己感兴趣的东西。
如上所示,已经开发了一个简单的电子跨平台桌面应用程序,真的是太容易了!
5.过程的详细说明
5.1基本认知
电子架构与Chromium架构相似,都有一个主进程和多个渲染进程。
但也有不同之处:
1)原生API暴露在每个进程中,提供原生能力;
2)引入Node.js,可以使用Node的能力;
3)但是渲染过程需要配置成使用node。
可以简单理解为:电子用Node.js环境的外壳覆盖web项目,这样我们就可以调用Node.js丰富的API,这样我们就可以用Javascript编写桌面应用,扩展很多我们在web端做不到的事情。
下图中,技术原理更容易理解:
5.2主要流程的主要特征
运行package.json主脚本的进程称为主进程。具体代码的解释将在下一节进行,本节不做过多阐述。
电子主流程的具体职责:
1)主进程连接操作系统和渲染进程,可以看作是页面和计算机之间的桥梁;
2)进程间通信和窗口管理
3)全球普遍服务;
4)只能或适合在主流程中做的事情;
5)维护一些必要的全局状态。
5.3渲染过程的主要特征
渲染过程是大家熟悉的前端环境,只是载体从浏览器变成了窗口。
注意:出于安全考虑,渲染进程不能直接访问本地资源,需要在主进程中完成。
电子渲染过程的主要特征:
1)电子使用Chromium来显示网页,所以也使用了Chromium的多进程架构;
2)每个网页运行在自己的渲染过程中;
3)使用BrowserWindow类启动渲染进程,并在进程中运行此实例。当BrowserWindow实例被销毁时,相应的渲染进程也会终止;
4)渲染过程中不能调用原生资源,但是渲染过程中也包含Node.js环境,所以可以引入Node.js。
5.4主流程与渲染流程的关系
主进程和渲染进程之间的关系主要如下:
1)主进程使用BrowserWindow实例创建网页;
2)每个BrowserWindow实例在自己的渲染过程中运行一个网页;
3)主进程管理所有页面及其对应的渲染进程;
4)因为在网页中管理原生GUI资源非常危险,容易造成资源泄露,所以不允许在网页中调用GUI相关的API。
具体关系如下图所示:
这样想它们:
也就是说,Chrome的每个标签及其页面就像是电子版中一个独立的渲染过程。即使关闭了所有标签页,Chrome依然存在。这就像电子的主进程,可以打开一个新的窗口,也可以关闭这个应用。就像下图一样。
6.从代码的角度理解流程。
6.1主流程和渲染流程
让我们来看看电子项目的基本目录结构:
应用
└─public
└-index.html-the导入文件
├-main.js -
├-IPC-Inter-process模块
├-App网络-应用通信模块
└-src -窗口管理,渲染过程

├-Components-General组件模块
├-Store-data共享模块
├-Statics-Static资源模块
└-Pages-Window业务模块
├-Window A窗
└-Window B窗口
如上图:package.json中主字段对应的文件的进程就是主进程。电子集成Chromium来显示窗口界面,窗口中看到的所有内容都用HTML来渲染。Chromium本身就是多进程渲染页面的架构,所以Electron在显示窗口时也会使用Chromium的多进程架构。而这种多进程渲染架构,在电子中被称为渲染进程。
6.2进程间通信
在Electron中,GUI相关模块只在主进程中可用,在渲染进程中不可用。
为了在渲染过程中使用它们,你需要使用ipc模块向主进程发送消息。以下是进程间通信的几种方法。
1)ipcMain ipcRenderer:
从主进程到呈现进程的异步通信,或者从主进程向呈现进程发送消息。
发送消息时,事件名称为channel。回复消息时,需要设置event.returnValue
要将异步消息发送回发送方,可以使用event.reply这个辅助方法将自动处理来自呈现进程的消息,而event.sender.send方法总是将消息发送到主进程。
以下是在渲染和主进程之间发送和处理消息的示例://在主进程中
const { ipcMain } =要求
ipcMain.on => {
console.log//输出“ping”
事件.回复;
})
ipcMain.on => {
Console.log //输出' ping '
event.returnValue = 'pong '
})
//在渲染的过程中const { ipcRenderer } =要求
Console.log) //输出“pong”
ipcRenderer.on => {
console.log//输出“乓”
})
ipcRenderer.send
2)远程模块:它为远程渲染进程和主进程之间的通信提供了一种简单的方法。您可以调用主进程对象的方法,而无需显式发送进程间消息。
例如,通过渲染过程创建浏览器窗口。
const { browser window } = require . remote
let win = newBrowserWindow
win.loadUrl
注意:反过来,如果需要从主进程访问渲染进程,可以使用webContents.executeJavascript。3)网页内容:
也就是说,通过通道向呈现进程发送异步消息可以发送任何参数。在内部,参数会被序列化为JSON,所以被参数对象破坏的函数和原型链不会被发送。
除了以上方法,还可以使用localStorage、sessionStorage等。
7.包装和出版
开发完成后,需要将应用程序打包成可执行文件,这是学习电子最重要的一步。
目前,主流的封装工具是电子封装器和电子生成器。
7.1电子封装器
1)安装依赖性:
npm i电子包装-保存-开发
2)包装:电子包装商平台=-arch =[可选标志...]
您也可以直接运行npm运行电子打包程序打包。7.2电子建造商
官方解释:
一个完整的解决方案,用于打包和构建面向macOS、Windows和Linux的ready for distribution Electron、Proton Native或Muon应用程序,并提供开箱即用的“自动更新”支持。
简单来说:electron-builder比electron-packager功能更丰富,支持更多平台,还支持自动更新。除了这几点之外,electron-builder制作的包更轻便,不暴露源代码的setup安装程序也可以打包。另外感觉比电子打包机的坑少一点。
1)安装依赖性:
电子制造-保存-开发
2)包装:{
“构建”:{
" appId": "com.xxx.app ",
“扩展”:空,
"文件":[
" build* "
],
" mac": {
" icon": "icons/icon.icns "
},
"赢":{
“目标”:“nsis”,
" icon": "icons/icon.png "
}
}
}
这是最基本的配置。当然,在封装过程中可能会遇到其他问题,需要修改配置。通常,在文件配置中只写一个构建文件夹是不够的,应该根据项目结构和打包情况添加其他路径。添加脚本命令
{
"脚本":{
【包装】:【电子建设者】
}
}
运行npm运行包包。打包后,dist目录下有可执行文件。如果打开后没有错误,则打包成功。
8.踩坑总结
我遇到的坑大部分都是包装遇到的。下面是几个典型的坑。
8.1使用电子打包机打包并报告错误。
为“electron-v6.0.2-darwin-x64.zip”生成得校验和与预期得校验和不匹配.
解决方法:将节点版本升级到8.x以上即可。8.2打开打包生成的可执行文件,报错。
这个问题可能有几个原因。
1)本地路径可能在项目中直接访问,出于安全考虑不允许浏览器访问。
2)2)package . JSON中的构建配置问题如果main.js在深度路径中,需要在下面单独添加main.js的路径:
“构建”:{
...
+ "public/main.js "
...
}
3)webpack配置中的路径直接使用__dirname。您可以使用远程模块的getAppPath方法来获取路径:const remote =要求
const app = remote.require
console . log);
参考:https://github.com/electron/electron/issues/51078.3依赖性和开发依赖性
在电子封装过程中,重要的是要区分哪些依赖于生产环境,哪些依赖于开发环境,以避免此类错误:
8.4关于慢包装
Cnpm安装各种node_modules。这样所有的包都是扁平化安装,node_modules一次展开就有很多文件,导致打包过程非常慢。
但是如果是用npm安装node_modules的时候,所有的包都是一个更深层次的树形结构。但是打包速度会快很多。
9.电子的利与弊
最后,根据实践经验,总结了电子技术的优缺点。
电子有明显的优点:
1)易用性:HTML、CSS、JS、Node、npm包、UI框架,方便高效,可以轻松实现一个好看的UI;
2)多终端操作:可以快速搭建“跨平台”的桌面应用;
3)开发时间短:与其他跨平台方案相比,更稳定,bug更少。毕竟只要浏览器外壳运行就ok;
4)兼容性问题:再也不用兼容多种浏览器了。
电子缺点同样明显:
1)安装包大:安装包略大,至少包含一个浏览器的体积。每安装一个app就相当于安装了一个chrome;
2)运行性能略差:性能不如原生应用,Mac系统有点滑,窗口系统有点掉帧;
3)内存占用大:卡启动慢,启动一个新进程,启动代价是一个NodeJS的内存开销;
4)网页加载略慢:loadURL加载白屏远程页面需要很长时间。

10.参考资料
[1]电子官方开发者手册
[2]对电子的第一次体验
【3】电子基础介绍简单明了,看完就什么都懂了。
[4]网易云信Web端IM聊天消息全文搜索技术实践


