mcpField
U
understanding-tauri-architecture

understanding-tauri-architecture

github.com/dchuk开发36322 次安装40 周前更新
代码仓库

关于 understanding-tauri-architecture

面向 Tauri 开发者的桌面应用架构参考文档,介绍 Rust 核心、WebView 前端、IPC 通信及分层安全模型。

主要功能

  1. 01核心与外壳架构
  2. 02Rust 后端职责
  3. 03原生 WebView 集成
  4. 04命令与事件 IPC
  5. 05能力与权限模型

适用场景

  1. 01理解 Tauri 应用分层
  2. 02设计前后端通信方式
  3. 03检查 Tauri 权限边界

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dchuk/claude-code-tauri-skills --skill understanding-tauri-architecture

安装后在 Claude Code 中输入/understanding-tauri-architecture确认已加载。

详细介绍

Tauri 架构

Tauri 是一套多语言工具包,用于构建桌面应用。它将 Rust 后端与在原生 WebView 中渲染的 HTML/CSS/JavaScript 相结合。本文介绍基本的架构概念。

架构概览

+------------------------------------------------------------------+
|                        TAURI APPLICATION                         |
+------------------------------------------------------------------+
|                                                                  |
|  +---------------------------+    +---------------------------+  |
|  |      FRONTEND (Shell)     |    |     BACKEND (Core)        |  |
|  |---------------------------|    |---------------------------|  |
|  |                           |    |                           |  |
|  |  HTML / CSS / JavaScript  |    |        Rust Code          |  |
|  |  (or any web framework)   |    |    (tauri crate + app)    |  |
|  |                           |    |                           |  |
|  |  - React, Vue, Svelte,    |    |  - System access          |  |
|  |    Solid, etc.            |    |  - File operations        |  |
|  |  - Standard web APIs      |    |  - Native features        |  |
|  |  - Tauri JS API           |    |  - Plugin system          |  |
|  |                           |    |                           |  |
|  +-------------+-------------+    +-------------+-------------+  |
|                |                                |                 |
|                |       IPC (Message Passing)    |                 |
|                +<------------------------------->+                |
|                |     Commands & Events          |                 |
|                                                                  |
|  +------------------------------------------------------------+  |
|  |                    WEBVIEW (TAO + WRY)                     |  |
|  |------------------------------------------------------------|  |
|  |  - Platform-native webview (not bundled)                   |  |
|  |  - Windows: WebView2 (Edge/Chromium)                       |  |
|  |  - macOS: WKWebView (Safari/WebKit)                        |  |
|  |  - Linux: WebKitGTK                                        |  |
|  +------------------------------------------------------------+  |
|                                                                  |
+------------------------------------------------------------------+
                                |
                                v
+------------------------------------------------------------------+
|                     OPERATING SYSTEM                             |
|  - Windows, macOS, Linux, iOS, Android                          |
+------------------------------------------------------------------+

核心与外壳设计

Tauri 采用核心-外壳架构,将应用拆分为两个不同的层:

核心(Rust 后端)

核心是基于 Rust 的后端,负责处理所有系统级操作:

  • 系统访问:文件系统、网络、进程
  • 原生功能:通知、对话框、剪贴板
  • 安全保障:权限验证、能力检查
  • 插件管理:通过插件扩展功能
  • 应用生命周期:窗口管理、更新、配置

核心绝不会向前端开放直接的系统访问权限。所有交互都通过经过验证的 IPC 通道进行。

外壳(前端)

外壳是在 WebView 中渲染的用户界面层:

  • Web 技术:HTML、CSS、JavaScript/TypeScript
  • 框架无关:支持 React、Vue、Svelte、Solid 或原生 JS
  • 沙箱执行:在 WebView 的安全沙箱中运行
  • Tauri API 访问:通过 @tauri-apps/api 调用后端

生态系统核心组件

tauri Crate

核心协调组件,负责:

  • 在编译时读取 tauri.conf.json
  • 管理注入 WebView 的脚本
  • 提供系统交互 API
  • 处理应用更新
  • 集成运行时、宏和实用工具
tauri-runtime

Tauri 与底层 WebView 库之间的衔接层。它抽象了特定于平台的 WebView 交互,使 Tauri 的其余部分能够保持平台无关。

