跨端框架Tauri的使用

Tauri是什么

Tauri 是一个开源框架,用于构建轻量级、高性能的桌面应用程序和移动端。它是使用 Web 技术(如 HTML、CSS 和 JavaScript)来创建用户界面,同时利用 Rust 语言提供的api功能。Tauri 的目标是提供一种更高效、更安全的方式来开发跨平台的桌面应用程序以及移动端软件程序。

Tauri 可以理解为多语言和通用工具包,具有很强的可组合性,允许工程师制作各种各样的应用程序。它用于使用 Rust 工具和 Web 视图中呈现的 HTML 的组合为台式计算机构建应用程序。使用 Tauri 构建的应用程序可以附带任意数量的可选 JS API 和 Rust API,以便 Web 视图可以通过消息传递来控制系统。开发人员可以使用自己的功能扩展默认 API,并轻松桥接 Webview 和基于 Rust 的后端。

Tauri 与框架无关。这意味着你可以将它与你选择的任何前端库一起使用——比如 Vue、React等或者纯Rust前端代码。你可以只使用 Tauri 提供的 JavaScript API 来构建你的整个应用程序。这样一来,您不仅可以轻松构建新应用,还可以将已构建的 Web 应用的代码库转换为本机桌面应用,而无需更改原始代码。

Tauri本身也可以用纯粹的Rust代码来写,比如使用Rust支持最好的WASM去写整个跨端项目也是可以。

Tauri VS Electron

提到前端跨端尤其是桌面端技术,就不得不提Electron技术。在桌面端方面,Electron是前辈,我们来对比一下,两者各自的优势。

Electron 的优势:

  • 生态系统和社区:Electron 有一个更成熟和广泛的生态系统,拥有大量可用的库和工具。它的社区也更大,这意味着更多的资源、文档和支持。
  • 成熟度和稳定性:Electron 已经被广泛使用多年,许多流行应用(如 VS Code、Slack)都是基于 Electron 构建的。因此,它在稳定性和功能性方面经过了更多的测试和验证。
  • 开发便利性:由于 Electron 使用 Node.js,JavaScript 开发者可能会发现使用 Electron 更加方便,特别是对于那些已经熟悉 Node.js 生态系统的人。
  • 功能丰富:Electron 由于其成熟度,通常提供更多的功能和集成选项。

Tauri 的优势:

  • 性能和资源占用:Tauri 应用通常比 Electron 应用更轻量,占用更少的内存和磁盘空间。这是因为 Tauri 使用 Rust 作为api调用和系统交互,它比 Electron 中的 Node.js 更高效。
  • 安全性:Tauri 提供更高的安全性,因为它限制了应用程序对系统资源的访问,而 Electron 通常给予更多的访问权限。
  • 打包大小:Tauri 打包的应用程序体积通常比 Electron 小很多,这对于希望减小应用体积的开发者来说是一个重要优势。
  • 能效:Tauri 应用程序通常比 Electron 更节能,尤其是在移动设备或低功耗设备上。

如何快速启动Tauri

以下是如何快速在一个React、Vue等前端项目里,加入Tauri框架,并且快速启动。

前提保证你的本地开发环境的Rust环境是正确的。首先在前端根目录中执行命令npm install --save-dev @tauri-apps/cli,然后在文件package.json中添加

"scripts": {
  "tauri": "tauri"
}

然后在根目录中继续执行命令npm run tauri init,这时候会在终端里询问交互几个问题(比如项目title和一些命令等),然后根目录中会生成出一个src-tauri的目录,我们进入这个src-tauri目录,需要在文件tauri.conf.json更改一些属性,比如你需要之后build的话需要更改identifier属性,其他重要的属性比如

"build": {
    "beforeBuildCommand": "pnpm run build",
    "beforeDevCommand": "pnpm run start",
    "devPath": "http://localhost:4321",
    "distDir": "../dist"
  },

这其中,beforeBuildCommandbeforeDevCommand,是对应项目本身的build和dev命令,devPath是对应前端启动的网络路径,distDir对应前端项目build之后的包路径。

这以上的属性配置好之后,就可以在根目录中执行运行或者打包命令:

  • npm run tauri dev
  • npm run tauri build

Tauri框架的一些技巧

设置桌面端软件的菜单

创建菜单

src-tauri目录的main.rs文件里,可以使用rust代码去增加桌面端软件的菜单功能(在Tauri 2.0中,menu的代码大部分功能都重构或更改了),这里就是添加一些简单的桌面端软件的。hide、show、quit等能力。

