边做边学 Tauri - 第一部分:简介和结构
介绍
这是通过实践项目学习 Tauri 系列文章的第一篇。但这篇文章也会涉及一些 Rust 的学习。
事实上,我在 2023 年底就决定在 2024 年学习 Rust,所以我开始学习它;但正如经常发生的那样,将你的知识运用到实践项目中会遇到问题,如果你没有正确的想法,这可能会很困难。
幸运的是,我听说了 Tauri。Tauri
是一个工具包,可以让你为任何操作系统构建桌面应用程序,用 Rust 编写核心,并使用几乎任何 Js 框架(或者根本不用)来构建前端。
它似乎非常适合将我的 Web 开发人员知识运用到前端工作,同时训练和提高我全新的后端语言:Rust。
另一个幸运的巧合是,我厌倦了每周发布新闻通讯时必须进行的一些重复步骤。用意大利语 Markdown 编写后,我需要将其转换为 HTML,将其翻译成英文,并将新版本转换为 HTML。在 Brevo 和 Devto 上都做好准备……天哪,我是个开发者,我应该把这些事情自动化!那就开始吧!我搭建了自己的平台,可以自动处理所有这些任务。
因此,在这些文章中,我将指导您完成我所采取的步骤以获得实际结果,目的是帮助您同时提高对 Rust 和 Tauri 的了解,就像这个项目为我所做的那样!
好了,闲话少说!我们开始吧!
第一步
首先,你需要在你的机器上安装 Rust 和 Cargo。如果你还没有安装,可以在这里找到更多关于最佳安装方法的说明。
安装完成后,我们可以通过运行以下命令来初始化我们的项目:
cargo install create-tauri-app --locked # only needed the first time to install create-tauri-app tool
cargo create-tauri-app
一个小向导将引导您挑选您最喜欢的堆栈。
注意:
在本系列文章中,我将使用 Vue 和 TyprScript 作为前端,但正如前文所述,您可以使用任何您喜欢的技术栈作为前端。除了 Tauri 流程理解需要时,我不会过多地关注这部分。
因此,您按照说明进入您的文件夹。
文件和文件夹
启动项目后,我们一如既往地看到创建了一堆文件和文件夹。具体来说,我们将在其中几个文件夹中进行操作:src
,其中包含所有前端代码;src-tauri
,其中包含所有后端 Rust 代码。
该src
文件夹与您在 Web 项目中常见的文件夹非常相似;其中包含组件、资源等等。因此,让我们集中精力查看该src-tauri
文件夹,看看能在其中找到什么。
Cargo.toml
如果您不熟悉 Rust 环境,Cargo.toml 文件包含所有项目信息和依赖项:它非常类似于节点项目的 package.json 文件
Tauri.conf.json
这个文件实际上包含一些很酷的配置项。
首先,它包含一些开发和构建命令,您可以暂时保留它们。然后,您可以找到您的软件包信息,例如productName
项目名称和version
。之后,在tauri
键下,您会找到一些默认定义的项。这实际上很有趣,因为它包含了许多对我们应用有价值的配置。
首先是允许列表 (allowlist),它是 Cargo 等效功能的转换,用于选择是否允许访问某些系统功能,例如文件系统、shell、http 等等。
这是一个以安全性为中心的配置,因为如果本节未明确指定,Tauri 项目就无法访问某些功能。这意味着您可以非常详细地选择应用的功能,以确保其安全。
然后是捆绑包配置,其中包含有关捆绑应用程序的所有相关信息。唯一必需的参数是标识符,该标识符必须是唯一的。除此之外,您还可以指定应用程序图标、构建目标等等。
我们将在此文件中研究的最后一件事是windows
指定有关我们窗口的配置:大小、位置、标题、是否可调整大小等等。
src
文件夹
这是我们应用程序核心部分所在的文件夹。在里面我们会找到一个main.rs
文件,里面已经包含了一些代码。那就让我们开始研究它吧!
main.rs:我们的起点
那么,我们打开 main.rs 文件,开始动手吧!我们遇到了什么?
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
显然它是一个函数,但上面这一行在 Rust 中很常见:它被称为属性,通常可以定义有关其后函数或结构的一些元数据。属性有很多,如果你不熟悉 Rust 或属性,我建议你看一下官方文档。
我们不会在本文中大量使用它们,但在使用 Rust 时了解它是一个很棒的功能(让你了解,你可以直接指定一个函数是一个测试函数,这要归功于它们,这使得在代码中创建测试变得非常容易)。
那么,这个#[tauri::command]
属性是关于什么的?
它指定下面是一个可以从我们的前端调用的函数,直接从 js 调用。我们可以返回给我们的前端任何我们喜欢的类型,在本例中它是一个字符串;唯一的条件是它必须派生出Serde::Serialize
特征。我们将在本系列的后面部分深入探讨这个问题
接下来,在下面几行,你可以找到以下内容:
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
这几行代码是我们应用程序的实际启动器。如果我们想在项目启动时添加一些内容,就需要在这一部分进行操作。
例如,如果我们想要多个窗口、窗口菜单等等,我们可以在主函数中初始化它们。
在本介绍中,我们只需注意一点:.invoke_handler(tauri::generate_handler![greet])
这行代码允许我们定义哪些使用属性的函数#[tauri::command]
可以被前端实际调用。
因此,当我们想要创建一个可由前端调用的新函数时,我们既需要使用该属性,又需要将其添加到generate_handler
数组中。
快速浏览一下前端
到目前为止,我们已经了解了后端。那么前端呢?我们如何调用Rust 函数?
正如您所见,打开src
项目根目录中的文件夹,您将看到 JS 项目的常见结构。
就我而言,这是一个使用 TypeScript 的 Vue 项目。
我们要找的东西实际上就在components
文件夹里,我们可以在那里找到 Greet 组件。
import { ref } from "vue";
import { invoke } from "@tauri-apps/api/tauri";
const greetMsg = ref("");
const name = ref("");
async function greet() {
greetMsg.value = await invoke("greet", { name: name.value })
}
我们可以看到该invoke
方法是从 tauri api 包导入的。invoke函数
接受两个参数,第一个是函数名称,第二个是以 Rust 参数为键的对象。
注意:Rust 指南要求变量和参数使用蛇形命名法,而这个对象的键必须使用驼峰命名法;如果你尝试在这里使用蛇形命名法,会报错。
文档里有写这个吗?是的。
我第一次注意到了吗?当然没有。
随便你。
我们得到的返回invoke
是一个承诺,其结果将正是我们在函数中返回的内容。
运行它
因此,您可以进入项目根目录,使用 安装所有 npm 包,npm install
然后使用 运行示例应用程序npm run tauri dev
。
编译需要一些时间,但之后您将看到我们冒险的起点已启动并运行。
结论
正如前文所述,这是系列的第一部分;我们没有亲自动手,只是获得了一些项目方向和大概的想法。
下次我们将开始构建一些功能,首先调用一些 API 并处理结果!
准备好开启编程之旅了吗?真心希望在下一章中能见到你!
下次再见,祝你
编程愉快 0_1