tauri-macros 和 tauri-codegen

生成编译时代码,用于:

  • 命令处理器(#[tauri::command])
  • 上下文和配置解析
  • 资源嵌入与压缩
TAO(窗口管理)

跨平台窗口创建库(从 Winit 分叉而来):

  • 创建和管理应用窗口
  • 处理菜单栏和系统托盘
  • 支持 Windows、macOS、Linux、iOS、Android
WRY(WebView 渲染)

跨平台 WebView 渲染库:

  • 抽象各平台的 WebView 实现
  • 处理 WebView 与原生代码之间的通信
  • 管理 JavaScript 求值和事件桥接

WebView 集成

Tauri 使用操作系统的原生 WebView,而不是捆绑浏览器引擎:

+-------------------+---------------------------+
|     Platform      |        WebView Engine     |
+-------------------+---------------------------+
| Windows           | WebView2 (Edge/Chromium)  |
| macOS             | WKWebView (Safari/WebKit) |
| Linux             | WebKitGTK                 |
| iOS               | WKWebView                 |
| Android           | Android WebView           |
+-------------------+---------------------------+
原生 WebView 的优势
  1. 二进制文件更小:无需捆绑浏览器引擎(约 600KB,而非约 150MB)
  2. 安全性:操作系统供应商修补 WebView 漏洞的速度,比应用开发者重新构建应用更快
  3. 性能:与操作系统原生集成
  4. 一致性:用户看到熟悉的渲染行为
注意事项
  • 不同平台之间的渲染略有差异
  • 功能是否可用取决于操作系统 WebView 版本
  • 测试应覆盖所有目标平台

进程间通信(IPC)

Tauri 通过异步消息传递实现前端与后端之间的通信。这比共享内存更安全,因为核心可以拒绝恶意请求。

IPC 流程图
+------------------+                      +------------------+
|    Frontend      |                      |   Rust Backend   |
|   (JavaScript)   |                      |     (Core)       |
+--------+---------+                      +--------+---------+
         |                                         |
         |  1. invoke('command', {args})           |
         +---------------------------------------->|
         |                                         |
         |     [Request serialized as JSON-RPC]    |
         |                                         |
         |                    2. Validate request  |
         |                    3. Check permissions |
         |                    4. Execute command   |
         |                                         |
         |  5. Return Result<T, E>                 |
         |<----------------------------------------+
         |                                         |
         |     [Response serialized as JSON]       |
         |                                         |
两种 IPC 原语
命令(请求-响应)

类型安全的前端到后端函数调用:

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

// Register in builder
tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet])
// JavaScript frontend
import { invoke } from '@tauri-apps/api/core';

const greeting = await invoke('greet', { name: 'World' });
console.log(greeting); // "Hello, World!"

主要特征:

  • 基于 JSON-RPC 协议
  • 所有参数都必须可序列化为 JSON
  • 返回一个 Promise,成功时会以结果完成
  • 支持异步 Rust 函数
  • 可以访问应用状态、窗口句柄等
事件(即发即弃)

双向异步通知:

// Frontend: emit event
import { emit } from '@tauri-apps/api/event';
emit('user-action', { action: 'clicked' });

// Frontend: listen for events
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('download-progress', (event) => {
    console.log(event.payload);
});
// Backend: listen for events
use tauri::Listener;

app.listen("user-action", |event| {
    println!("User action: {}", event.payload());
});

// Backend: emit events
app.emit("download-progress", 50)?;

主要特征:

  • 无返回值(单向)
  • 前端和后端都可以发送或监听
  • 最适合用于生命周期事件和状态变化
  • 不会在编译时进行类型检查

安全模型概览

Tauri 采用多层安全机制,保护应用和用户的系统。

信任边界模型
+------------------------------------------------------------------+
|                     UNTRUSTED ZONE                               |
|  +------------------------------------------------------------+  |
|  |                    WebView Frontend                        |  |
|  |  - JavaScript code (potentially from remote sources)       |  |
|  |  - User input                                              |  |
|  |  - Third-party libraries                                   |  |
|  +------------------------------------------------------------+  |
+------------------------------------------------------------------+
                              |
                    [TRUST BOUNDARY]
                    [IPC Layer validates all requests]
                              |
