比起 Electron,Tauri 打包后的安装包体积是真的小。
跨平台开发
最近使用跨平台开发框架写了一个软件,在此记录一下。
说起跨平台开发,我的理解是这样的:
- 多依赖浏览器环境运行
- 多使用前端语言进行开发
- 只需一次编码,但不同平台可能需要做兼容处理
- 能够在 macOS、Windows、Linux 或者 Android、iOS 上运行
跨平台框架选择
需求
女朋友让我帮忙写个文件上传的软件,先描述一下软件的功能需求:
- 支持上传文件到七牛云
- 上传后自动复制文件链接
- 支持查看上传历史
- 图片视频等资源可以直接预览
其实之前用 Java 写过一个「七牛云上传工具」,也能用,但是依赖 Java 环境,而且界面比较丑,也没有上传历史记录。
可能有人会说, PicGo 之类的软件不就可以满足需求么,干嘛还自己造轮子。
其实是这样的,类似 PicGo 的软件只能上传图片,而且安装包太大。我需要的是一个能上传文件,并且安装包小的轻量级软件,所以正好借这个机会自己来实现。
经过我的考虑,我对框架选择提出了以下要求:
- 使用 Vue 开发
- 能够打包成客户端
- 客户端支持 macOS 和 Windows
这么看下来肯定是跨平台开发了,那选择哪个框架呢?
Electron VS Tauri
本来是想用「Electron」的,但是说真的,只看官方文档没看出来怎么使用 Vue 入门。GitHub 虽然有一个「electron-vue」项目,但已经太久没维护了,连项目初始化都报错。
无奈只好放弃使用 Electron,一番搜索后找到了「Tauri」,跟 Electron 类似,也支持在 Mac、Win、Linux 上运行,并且最新的 2.0(Alpha)还支持在 Android 和 iOS 上运行。不过这不是最主要的,最主要的是以下两点:
- 官方脚手架初始化项目支持 Vite,也就是说可以无缝使用 Vue 进行开发。
- 打包后的安装包体积小,众所周知 Electron 打包会包含一个浏览器,而 Tauri 并不会。
Tauri 入门
特点
不同于 Electron 嵌入 Chromium 的做法,Tauri 利用 macOS 上的 WebKit、Windows 上的 WebView2 和 Linux 上的 WebKitGTK,以此来避免嵌入浏览器的笨重包袱,使得安装包能够做到很小的体积。
但这也可能导致兼容性问题,例如低版本的 Windows 系统不包含 Webview2,需要设置 Webview2 的安装配置;不同系统对混合内容等问题的兼容性不同。
环境准备
这里只介绍一下 macOS 下的准备工作,其他系统准备工作请参考「Prerequisites」。
- CLang 和 macOS 开发依赖项
xcode-select --install
- Rust
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
初始化
我这里以官方 Vite 初始化项目为例,更多初始化请参考官方文档「Quick Start」。
npm create tauri-app@latest
选择适合自己的配置项。
❯ npm create tauri-app@latest
Need to install the following packages:
create-tauri-app@3.3.5
Ok to proceed? (y) y
✔ Project name · tauri-app
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm)
✔ Choose your package manager · npm
✔ Choose your UI template · Vue - (https://vuejs.org)
✔ Choose your UI flavor · JavaScript
然后安装依赖:
npm install
接下来预览项目:
npm run tauri dev
控制台会显示预览链接,点击即可通过浏览器进行预览。同时会启动一个客户端的预览界面,如下图所示(第一次运行需要下载资源,可能会比较慢,耐心等待即可)。
如果只想通过浏览器进行预览,执行 npm run dev
即可。
项目目录
可以看到项目的目录跟 Vue 基本是一致的,多出的 src-tauri
目录便是 Tarui 特有的。
┌── public
│ ├── tauri.svg
│ └── vite.svg
├── src
│ ├── assets
│ ├── components
│ ├── App.vue
│ ├── main.js
│ └── styles.css
├── src-tauri
│ ├── icons
│ ├── src
│ ├── target
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ └── tauri.conf.json
├── README.md
├── index.html
├── package-lock.json
├── package.json
└── vite.config.js
- icons:各个平台的图标,可查看「Icons」进行详细了解
- src:Rust 代码,Tauri 可以在前端调用 Rust 代码,可查看「Calling Rust from the frontend」进行详细了解
- target:打包目录
- Cargo.lock & Cargo.toml & build.rs:Rust 相关
- tauri.conf.json:Tauri 的配置文件,可查看「Configuration」进行详细了解
开发
Tauri 虽然支持 Rust,但是完全不会 Rust 也没影响,像我就完全没接触过 Rust。
就跟正常开发 Vue 项目一样,安装依赖包,引入依赖,写页面、组件即可。
我这里使用了 View UI Plus 和七牛云 JavaScript SDK,按照各自的文档进入引入和使用即可。
额外说一句,七牛云 JavaScript SDK 需要先获取到上传凭证才能上传,具体可参考「上传凭证」文档。
API
Tauri 提供了一些列 API 使得开发更加容易,这里以「clipboard」为例,简单说下 Tauri API 的使用。
首先,需要在 tauri.conf.json
里设置 clipboard
节点,参考下面的代码:
{
"tauri": {
"allowlist": {
"clipboard": {
"all": true, // enable all Clipboard APIs
"writeText": true,
"readText": true
}
}
}
}
如果仅需设置剪贴板内容,无需读取,则只设置 writeText
为 true
即可。
在代码中使用 writeText
:
import { writeText } from '@tauri-apps/api/clipboard';
await writeText('Tauri is awesome!');
更多关于 Tauri API 使用可查看「@tauri-apps/api」。
生成图标
Tauri 支持 macOS、Windows 和 Linux 三个平台,为了简化 icon 的制作,Tauri 提供了专门生成 icons 的命令。
npm run tauri icon 图片路径
原始图片最好是 1024x1024 的 png 图片,执行命令后即可生成各平台下的 icon。
可查看「Icons」进行详细了解。
打包
npm run tauri build
使用 Mac 进行打包,那么打出来的就是 dmg 包,只能 macOS 使用。如果想实现跨平台打包,可以参考「Cross-Platform Compilation」。其他平台打包可参考「Building」。
界面展示
展示一下我使用 Tauri + Vue + View UI Plus 实现的界面。
Tauri 踩坑
在使用 Tauri 过程中踩了一些坑,也记录下来。
文件拖拽
拖拽上传需要在配置文件里将 tauri.conf.json 里 windows
节点下的 fileDropEnabled
设置为 false
,否则会跟 Vue 组件的拖拽冲突。
"windows": [
{
"fullscreen": false,
"resizable": false,
"title": "文件上传工具",
"width": 800,
"height": 450,
"fileDropEnabled": false,
}
]
并且为了防止将图片拖拽到非上传区域导致页面显示图片的情况,需要阻止页面 drop
和 dragover
的默认监听:
window.addEventListener("drop", (e) => e.preventDefault(), false);
window.addEventListener("dragover", (e) => e.preventDefault(), false);
右键菜单
软件最后要打包成客户端,不需要浏览器的右键菜单,可参考下方代码,禁用右键菜单:
window.addEventListener("contextmenu", (e) => e.preventDefault(), false);
复制文本
View UI Plus 带有 $Copy 复制到剪贴板
的全局方法,但在 Tauri 框架里有可能会失败。
解决办法就是调用 Tauri 的 writeText。
混合内容
Tauri 打包后的应用其实是 https://
的一个网页应用,如果页面中包含了 http://
的资源那就是混合内容,控制台会报错,图片等资源会显示不出来;如果资源也是 https://
那就不是混合内容,也不会报错。
由于做的是图片预览,所以我的解决办法是使用 Tauri 的 os type 判断,在 Windows 下直接打开一个 WebviewWindow 来加载图片 url,显示是没问题的。
但是在 macOS 上打开 WebviewWindow 加载图片 url 图片无法显示,控制台会提示 Failed to load resource: The resource could not be loaded because the App Transport Security policy requires the http://xxx.xxx.xxx use of a secure connection
,暂时只能提示手动去浏览器访问预览。
这里要注意,在开发模式下混合内容是不会报错的,显示也都正常,但是打包之后就会报错并且显示异常。
Windows 相关
Windows 下执行脚本可能提示「无法加载文件 xxx,因为在此系统上禁止运行脚本」,这是因为 PowerShell 执行策略导致的。
我的做法是更改 PowerShell 执行策略为 Bypass
:
Set-ExecutionPolicy -ExecutionPolicy Bypass
但是这个策略是有风险的,如果你的主力系统是 Windows,建议参考「about_Execution_Policies」选择合适的执行策略和执行策略范围。
打包的时候遇到 Error failed to bundle project: error running light.exe: error running light.exe
的问题,设置 budle
节点下的 windows
的 wix
语言为 zh-CN
:
"bundle": {
"windows": {
"wix": {
"language": "zh-CN"
}
}
},
在 Windows 上 Tauri 依赖的是微软的 WebView2,Windows 10 1803 及以后的版本和 Windows 11 都是自带 WebView2 的,但如果是低版本的系统,在安装时会自动下载和安装 WebView2,但是安装过程没有提示,感觉像是卡住了,体验不是很好。如果想自行配置 Webview2 的安装选项,可以参考 「Webview2 Installation Options」。
窗口居中闪烁
默认的窗口位置并不是居中的,可以设置 windows
节点的 cneter
为 true
:
"windows": [
{
"fullscreen": false,
"resizable": false,
"title": "文件上传工具",
"width": 800,
"height": 450,
"fileDropEnabled": false,
"center": true
}
]
但是这个居中有点问题,窗口还是会从默认位置出现,然后再跳到居中的位置,能看到跳的过程,体验不是很好。
总结
总体来说使用 Tauri 开发跨平台应该还是不错的,与 Vue 生态完美配合,安装包的体积也可以做到很小。
但也不可避免的有一些问题,例如 Windows 下 Webview2 的安装问题、不同系统下混合内容的兼容性问题等。
我觉得如果是个人项目可以用 Tauri 搞一下,但如果是商业化的项目需要提前评估,防止入坑后需要过多的时间来填坑。
更多关于 Tauri 的使用参考请查看「Tauri 官方文档」。
本文由 掘墓人 创作,采用 CC BY-NC-ND 4.0 DEED
,转载或翻译请注明出处。
最后编辑时间为: 2023年04月19日