1. Electron的核心模块
2. Tauri的核心模块
3. 选型总结
三、技术实现
1. 渲染进程代码迁移
2. 主进程代码迁移
3. 应用构建打包
4. 应用签名&更新
四、收益&总结
1. 社区活跃度还需要提升
2. Webview2的问题
3. 成熟度和稳定性还不够
背景
得物商家客服采用的是桌面端应用表现形式,而桌面端应用主要架构形式就是一套和操作系统交互的“后端” + 一套呈现界面的“前端(渲染层)”。而桌面端技术又可以根据渲染层的不同核心划分为以下几类:
C语言家族:原生开发、QT
Chromium家族:NW、Electron、CEF
Webview 家族:Tauri、pywebview、webview_java
自立山头:Flutter
在2022年5月份左右,得物商家客服开始投入桌面端应用业务,其目标是一个可以适配多操作系统(MacOS、Windows)、快速迭代、富交互的产品。
考虑到以上前提,我们当时可以选择的框架是Chromium家族或者Webview家族。但是当时对于Webview来说,Tauri 还并不成熟(在 2022年6月才发布了1.0版本)生态也不够丰富。
对于pywebview和webview_java相对于前端来说,一方面门槛较高,另一方面生态也非常少。
所以,在当时,我们选择了Chromium家族中的Electron框架。这是因为对于CEF、Electron、NW来说,Electron有着对前端开发非常友好的技术栈,仅使用JavaScript就可以完成和操作系统的交互以及交互视觉的编写,另外,Electron的社区活跃度和生态相对于其他两者也有非常大的优势。最重要的是:真的很快!
性能方面:随着商家客服入驻数量的快速增加,现有Electron桌面应用在多账户+多会话高并发场景下,占用内存特别大,存在性能瓶颈;
安全方面:Electron在内存安全性、跨平台攻击、不受限制的上下文和依赖管理等方面存在一些潜在的弱点;
体验方面:现有Electron桌面应用包体积大,下载、更新成本较高;
信息集成方面:商家客服目前需要在商家后台、商家客服后台、商家客服工作台3个系统来回切换操作,使用成本很高。
我们也发现,之前调研过的Tauri作为后起之秀,其生态和稳定性在今天已经变得非常出色,我们熟知的以下应用都是基于Tauri开发,涵盖:游戏、工具、聊天、金融等等领域:
除此之外,因为Tauri是基于操作系统自带的Webview + Rust的框架。首先,因为不用打包一个Chromium,所以包体积非常的小:
其次Rust作为一门系统级编程语言,具有以下特点:
内存安全:Rust通过所有权和借用机制,在编译时检查内存访问的安全性,避免了常见的内存安全问题,如空指针引用、数据竞争等;
零成本抽象:Rust提供了丰富的抽象机制,如结构体、枚举、泛型等,但不引入运行时开销。这意味着开发者可以享受高级语言的便利性,同时保持接近底层语言的性能;
并发性能:Rust内置支持并发和异步编程,通过轻量级的线程(称为任务)和异步函数(称为异步任务)来实现高效的并发处理。Rust的并发模型保证了线程安全和数据竞争的检查,以及高性能的任务调度和通信机制;
可靠性和可维护性:Rust强调代码的可读性、可维护性和可靠性。它鼓励使用清晰的命名和良好的代码结构,以及提供丰富的工具和生态系统来支持代码质量和测试覆盖率;
Rust的这些额外的特性使其成为改善桌面应用程序性能和安全性的理想选择。
技术调研
要实现Electron迁移到Tauri,得先分别了解Electron和Tauri的核心功能和架构模型,只有了解了这些,才能对整体的迁移成本做一个把控。
Electron的核心模块
基础架构
首先来看看Electron的基础架构模型:Electron继承了来自Chromium的多进程架构,Chromium始于其主进程。从主进程可以派生出渲染进程。渲染进程与浏览器窗口是一个意思。主进程保存着对渲染进程的引用,并且可以根据需要创建/删除渲染器进程。
每个Electron的应用程序都有一个主入口文件,它所在的进程被称为 主进程(Main Process)。而主进程中创建的窗体都有自己运行的进程,称为渲染进程(Renderer Process)。每个Electron的应用程序有且仅有一个主进程,但可以有多个渲染进程。
应用构建打包
打包一个Electron应用程序简单来说就是通过构建工具创建一个桌面安装程序(.dmg、.exe、.deb 等)。在Electron早期作为 Atom 编辑器的一部分时,应用程序开发者通常通过手动编辑Electron二进制文件来为应用程序做分发准备。随着时间的推移,Electron社区构建了丰富的工具生态系统,用于处理Electron应用程序的各种分发任务,其中包括:
这样,应用程序开发者在开发Electron应用时,为了构建出跨平台的桌面端应用,不得不去了解每个包的功能并需要将这些功能进行组合构建,这对新手而言过于复杂,无疑是劝退的。
应用签名&更新
现在绝大多数的应用签名都采用了签名狗的应用签名方式,而我们的商家客服桌面端应用也是类似,Electron Builder提供了一个sign的钩子配置,可以帮助我们来实现对应用代码的签名:
(详细的可以直接阅读electron builder官网介绍,这里只做简单说明)
对于应用更新而言,我们之前采用的是electron-updater自动更新模式:
Tauri的核心模块
基础架构
那么,Tauri的基础架构模型是什么样的?其实官网对这块的介绍比较有限,但是我们可以通过其源码仓库和代码结构管中窥豹的了解Tauri的核心架构模型,为了方便大家理解,我们以得物商家客服桌面端应用为模型,简单的画了一个草图:
一些核心模块的解释:
WRY
由于Web技术具有表现力强和开发成本低的特点,与 Electron 和NW等框架类似,Tauri应用程序的前端实现是使用Web技术栈编写的。那么Tauri是如何解决Electron/CEF等框架遇到的Chromium内核体积过大的问题呢?
也许你会想,如果每个应用程序都需要打包浏览器内核以实现Web页面的渲染,那么只要所有应用程序共享相同的内核,这样在分发应用程序时就无需打包浏览器内核,只需打包Web页面资源。
TAO
跨平台应用窗口创建库,使用Rust编写,支持Windows、MacOS、Linux、iOS和Android等所有主要平台。该库是winit的一个分支,Tauri根据自己的需求进行了扩展,如菜单栏和系统托盘功能。
JS API
这个API是一个JS库,提供调用Tauri Rust后端的一些API能力,利用这个库可以很方便的完成和Tauri Rust后端的交互以及通信。
看起来有点复杂,其实核心也是分成了主进程和渲染进程两个部分。
Tauri的主进程使用Rust编写,Tauri在主进程中提供了一些常用的Rust API比如窗口创建、消息提醒... 如果我们觉得主进程提供的API不够,那么我们可以通过Tauri的插件体系自行扩展。
Tauri的渲染进程则是运行在操作系统的Webview当中的,我们可以直接通过JS + HTML + CSS来编写,同时,Tauri会为渲染进程注入一些全局的JS API函数。比如fs、path、shell等等。
Tauri
这是将所有组件拼到一起的crate。它将运行时、宏、实用程序和API集成为一款最终产品
应用构建打包
此命令会将渲染进程的Web资源 与 主进程的Rust代码一起嵌入到一个单独的二进制文件中。二进制文件本身将位于src-tauri/target/release/[应用程序名称],而安装程序将位于src-tauri/target/release/bundle/。
应用签名&更新
Tauri的签名和Electron类似,如果需要自定义签名钩子方法,在Tauri中现在也是支持的:
后面我们会详细介绍该能力的使用方式。
而对于更新而言,Tauri则有自己的一套体系:Updater | Tauri Apps这里还是和Electron有着一定的区别。
选型总结
通过上面的架构模型对比,我们可以很直观的感受到如果要将我们的Electron应用迁移到Tauri上,整体的迁移改造工作可以总结成以下图所示:
核心内容就变成了以下四部分内容:
主进程的迁移:而对于商家客服来说,目前主要用的有:
自定义窗口
autoUpdater自动更新
BrowserWindow窗口创建
Notification消息通知
Tray系统托盘
IPC通信
而这些API在Tauri中都有对应的实现,所以整体来看,迁移成本和技术可行性都是可控的。
渲染进程的迁移:渲染进程改造相对而言就少很多了,因为Tauri和Electron都可以直接使用前端框架来编写渲染层代码,所以几乎可以将之前的前端代码直接平移过来。但是还是有一些小细节需要注意,比如IPC通信、JS API的改变、兼容性... 这部分后面也会详细介绍。
应用构建打包:从之前的Electron构建模式改成Tauri构建模式,并自动化整个构建流程和链路。
应用签名&更新:签名形式不用改,主要需要调整签名的配置,实现对Tauri应用的自动签名和自动更新能力。
最终,我们选择了Tauri对现有的商家客服桌面端进行架构优化升级。
技术实现
渲染进程代码迁移
目录结构调整
在聊如何调整Tauri目录结构之前,我们需要先来了解一下之前的Electron应用目录结构设置,一个最简单的Electron应用的目录结构大致如下:
其中文件说明如下:
有的时候你可能需要划分目录来编写不同功能的代码,但是,不管功能目录怎么改,最终的渲染进程和主进程的构建产物都是期望符合类似于上面的结构。
所以,之前得物的商家客服也是类似形式的目录结构:
对于Tauri来说,Tauri打包依托于两个部分,首先是对前端页面的构建,这块可以根据业务需要和框架选择(Vue、 React)进行构建脚本的执行。一般前端构建的产物都是一个dist文件包。
然后是Tauri后端程序部分的构建,这块主要是对Rust代码进行编译成binary crate。
(Tauri后端的编译在很大程度上依赖于操作系统原生库和工具链,因此当前无法进行有意义的交叉编译。所以,在本地编译我们通常需要准备一台mac和一台Windows电脑,以满足在这两个平台上的构建。)
所以,这里对渲染进程的目录调整就很清晰了,直接将我们之前Electron中的renderer-process目录中的代码迁移到src目录中即可。
注意:因为我们对渲染进程目录进行了调整,所以对应的打包工具的目录也需要进行调整。
跨域请求处理
商家客服中会有一些接口请求,这些接口请求有的是从业务中发起的,有的使用依赖的npm库中发起的请求。但因为是客户端引用,当从客户端环境发起请求时,请求所携带的origin是这样的:
那么,就会遇到一个我们熟知的一个前端跨域问题。这会导致如果不在access-ctron-allow-origin中的域名会被block掉。
如果有小伙伴对Electron比较熟悉,可能会知道在Electron实现跨域的方案之一是可以关闭浏览器的跨域安全检测:
或者在请求返回给浏览器之前进行拦截,手动修改access-ctron-allow-origin让其支持跨域:
达到的效果就像这样:
那么Tauri中可以这么做吗?答案是不行的!
虽然Tauri虽然和Electron进程模型很类似,但是本质上还是有区别的,最大的区别就是Electron中的渲染进程是基于Chromium魔改的,他可以在Chromium中植入一些控制器来修改Chromium的一些默认行为。但Tauri完全是基于不同平台的内置Webview封装,考虑的兼容性问题,并没有对Webview进行改造(虽然Windows的Webview2支持 --disable-web-security,但是其他平台不行)。所以他的跨域策略是Webview默认的行为,无法调整。
那么在Tauri中,如何发起一个跨域请求了?
其实社区也有几种解决方案,接下来简单介绍一下社区的方案和问题。
使用axios adapter
问题:假设项目中依赖一个npm库,这个库中发起了一个axios请求,那么也需要对这个库的axios进行适配器改造。这样还是解决不了三方依赖使用axios的问题。我们还是需要侵入npm包进行axios改造。另外,如果其他库使用的是xhr或者fetch来直接发请求或者,那就又无解了。
最后,不管使用方案1还是2,都有个通病,那就是请求都是走的Tauri后端来发起的,这也意味着我们将在Webview的devtools中的network看不到任何请求的信息和响应的结果,这对开发调试来说无疑是非常难以接受的。
核心代码:
那怎么解决devtools没法调试请求的问题呢?
所以我们只能采用新的方式来支持,那就是外接devtools。啥意思呢?就是在操作系统网络层代理掉网络请求,然后输出到另一个控制台中进行展示,原理类似于Charles。
到这里,我们就完成了对跨域网络请求的处理改造工作。核心架构图如下:
关键性API兼容
Tauri依赖的操作系统webview并没有实现对Notification 的支持,webview本身希望宿主应用自行实现对Notification的实现,所以Tauri就重写了JS的Notification API,当你在调用window Notification的时候,实际上你和Rust进程完成了一次通信,调用的还是tauri::Notification模块。
在Tauri源码里面,是这样实现的:
除此之外,Tauri还分别实现了:
DOM上标签的点击跳转功能,使用内置的TauriAPI进行打开webview。
差异化操作系统原生窗口的拖拽和最大化事件:在Windows和Linux上,当鼠标按下时拖动,双击时最大化;而在MacOS上,最大化应该在鼠标抬起时发生,如果双击后鼠标移动,应该取消最大化。
所以,我们在对商家客服从Electron迁移到Tauri的过程中,还需要对这些关键性API进行兼容性测试和回归。一旦发现相关API不符合预期,我们需要及时调整业务策略或者给尝试进行hack。
(这里卖个关子,虽然Tauri不支持对Notification的点击事件回调,那么我们是怎么让他支持的呢?在下一节主进程代码迁移中我们会详细介绍。)
兼容性回归
对于样式兼容性来说,因为Electron在不同操作系统内都集成了Chromium所以我们完全不用担心样式兼容性的问题。但是对于Tauri来说,因为不同操作系统使用了不同的Webview,所以在样式上,我们还是需要注意不同操作系统下的差异性,比如:以下分别是Linux和Windows渲染Element-Plus的界面:
可以看到在按钮大小、文字对齐等样式上面还是存在着不小的差距。
除了上述问题,如果你需要兼容Linux系统,那么还有webkitgtk在非整数倍缩放下的bug,应该是陈年老问题了。当然,这些问题都是上游webkitgtk的“锅”。
对于Electron应用的用户来说,可能没有这样的烦恼,最新的API只要Chrome支持,那就可以用。
主进程代码迁移
自定义操作栏窗口
默认情况,在构建窗口的时候,会使用系统自带的原生窗口样式,比如在MacOS下的样式:
在有些情况下,操作系统的原生窗口并不能符合我们的一些视觉和交互需求。所以,在创建桌面应用的时候,有时候我们希望能完全掌控窗口的样式,而隐藏掉系统提供的窗口边框和标题栏等。这个时候就需要用到自定义操作栏窗口。比如在Windows中,我们希望在右上角有一排自定义的操作栏,就像是这样:
商家客服桌面端的窗口就是一个无边框的自定义操作栏的窗口,在Electron中,我们可以这样操作快速创建一个无边框窗口:
然后在渲染进程中,自己 “画一个标题栏”:
然后定义一下icon的样式:
单例模式
通过使用窗口单例模式,可以确保应用程序在用户尝试多次打开时只会有一个主窗口实例,从而提高用户体验并避免不必要的资源占用。在Electron中可以很容易做到这一点:
但是,在Tauri中,我需要引入一个单例插件才可以:
其在Windows下判断单例的核心原理是借助了windows_sys这个Crate中的CreateMutexW API来创建一个互斥体,确保只有一个实例可以运行,并在用户尝试启动多个实例时,聚焦于已经存在的实例并传递数据,简化后的代码大致如下:
系统消息通知能力
消息通知是商家客服桌面端应用必不可少的能力,消息通知能力一般可以分为以下两种:
触达操作系统的消息通知
用户点击消息后的回调事件
前面我们有提到,在Electron中,我们需要显示来自渲染进程的通知,那么可以直接使用HTML5的Web API来发送一条系统消息通知:
如果我们需要为消息通知添加点击回调事件,那么我们可以这么写:
然而,对于Tauri来说,只实现了第1个能力,也就是消息触达。Tauri本身不支持点击回调的功能,这就导致了用户发来了一个消息,但是业务无法感知客服点击消息的事件。而且原生的Web API也是Tauri自己写的,原理还是调用了Rust的通知能力。接下来,我也会详细介绍一下我们是如何扩展消息点击回调能力的。
Tauri在Rust层,我们可以通过下面这段代码来调用Notification:
这里,我们可以看到notify函数非win7环境下show函数调用的是notify_rust这个库,而在win7环境下调用的是win7_notifications这个库。而notify_rust这个库,本身确实未完成实现对MacOS和Windows点击回调事件。
所以我们需要自定义一个Notification的Tauri插件,实现对点击回调的能力。(因为篇幅原因,这里只介绍一些核心的实现逻辑)
MacOS 支持消息点击回调能力
notify_rust在Mac上实现消息通知是基于Mac_notification_sys这个库的,这个库本身是支持对点击action的response,只是notify_rust没有处理而已,所以我们可以为notify_rust增加对Mac上点击回调的处理能力:
Win 10上支持消息点击回调能力
在Windows 10操作系统中,notify_rust则是通过winrt_notification这个Crate来发送消息通知,winrt_notification 则是调用的windows这个crate来实现消息通知,windows这个crate的官方描述是:为Rust开发人员提供了一种自然和习惯的方式来调用Windows API。这里,主要会用到以下几个方法:
windows::UI::Notifications::ToastNotification::CreateToastNotification:这个函数的作用是根据指定的参数创建一个Toast通知对象,可以设置通知的标题、文本内容、图标、音频等属性,并可以指定通知被点击时的响应行为。通过调用这个函数,可以在Windows应用程序中创建并显示自定义的Toast通知,向用户展示相关信息。
windows::Data::Xml::Dom::XmlDocument:这是一个用于在Windows应用程序中创建和处理XML文档的类。它主要提供了一种方便的方式来创建、解析和操作XML数据。
windows::UI::Notifications::ToastNotificationManager::CreateToastNotifierWithId:通过调用CreateToastNotifierWithId函数,可以创建一个Toast通知管理器对象,并指定一个唯一的标识符。这个标识符通常用于标识应用程序或者特定的通知渠道,以确保通知的正确分发和管理。创建了Toast通知管理器之后,就可以使用它来生成和发送Toast通知,向用户展示相关信息,并且可以根据标识符进行个性化的通知管理。
windows::Foundation::TypedEventHandler:这是Windows Runtime API中的一个委托(delegate)类型。在Windows Runtime中,委托类型用于表示事件处理程序,允许开发人员编写事件处理逻辑并将其附加到特定的事件上。
所以,要想在> win7的操作系统中显示消息同时的主要流程大致是:
通过XmlDocument来创建一个Xml消息通知模板。
然后将创建好的Xml消息模板作为CreateToastNotification的入参来创建一个toast通知。
最后调用CreateToastNotifierWithId来创建一个Toast通知管理器对象,创建成功后显示toast。
通过TypedEventHandler监听用户点击事件并完成回调触发
但是winrt_notification这个库,只完成了1-3步骤,所以我们需要手动实现步骤4。核心代码如下:
Win 7上支持消息通知点击回调能力
在Windows 7中,Tauri调用的是win7_notifications这个库,这个库本身也没有实现对消息点击的回调处理,我们需要扩展win7_notifications的能力来实现对消息通知的回调事件。我们希望这个库可以这样调用:
而我们要做的,就是为win7_notify这个库中的Notification结构体增加一个click_event函数,这个函数支持传入一个闭包,这个闭包在点击消息通知的时候执行。
总结:
Tauri本身不支持Notification的点击事件,需要自行实现。
需要对不同操作系统分别实现点击回调能力。
MacOS mac_notification_sys库本来就有点击回调,只是Tauri没有捕获处理,需要自定义捕获处理逻辑就好了。
Windows > 7中,通过windows这个crate,来完成调用Windows操作系统API的能力,但是winrt_notification这个库并没有实现对WindowsAPI回调点击的捕获处理,所以需要重写winrt_notification这个库。
Windows 7中,消息通知其实是通过绘制窗口和监听鼠标点击来触发的,但是win7_notify本身也没有支持用户对点击回调的捕获,也需要扩展这个库的点击捕获能力。
应用构建打包
Windows 10
Tauri CLI默认情况下使用当前编译机器的体系结构来编译可执行文件。假设当前是在64位计算机上开发,CLI将生成64位应用程序。如果需要支持32位计算机,可以使用--target标志使用不同的Rust目标编译应用程序:
为了支持不同架构的编译,需要为Rust添加对应的环境支持,比如:
Windows 7
Webview 2
Tauri在Windows 7上运行有两个东西需要注意,一个是Tauri的前端跨平台在Windows上依托于Webview2但是Windows 7中并不会内置Webview2因此我们需要在构建时指明引入Webview的方式:
综合比较下来,embedBootstrapper目前是比较好的方案,一方面可以减少安装包体积,一方面减少不必要的静态资源下载。
Windows 7一些特性
在Tauri中,会通过"Windows7-compat"来构建一些Win7特有的环境代码,比如:
在Tauri文档中也有相关介绍,主要是在使用Notification的时候,需要加入Windows7-compat特性。不过,因为 Tauri 对Notification的点击事件回调是不支持,所以我重写了Tauri的所有Notification模块,已经内置了Windows7-compat能力,因此可以不用设置了。
MacOS
MacOS操作系统也有M1和Intel的区分,所以为了可以构建出兼容两个版本的产物,我们需要使用universal-apple-darwin模式来编译:
应用签名&更新
应用更新
核心流程如下:
对于需要更新的应用,可以在渲染进程通过JS调用 installUpdate() API
Tauri内部会发送一个更新协议事件:
Tauri主进程Updater模块会响应这个事件,执行download_and_install函数
下载endpoints服务器上的zip包内容并解压存储到一个临时文件夹,Windows中大概位置在C:\Users\admin\AppData\Local\Temp这里。
["-NoProfile", "-WindowStyle", "Hidden", "Start-Process"],这些参数告诉PowerShell在后台运行,不显示任何窗口,并启动一个新的进程。
"basicUi":指定安装过程中包括最终对话框在内的基本用户界面,需要用户手动点击下一步。
"quiet":安静模式表示无需用户交互。如果安装程序需要管理员权限(WiX),则需要管理员权限。
"passive":会显示一个只有安装进度条的UI,安装过程用户无需参与。
需要注意的是:如果以为更新是增量更新,不会卸载之前已经安装好的应用程序只更新需要变更的部分。其实是不对的,整个安装过程可以理解为Tauri在后台帮你重新下载了一个最新的安装包,然后帮你重新安装了一下。
总结:更新的核心原理就是通过使用Windows的PowerShell来对下载后的安装包进行open。然后由安装包进行安装。
为什么我要花这么大的篇幅来介绍 Tauri 的更新原理呢?
这是因为我们在更新的过程中碰到了两个比较大的问题:
通过cmd调用PowerShell来安装时,会在安装过程中出现一个蓝色的PowerShell控制台一闪而过:
这些都是因为Tauri直接使用Powershell的问题,那需要怎么改呢?很简单,那就是使用Windows操作系统提供的ShellExecuteW来运行安装程序,核心代码如下:
所以,你要做的就是确保Tauri升级到v1.6.8及以后版本。
应用签名
所以我们需要额外处理一下:
签名狗支持导出一个.cert证书,可以查看到证书的指纹:
这里证书的指纹对应的就是certificateThumbprint字段。
然后需要插入我们在签名机构购买的USB key。这样,在构建的时候,就会提示让我们输入密码:
到这里就可以完成对应用程序的签名。
不过对于我们而言,USB key签名狗是整个公司共享的,通常不在前端开发手里(尤其是异地办公)。一种做法是在Tauri构建的过程中,对于需要签名的软件提供一个signCommand命令钩子,并为这个命令传入文件的路径,然后交由开发者对文件进行自行签名(比如上传到拥有签名工具的电脑,上传上去后,远程进行签名,签名完成再下载)。所以这就需要让Tauri将签名功能暴露出来,让我们自行进行签名,比如这样:
该命令中包含一个%1,它只是二进制路径的占位符,Tauri在构建的时候会将需要签名的文件路径替换掉%1。
收益&总结
经过我们的不懈努力(不断地填坑)到目前,得物商家客服Tauri版本终于如期上线,基于Tauri迁移带来的收益如下:
整体性能测试相比之前的Electron应用有比较明显的提升:
包体积7M,Electron 80M下降91.25%。
平均内存占用249M Electron 497M下降49.9%。
平均CPU占用百分比20%,Electron 63.5%下降 63.19%。
整体在性能体验上有一个非常显著改善。但是,这里也暴露出使用Tauri的一些问题。
社区活跃度还需要提升
直到2024年的今天,Tauri依然还不是特别完美,目前官方主要精力是放在了2.0的开发上,对于1.x的版本维护显得力不从心,主要原因也是因为官方人少。
比如,Tauri: dev分支上,主要贡献者(> 30 commit)只有4个人;相对于Electron:主要贡献者有10人。
除此之外,Electron实现了对Chromium的高级定制,因此在Electron中,我们可以使用BrowserView这样的功能,相对于Electron来说,Tauri目前所做的仅仅是对Webview的封装,Webview不支持的功能暂时都不行。另外,系统性的API确实少的可怜。如果要实现一些其他的功能,比如自动更新显示进度条等能力,就不得不使用Rust来扩展API。然后Rust语言学习成本是有一点的,所以,也给我们日常开发带来了不少挑战。
Webview2的问题
因为Tauri在Windows系统上比较依托于Webview2作为渲染的容器,虽然Tauri提供了检测本地电脑是否有安装Webview2以及提供联网下载的能力,但是因为Windows电脑千奇百怪,经常会出现未内置Webview2的Windows电脑下载不成功而导致程序无法启动的情况:
对于这种情况,我们虽然可以将Webview2内置到安装包里面,在用户安装的时候进行内置解压安装,但是这样包体积就跟Electron相差不大。
成熟度和稳定性还不够
我们在将得物商家客服迁移到Tauri的过程中,就遇到了非常多的问题,有些问题是Tauri的bug。有些问题是Tauri的feature不够,有的是Rust社区的问题。单纯这一个迁移工作,我们就为Tauri社区共享了7个左右的PR:
在遇到这些问题时,真的特别让人头大,因为社区几乎没有这些问题的答案,需要我们自己去翻Tauri的源码实现,有些是涉及到操作系统底层的一些API,因此我们必须要去看一些操作系统的API介绍和出入参说明,才能更好的理解Tauri的代码实现意图,才能解决我们碰到的这些问题。
另外,Tauri和操作系统系统相关的源码都是基于Rust来编写的,也为我们的排查和解决增加了不少难度。最后一句名言和读者共勉:纸上得来终觉浅,绝知此事要躬行。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.