+------------------------------------------------------------------+
|                      TRUSTED ZONE                                |
|  +------------------------------------------------------------+  |
|  |                    Rust Backend                            |  |
|  |  - Your Rust code                                          |  |
|  |  - Tauri core                                              |  |
|  |  - System access (gated by permissions)                    |  |
|  +------------------------------------------------------------+  |
+------------------------------------------------------------------+
安全层
  1. WebView 沙箱:前端代码在 WebView 的安全沙箱中运行
  2. IPC 验证:验证所有跨越信任边界的消息
  3. Capabilities:定义每个窗口可访问的权限
  4. 权限:对允许执行的操作进行细粒度控制
  5. 作用域:限制命令行为(例如,将文件访问限制在特定目录中)
  6. CSP:内容安全策略限制前端代码可执行的操作
Capabilities 系统

Capabilities 控制授予特定窗口的权限:

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "main-window-capability",
  "description": "Permissions for the main application window",
  "windows": ["main"],
  "permissions": [
    "core:path:default",
    "core:window:allow-set-title",
    "fs:read-files",
    "fs:scope-app-data"
  ]
}

Capabilities 在 src-tauri/capabilities/ 中以 JSON 或 TOML 文件定义。

权限结构
Capability
    |
    +-- windows: ["main", "settings"]  // Which windows
    |
    +-- permissions:                    // What's allowed
            |
            +-- "plugin:action"         // Allow specific action
            +-- "plugin:scope-xxx"      // Scope restrictions
默认安全态势
  • 默认拒绝:必须明确允许命令
  • 不允许远程访问:默认情况下,只有打包的代码才能访问 Tauri API
  • 窗口隔离:每个窗口都有自己的 capabilities 集合
  • 编译时检查:许多安全配置会在构建时验证

Rust 后端结构

典型的 Tauri 后端采用以下结构:

src-tauri/
+-- Cargo.toml              # Rust dependencies
+-- tauri.conf.json         # Tauri configuration
+-- capabilities/           # Permission definitions
|   +-- main.json
+-- src/
    +-- main.rs             # Entry point (desktop)
    +-- lib.rs              # Core app logic
    +-- commands/           # Command modules
    |   +-- mod.rs
    |   +-- file_ops.rs
    +-- state.rs            # App state management
入口点模式
// src-tauri/src/lib.rs
mod commands;

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_shell::init())
        .invoke_handler(tauri::generate_handler![
            commands::greet,
            commands::read_file,
        ])
        .manage(AppState::default())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
命令模式
// Basic command
#[tauri::command]
fn simple_command() -> String {
    "Hello".into()
}

// With arguments (camelCase from JS, snake_case in Rust)
#[tauri::command]
fn with_args(user_name: String, age: u32) -> String {
    format!("{} is {} years old", user_name, age)
}

// With error handling
#[tauri::command]
fn fallible() -> Result<String, String> {
    Ok("Success".into())
}

// Async command
#[tauri::command]
async fn async_command() -> Result<String, String> {
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok("Done".into())
}

// Accessing app state
#[tauri::command]
fn with_state(state: tauri::State<'_, AppState>) -> String {
    state.get_value()
}

// Accessing window
#[tauri::command]
fn with_window(window: tauri::WebviewWindow) -> String {
    window.label().to_string()
}

不捆绑运行时

Tauri 不会附带运行时。最终二进制文件:

  • 将 Rust 代码直接编译为本机机器码
  • 将前端资源嵌入二进制文件
  • 使用系统原生 WebView
  • 生成小巧、快速的可执行文件

与捆绑了 JavaScript 的 Electron 应用相比,这使得对 Tauri 应用进行逆向工程并非易事。

总结

组件角色
核心(Rust)系统访问、安全、业务逻辑
外壳(前端)UI 渲染、用户交互
WebView(TAO+WRY)平台原生渲染桥接层
IPC(命令/事件)在各层之间安全地传递消息
Capabilities控制每个窗口的权限

该架构优先考虑:

  1. 安全性:多层保护、信任边界
  2. 性能:原生代码、不捆绑运行时
  3. 体积:尽可能缩小二进制文件
  4. 灵活性:支持任何前端框架,提供强大的 Rust 后端

评论

支持 Markdown