Tauri 2 零基础入门实战:30 分钟从 0 打出 4.63MB 安装包(附完整代码 + 7 个必踩的坑)

这篇教程的目标很具体:从一台干净的电脑开始,到手里有一个能双击安装的桌面应用,全程约 30 分钟,产物是 4.63 MB 的 Windows 安装包

对比一下同一个功能如果用 Electron 做:安装包起步 150 MB 以上(VS Code 的 Windows 安装包我今天实测是 224 MBContent-Length: 235072944)。

更值得说的是——你基本不用写 Rust。Tauri 2 把「重型逻辑下沉到 Rust」做成了可选选项,前端那套 Vue/React 代码可以原样搬进来。文末我把这套技术栈做出来的成品开源了,安装包体积、功能清单全部可查。


先看清楚:学完这篇你手里会有什么

阶段产出大概耗时
环境准备Rust 工具链 + 系统依赖装好,tauri info 全绿8–15 分钟(首次下载 Rust 最慢)
脚手架一个能 npm run tauri dev 弹出原生窗口的项目1 分钟
打通通信前端按钮 → Rust 函数 → 返回数据;Rust 主动推前端10 分钟
打包src-tauri/target/release/bundle/ 下的 .exe / .msi / .dmg / .deb3–10 分钟(首次编译慢)

不需要的:不需要会 Rust 的所有权模型,不需要学 Qt,不需要重写 UI。


一、Tauri 不是"更轻的 Electron",它是另一个物种

很多介绍把 Tauri 说成"体积小一点的 Electron",这个说法会把你带偏。它俩的差别不在优化,在架构路线

一句话定义

Tauri 是一个把系统自带的 WebView 当作渲染层、把 Rust 编写的原生进程 当作后端、用一套白名单式权限系统把两者粘起来的桌面/移动应用框架。

进程模型:一眼看出本质区别

Electron 的模型 —— 你把浏览器打包进安装包
┌─────────────────── 你的安装包(150MB+)───────────────────┐
│  Chromium(~120MB,每个 App 各带一份)                      │
│  Node.js 运行时(~30MB)                                    │
│  你的前端产物(几百 KB)  ← 你真正写的东西只有这一块          │
└────────────────────────────────────────────────────────────┘

Tauri 的模型 —— 你只发"壳 + 前端产物"
┌── 你的安装包(几 MB)──┐        ┌─── 操作系统提供 ───┐
│  Rust 核心进程(~2-3MB)│ <IPC>  │ Windows: WebView2  │
│  你的前端产物(几百 KB)│        │ macOS:  WKWebView  │
└─────────────────────────┘        │ Linux:  WebKitGTK  │
                                   └────────────────────┘

差别就一句话:Electron 的发包成本花在"带一份 Chromium",Tauri 的成本花在"要验证三种 WebView 引擎"

前者是钱和体积,后者是测试工作量。你怎么选,取决于你更怕哪个。

Tauri 2 相对于 1.x 的四个实质变化