let app_menu = Submenu::new(
    name,
    Menu::with_items([
      #[cfg(target_os = "macos")]
        MenuItem::About(name.into(), AboutMetadata::default()).into(),
      MenuItem::Hide.into(),
      MenuItem::HideOthers.into(),
      MenuItem::ShowAll.into(),
      MenuItem::Quit.into(),
    ]),
);

// 主函数使用菜单
fn main() {
  tauri::Builder::default()
    .menu(menu)
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

监听快捷键按钮

这里代码是能在桌面端监听键盘的快捷键输入的,比如后退功能。

let view_menu = Submenu::new(
    "View",
    Menu::new()
      .add_item(CustomMenuItem::new("go_back", "Go Back").accelerator("CmdOrCtrl+[")),
);

// 主函数使用监听事件
fn main() {
  tauri::Builder::default()
    .menu(menu::init())
    .on_menu_event(menu::menu_handler)
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

使用指令

Tauri的指令功能,可以让rust代码可以跟JavaScript环境交互。这里用rust代码,申明了一个greet方法,能够在主函数中注册之后,在Js的代码中自由调用。大家也可以把一些ui之外的,逻辑或者复杂计算的场景交给Rust,以提升整个软件的运行效率。

#[tauri::command]
fn greet(name: &str) -> String {
   format!("Hello, {}!", name)
}

// 主函数注册指令
fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}
import { invoke } from '@tauri-apps/api'

function App() {
  invoke('greet', { name: 'World' })
  .then((response) => console.log(response))

  return ()
}

也可以使用withGlobalTauri特性,可以在tauri.conf.json文件里配置一下

"build": {
  "beforeBuildCommand": "npm run build",
  "beforeDevCommand": "npm run dev",
  "devPath": "http://localhost:3000",
  "distDir": "../build",
  "withGlobalTauri": true
}

然后就可以在js环境里自由调用:

const { invoke } = window.__TAURI__.tauri

function App() {
  invoke('greet', { name: 'World' })
  .then((response) => console.log(response))

  return ()
}

Tauri是如何工作的呢

在 Tauri 框架中,根据操作系统的不同(如 Windows 和 macOS),它会调用各自平台的原生能力来提供功能和性能。根据各自平台的一些webview能力来渲染的UI。

在 Electron 中,前端是与应用程序捆绑在一起的 Chromium 网页视图。这意味着,无论使用何种操作系统,始终可以确定应用使用的 Node.js 和 Chromium 版本。这带来了主要的好处,但也有一些缺点。 最大的好处是易于开发和测试,知道哪些功能可用,如果某些东西可以在 macOS 上运行,它很可能也可以在 Windows 和 Linux 上运行,并且渲染一致。但是,缺点是,由于捆绑了所有这些二进制文件,应用程序大小会大得多。

Tauri 采取了截然不同的方法。没有将 Chromium 与所需要的应用捆绑在一起,而是使用操作系统的默认 Web 视图。这意味着,比如在 macOS 上,应用将使用 WebKit(Safari 的引擎),在 Windows 上,它将使用 WebView2(基于 Chromium),在 Linux 上,它将使用 WebKitGTK(与 Safari 的相同)。最终这使得Tauri的应用结果是一个非常小的程序。

Tauri mobile

去年晚些时候即将到来的 2.0 稳定版本,Android 和 iOS 都将成为 Tauri 生态系统的一等公民。一些移动端的插件和系统的相互调用将登上tauri舞台。

这里简单讲一下Tauri2.0的一些依赖和用法。

Tauri mobile 所需要的2.0依赖

Cargo.toml文件所需要的2.0版本依赖:

[build-dependencies]
tauri-build = { version = "2.0.0-alpha.6", features = [] }

[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "^2.0.0-alpha", features = [] }

[features]
custom-protocol = [ "tauri/custom-protocol" ]

[lib]
crate-type = ["staticlib", "cdylib", "rlib"]

package.json所需要添加的依赖:

"devDependencies": {
    "@tauri-apps/cli": "^2.0.0-alpha"
}

Tauri mobile的一些命令

在项目根目录内可以使用命令,快速生成android或者ios的代码目录,如npm run tauri android init或者npm run tauri ios init,项目的src-tauri目录就产生了gen目录,其中就是移动端的自动生成的代码,我们除非签名或者其他配置才需要动他。然后想要运行或者打包安卓或ios的话,就使用命令:

  • npm run tauri android dev or npm run tauri ios dev
  • npm run tauri android build or npm run tauri ios build

其他