这一条很重要,网上大量中文教程还停留在 Tauri 1.x,命令和配置都对不上:

  1. 权限系统(Capabilities)成为标配。1.x 是配置里写 allowlist,2.x 改成独立的 capabilities/*.json + 插件各自的权限标识,粒度细到单个命令。
  2. 插件化tauri-plugin-* 统一了官方扩展(fs / dialog / updater / sql / store / autostart …),装上就能用,不像 1.x 那样塞进核心。
  3. 支持移动端。iOS / Android 复用同一套前端,tauri ios init / tauri android init
  4. 多 Webview 支持。一个窗口里可以放多个独立 WebView(对做浏览器类、分屏类应用很关键)。

当前版本(写这篇文章时从 crates.io 取的):tauri 稳定版 2.11.5tauri-cli 2.11.4,脚手架 create-tauri-app 4.7.4。注意 crates.io 上还有个 3.0.0-alpha.0,那是预发布,别用


二、环境准备:三张清单,照着装

2.1 系统依赖

平台要装什么
Windows 10/11① Rust 工具链(含 rustup)② Microsoft C++ Build Tools(Visual Studio 生成工具里的"使用 C++ 的桌面开发"工作负载,含 Windows SDK)③ WebView2(Win11 和 Win10 1803+ 已内置,不用管)
macOS 10.15+xcode-select --install + Rust 工具链。没别的了(WKWebView 是系统的)
Linux一行命令搞定(各发行版不同,见下)

Linux(Debian/Ubuntu 系,官方文档给的依赖清单):

sudo apt update
sudo apt install libwebkit2gtk-4.1-dev \
  build-essential \
  curl \
  wget \
  file \
  libxdo-dev \
  libssl-dev \
  libayatana-appindicator3-dev \
  librsvg2-dev

Arch / Fedora / openSUSE / Alpine 的命令在官方 Prerequisites 页有,别照抄 Debian 那行。

2.2 Rust 工具链

Windows 上去 rustup.rs 下载 rustup-init.exe 双击即可,或者:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

国内下载慢怎么办:给 rustup 和 cargo 配国内镜像源(这是合规且最稳的做法,改的是配置里的源地址,不需要任何额外工具):

# 走系统包管理器或镜像站,例如清华 TUNA 的 rustup 镜像
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup
export RUSTUP_UPDATE_ROOT=https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup

cargo 依赖同理,在 ~/.cargo/config.toml 里配 [source.crates-io] replace-with = "<你的镜像名>" 指向国内镜像。

2.3 验证环境(这一步别跳过)

node -v      # 建议 18+(本项目用的是 20 LTS 也能跑)
rustc -V     # 应该是 1.7x 及以上
cargo -V

还有个神器,装完 Tauri CLI 后跑:

npm run tauri info

它会把你的 OS、WebView 版本、Rust 版本、Node 版本、缺失依赖全部列出来,环境问题九成在这一步就能暴露。遇到 error: linker 'link.exe' not found 之类,基本都是 MSVC Build Tools 没装或没选对工作负载,重跑安装器勾上"使用 C++ 的桌面开发"就好。


三、30 秒建项目:目录结构逐行讲清楚

3.1 创建

npm create tauri-app@latest

交互式问答(我的选择,你可以按需换):

✔ Project name · my-tauri-app
✔ Identifier · com.example.myapp        ← 反写域名,打包成安装包的唯一 ID,别乱填
✔ Choose which language to use for your frontend · TypeScript / JavaScript
✔ Choose your package manager · npm
✔ Choose your UI template · Vue           ← React / Svelte / Solid / Angular / Vanilla 都行
✔ Choose your UI flavor · TypeScript

然后:

cd my-tauri-app
npm install
npm run tauri dev

第一次会编译几分钟(Rust 要编几百个 crate),之后增量编译就快了。看到窗口弹出来,环境就通了。

3.2 目录结构(新手最该看的 20 行)

my-tauri-app/
├── package.json              ← 前端依赖 + tauri 脚本入口
├── vite.config.ts            ← 前端构建配置(Tauri 不干涉这块)
├── index.html                ← 前端入口页
├── src/                      ← 前端代码(Vue/React…原样搬进来即可)
│   ├── App.vue
│   └── main.ts
└── src-tauri/                ← ★ 整个"原生外壳"在这里
    ├── Cargo.toml            ← Rust 依赖清单(Rust 的 package.json)
    ├── build.rs              ← 构建脚本,Tauri 自动生成,别动
    ├── tauri.conf.json       ← ★ 应用配置总入口:窗口、打包、插件、CSP
    ├── capabilities/
    │   └── default.json      ← ★ 权限白名单(2.x 的核心安全机制)
    ├── icons/                ← 打包用的图标(用 tauri icon 生成)
    └── src/
        ├── main.rs           ← 进程入口,只调用 lib.rs
        └── lib.rs            ← ★ 你的 Rust 代码主要写这里

记住三个星号文件就够了tauri.conf.json(配置)、capabilities/default.json(权限)、src-tauri/src/lib.rs(后端逻辑)。

3.3 tauri.conf.json 最小可读版

{
  "$schema": "https://schema.tauri.app/config/2",
  "productName": "my-tauri-app",
  "version": "0.1.0",
  "identifier": "com.example.myapp",
  "build": {
    "beforeDevCommand": "npm run dev",
    "devUrl": "http://localhost:3000",
    "beforeBuildCommand": "npm run build",
    "frontendDist": "../dist"
  },
  "app": {
    "windows": [
      {
        "label": "main",
        "title": "我的第一个 Tauri 应用",
        "width": 1200,
        "height": 800,
        "center": true
      }
    ],
    "security": {
      "csp": "default-src 'self'; img-src 'self' asset:; style-src 'self' 'unsafe-inline'; script-src 'self'"
    }
  },
  "bundle": {
    "active": true,
    "targets": "all",
    "icon": ["icons/32x32.png", "icons/128x128.png", "icons/icon.icns", "icons/icon.ico"]
  }
}

两个字段值得单独说:

  • beforeDevCommand / beforeBuildCommand:Tauri 不接管前端构建,它只是"先跑你这个命令,再去加载 devUrlfrontendDist"。所以 Vite / Webpack / 任何构建工具都能用,迁移成本几乎为零。
  • security.csp:默认就是严格模式。别为了省事改成 null,那等于把你最大的安全优势丢掉。

四、核心机制一:前端怎么调 Rust(command + invoke)

这是整个 Tauri 最核心的一套 API,就两个符号:Rust 侧 #[tauri::command],JS 侧 invoke()

4.1 最小可用例子

Rust 侧src-tauri/src/lib.rs):

#[tauri::command]
fn greet(name: &str) -> String {
    format!("你好,{}!这条消息来自 Rust 🦀", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])   // ★ 必须注册,漏了就找不到命令
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

前端侧src/App.vue):

<script setup lang="ts">
import { ref } from 'vue'
import { invoke } from '@tauri-apps/api/core'

const name = ref('World')
const msg = ref('')

async function sayHi() {
  // 第一个参数是命令名(字符串),第二个是参数对象
  msg.value = await invoke<string>('greet', { name: name.value })
}
</script>

<template>
  <input v-model="name" />
  <button @click="sayHi">调用 Rust</button>
  <p>{{ msg }}</p>
</template>

跑起来点按钮,你会看到 Vue 渲染出 Rust 返回的字符串。到这里你就打通了桌面应用最重要的那条链路。

4.2 三个新手必踩的细节

① 参数名自动转换 camelCase → snake_case

JS 里传 { userName: 'x' },Rust 函数签名写成 user_name: String。Tauri 内部会自动转换。反过来你要是不转换,会收到一个很模糊的"参数缺失"错误。

② 复杂结构要有 Deserialize / Serialize

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
struct WatchItem {
    code: String,
    market: String,
}

#[derive(Serialize)]
struct Quote {
    code: String,
    price: f64,
    change_pct: f64,
}

#[tauri::command]
fn add_watch(item: WatchItem) -> Result<Quote, String> {
    if item.code.is_empty() {
        return Err("股票代码不能为空".into());
    }
    // ... 业务逻辑
    Ok(Quote { code: item.code, price: 12.34, change_pct: 1.23 })
}

前端拿到的是原样的对象:

const q = await invoke<Quote>('add_watch', {
  item: { code: '600519', market: 'sh' },
})

③ 错误处理用 Result<T, E>,E 建议是 String

Rust 的 Result<Quote, String> 在 JS 侧会变成一个 rejected promise,所以要用 try/catch

try {
  const q = await invoke<Quote>('add_watch', { item })
} catch (e) {
  // e 就是 Rust 侧 map_err / Err("...") 里的字符串
  console.error('调用失败:', e)
}

这是我认为 Tauri 设计得最舒服的一点:错误不是靠字符串约定,而是语言级别的类型系统强制你处理。

4.3 共享状态:State 和托管状态

桌面应用总有"全局只初始化一次的东西"——数据库连接、行情缓存、配置对象。Tauri 的写法:

use std::sync::Arc;
use tauri::State;

struct Cache {
    count: std::sync::atomic::AtomicU64,
}

#[tauri::command]
fn hit(cache: State<'_, Arc<Cache>>) -> u64 {
    cache.count.fetch_add(1, std::sync::atomic::Ordering::SeqCst) + 1
}

pub fn run() {
    tauri::Builder::default()
        .manage(Arc::new(Cache { count: 0.into() }))   // ★ 注册到应用上下文
        .invoke_handler(tauri::generate_handler![hit])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

关键点:Rust 是无数据竞争的。你这里的 AtomicU64 / Mutex 是编译器强制你加的,不是"记得加"。前端传来的并发调用打到同一个 Rust 状态上,不会出现 Electron 里那种"两个 ipcMain 回调同时改一个对象"的玄学 bug。

4.4 异步命令:别阻塞 UI

只要命令里要做网络请求或磁盘 IO,就加 async

#[tauri::command]
async fn fetch_depth(code: String, market: String) -> Result<Depth, String> {
    // await 一个 HTTP 请求
    let d = reqwest_get_depth(&code, &market).await.map_err(|e| e.to_string())?;
    Ok(d)
}

注意async 命令里如果持有了 State<'_, T>,需要用 State<'_, T> 这种带生命周期的写法;而且不要在 async 里持有 MutexGuard 跨 await 点,否则编译不过(编译器会阻止你写出死锁)。这一点初学时会觉得"Rust 好烦",两次之后你会感谢它。


五、核心机制二:Rust 主动推给前端(事件系统)

invoke 是"前端问、后端答"。但桌面应用里更常见的场景是后端有持续的数据流,前端只负责渲染——行情、日志、进度条、下载速度。

传统 Electron 写法是前端 setInterval 轮询 ipcRenderer.invoke。Tauri 里正确做法是事件推送

Rust 侧推

use tauri::{Emitter, Manager};
use std::time::Duration;

// 在 setup 或某个命令里启动一个后台任务
tauri::Builder::default()
    .setup(|app| {
        let handle = app.handle().clone();
        tauri::async_runtime::spawn(async move {
            loop {
                // ... 取数逻辑
                let payload = serde_json::json!({ "code": "600519", "price": 1700.5 });
                // ★ 广播给所有 webview
                let _ = handle.emit("quote://tick", payload);
                tokio::time::sleep(Duration::from_secs(3)).await;
            }
        });
        Ok(())
    })

前端侧听

import { listen } from '@tauri-apps/api/event'
import { onUnmounted } from 'vue'

const unlisten = await listen<{ code: string; price: number }>(
  'quote://tick',
  (event) => {
    // event.payload 就是 Rust 侧 emit 的对象
    store.update(event.payload)
  }
)

// ★ 一定要清理,否则组件销毁后监听器还在,内存和重复调用都会出问题
onUnmounted(() => unlisten())

一个真实的坑:事件可能比监听器先到

这是我做行情工具时踩到的:Rust 侧在启动阶段立刻 emit,但前端的 Vue 组件挂载、listen 注册完成是有延迟的(尤其首页要做权限校验、拉配置)。结果是前端漏掉了最早的几帧数据,界面上一段时间是空的。

两种解法:

  • 拉推结合:前端 listen 注册成功后再 invoke('start_stream'),让后端在收到指令后才开始推。这是最稳的。
  • 后端留一份最新快照:前端挂载时先 invoke('get_snapshot') 拿当前值,再开始 listen 收增量。

我用的是第一种。这个坑在任何"事件驱动架构"里都存在,只是 Tauri 让你更早碰到它。


六、核心机制三:权限系统(Tauri 最被低估的设计)

这一节是 Tauri 2 和 Electron 在安全模型上最根本的差别,也是我认为最值得学的一块。

6.1 问题是什么

Electron 应用里,渲染进程如果要访问文件系统,通常是通过 preload 暴露一组 API,或者干脆开 nodeIntegration。它的安全边界靠你自己写对。一旦前端出现 XSS(比如渲染了未转义的第三方数据),攻击者拿到的是整个 Node 运行时。

Tauri 的模型是:后端只有被显式授权的命令才对外可见。没授权,前端连"命令名"都不知道。

6.2 capabilities 长什么样

src-tauri/capabilities/default.json

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "主窗口的能力集",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "opener:default",
    "core:window:allow-set-position",
    "core:window:allow-start-dragging"
  ]
}

逐字段解释:

  • windows这套权限只对哪些窗口生效。你可以给主窗口开一堆权限,给托盘小窗一个都不开——这是 Electron 很难优雅做到的。
  • permissions:每个字符串是一条权限,格式是 <插件名>:<动作>core:default 是最小核心集,opener:default 是 opener 插件的默认集。
  • 想用某些命令(比如让窗口可以被拖动、能改坐标),要单独把 core:window:allow-* 列出来

6.3 缺权限的报错长什么样

新手最常见的困惑是这个:

window.set_position not allowed.
Permissions associated with this command: core:window:allow-set-position

报错信息本身就告诉你该加什么权限了。看到这种,去 capabilities/default.jsonpermissions 里把那行加上,重启 dev 即可。这比"Electron 里默默生效或默默失败"友好太多。

6.4 三条实践原则

  1. 从最小开始,按报错加。官方默认模板给的就是 core:default,够用了。别一上来把 fs:defaultshell:default 全打开。
  2. 按窗口分能力。主窗口给业务权限,悬浮窗/托盘窗只给渲染权限。
  3. CSP 不要关tauri.conf.json 里的 security.csp 是最后一道防线,配合权限系统才有意义。

七、核心机制四:插件生态,一行命令装一个能力

Tauri 2 把官方扩展全拆成了独立插件,装起来非常统一:

npm run tauri add opener      # 用系统默认程序打开链接/文件
npm run tauri add autostart   # 开机自启
npm run tauri add updater     # 自动更新
npm run tauri add sql         # SQLite(Rust 侧 sqlx)
npm run tauri add store       # 轻量 KV 持久化
npm run tauri add single-instance  # 单实例

这条命令会自动改三处:package.json(JS 包)、Cargo.toml(Rust crate)、lib.rs(注册插件),并且往 capabilities 里加对应的默认权限。比手动装省掉十次踩坑。

常用插件速查:

插件干什么谁需要
opener打开浏览器链接 / 本地文件几乎所有应用
autostart开机自启工具类、盯盘类
updater应用内自动更新有分发需求的产品
storeKV 配置持久化存用户偏好
sqlSQLite本地数据量大的
single-instance防止开多个实例常驻类
global-shortcut全局快捷键效率工具
window-state记住窗口位置大小体验加分项
logRust 侧日志排查线上问题
notification系统通知提醒类

一个提醒:插件也是权限的一部分。装了 openercapabilities 里没写 opener:default,前端调用一样会报权限错误。装完插件顺手确认一下权限文件。


八、打包:从源码到安装包

8.1 一条命令

npm run tauri build

产物在 src-tauri/target/release/bundle/ 下,按平台自动生成。我这套技术栈做出来的项目,v1.4.7 一次 tauri build 出的全部产物(体积是从 GitHub Release API 读的字节数,最可信):

平台文件名体积
Windows*_x64-setup.exe(NSIS)4.63 MB
Windows*_x64_zh-CN.msi(WiX)6.46 MB
Windows*_x64-portable.zip(免安装)6.38 MB
macOS*_universal.dmg13.06 MB
Linux*.deb8.00 MB
Linux*.rpm8.00 MB
Linux*.AppImage79.26 MB

这里必须诚实说一件事:Linux 的 AppImage 有 79 MB,比 Windows 大了 17 倍。原因是 AppImage 要把 WebKitGTK 相关依赖打进去(Linux 发行版之间 WebKit 版本差异太大,不打包就跑不起来)。所以"Tauri 只有几 MB"这个说法,在 Linux 桌面上是要打折的。 用 deb/rpm 走系统依赖就是 8 MB,代价是要求用户系统装了 WebKitGTK。

8.2 Windows 安装包为什么能这么小

因为 WebView2 是共享的。Win11 和 Win10 1803+ 都内置了 WebView2 Runtime,你的安装包不用带浏览器。对于更老的系统,Tauri 默认的 webviewInstallModedownloadBootstrapper——安装时按需下载一个约 2 MB 的引导器。想要完全离线安装,可以改成 embedBootstrapperofflineInstaller,代价是安装包会变大。

8.3 体积优化:Cargo profile

src-tauri/Cargo.toml 加上官方推荐的 release profile:

[profile.dev]
incremental = true          # 分步编译,增量更快

[profile.release]
codegen-units = 1           # 让 LLVM 做更好的优化
lto = true                  # 链接时优化
opt-level = "s"             # 优先体积(追求速度用 3)
panic = "abort"             # 去掉 panic 展开,体积更小
strip = true                # 剥离调试符号

还有一招(需要 tauri@2.4 及以上):

{ "build": { "removeUnusedCommands": true } }

它会在构建时对比 capabilities 里的 ACL,把前端从未被授权调用的命令从二进制里摘掉,真正做到"不用就不付成本"。

8.4 图标:别自己 P 图

准备一张 1024×1024 的 PNG,然后:

npm run tauri icon path/to/your-icon.png

它会一次性生成 Windows .ico、macOS .icns、各尺寸 PNG 和移动端全套图标,直接进 src-tauri/icons/


九、新手必踩的 7 个坑(收藏这张表)

#症状原因解法
1error: linker 'link.exe' not foundWindows 没装 MSVC C++ Build Tools装 VS 生成工具,勾"使用 C++ 的桌面开发"
2前端调 invoke 报命令不存在忘了在 generate_handler![] 里注册每个命令都要列进 generate_handler!
3前端报 xxx not allowedcapabilities 里没授权按报错提示把权限字符串加进 permissions
4传参报"缺少字段"JS 用 camelCase,Rust 用 snake_case靠 Tauri 自动转换,但结构体字段名要写对,且加 #[derive(Deserialize)]
5首次 tauri build 卡住十几分钟Rust 全量编译几百个 crate正常现象;后续增量秒级。国内配上 crates 镜像会快很多
6换了图标但安装包没变打包缓存 / 图标路径没更新确认 bundle.icon 路径,清 target/release/bundle 重打
7组件销毁后还在处理事件listenunlisten 没调onUnmounted(() => unlisten()),或用 getCurrentWebview().listen 配合自动清理

十、数据口径与证据强度(重要)

按我自己的规矩,数字全部标来源,你自己可以复核:

数据来源 / 取数方式强度
macOS 安装包 13.06 MB、Windows setup 4.63 MB、Linux AppImage 79.26 MBgh release view -R Leaderxin/quant-desktop --json assets.assets[].size 字节数实测可复现
VS Code Windows 安装包 224 MBcurl -sIL https://update.code.visualstudio.com/latest/win32-x64-user/stableContent-Length: 235072944一手来源,可复现
Electron 官方 win32-x64 运行时 150.82 MBGitHub Releases API,electron-v44.3.0-win32-x64.zip = 158,149,320 B一手来源
tauri 稳定版 2.11.5 / tauri-cli 2.11.4 / create-tauri-app 4.7.4crates.io /api/v1/crates/<name>max_stable_version一手来源
Tauri 仓库 star 111,049 / Electron 123,039GitHub API repos/tauri-apps/taurirepos/electron/electron一手来源(star 是动态值,读到时点为准)
Cargo profile 优化项、Linux 依赖清单、removeUnusedCommands 需 2.4+Tauri 官方文档 App Size / Prerequisites / Create a Project官方文档
Tauri CLI 相关命令与配置字段官方文档 + 本项目 tauri.conf.json 实际配置官方文档 + 实测

证据强度说明:本文字节数均为真实读取,非估算,你可以用上面的命令自行复核。"Electron 应用安装包 100–230 MB"这种区间是社区普遍观测值,属于中等强度,仅供量级参考。


十一、我用这套技术栈做了什么(成品 + 实测结果)

上面所有代码和踩坑记录,来自我实际在维护的一个开源项目 QuantDesktop——一个免费开源的 A 股实时看盘桌面应用。

QuantDesktop:实时行情、K 线与自选列表

技术栈和本文完全一致:Tauri 2 + Rust + Vue 3 + TypeScript + Vite。

它的实测数据(都可查):

维度数值
Windows 安装包4.63 MB(NSIS)/ 6.46 MB(MSI)
macOS 通用包13.06 MB
已发布版本数8 个(v1.3.1 → v1.4.7,2026-08 至今)
Rust 侧自定义命令22 个(generate_handler! 里注册,全部走权限白名单)
核心功能实时行情推送、K 线 / 分时图、五档盘口、自选股管理、多数据源容灾切换、系统托盘 + 悬浮行情条、应用内自动更新

它为什么是个好的学习样本:这个项目把本文讲的东西全用上了——#[tauri::command] 的同步/异步两种形态、State 托管共享缓存、emit 事件推动情、capabilities 按窗口分配权限、独立小窗口(alwaysOnTop 的桌面行情条)、GitHub Releases 零成本自动更新。想看真实工程里怎么组织,比看 hello world 划算得多。

项目地址:https://github.com/Leaderxin/quant-desktop

完全免费开源,Windows / macOS / Linux 都有包,装了就能用。软件本身对 A 股投资者有直接用处,对想学 Tauri 的人则是一个能跑的参考实现。

这个系列的前两篇(建议一起看,链路才完整):


十二、一句话总结

Tauri 2 = 系统 WebView 做渲染 + Rust 做后端 + 白名单权限做边界,前端代码零改造,安装包小一个数量级;代价是三种 WebView 引擎要验、Rust 编译比 Node 慢、你要接受一门新语言在项目里存在。

如果你只是想"用前端技术写个桌面小工具",今天就可以用 npm create tauri-app@latest 试一次,30 分钟能拿到安装包,这是最便宜的验证方式。

最后留个问题给评论区:你手的桌面工具,愿意为了几 MB 的安装包去引入 Rust 吗? 或者反过来——你踩过 Electron 的哪个坑让你想换掉它?说说你的场景,我帮你算算换过去的成本。


本文所有命令与版本号基于 Tauri 2 稳定版实测,Ubuntu 系统依赖清单与官方文档一致;文中提及的链接与数据可通过文中给出的命令复现。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值