普通视图

发现新文章,点击刷新页面。
昨天 — 2026年2月22日首页

Next.js + Tauri 2 用 Static Export 把 React 元框架装进桌面/移动端

作者 HelloReader
2026年2月22日 15:03

1. 适配清单 Checklist

  • 开启静态导出:output: 'export'(Tauri 不支持 SSR 那种“必须有服务端”的方案)。 (Tauri)
  • tauri.conf.json 里把 frontendDist 指到 ../out(Next 静态导出目录)。 (Tauri)
  • 如果你用了 next/image,必须处理图片优化:静态导出下默认的图片优化 API 不可用,最简单就是 images.unoptimized = true。 (Tauri)
  • 开发态资源路径要能解析:按官方建议加 assetPrefix,让 dev server 正确解析静态资源(尤其在非 localhost/移动端调试时)。 (Tauri)

2. Tauri 配置:src-tauri/tauri.conf.json

这段的意义是:tauri dev 先跑 Next dev server,再让 WebView 加载 devUrltauri build 先跑 Next build(生成 out),再把 out 打包进应用。Tauri CLI 正是按这些字段工作的。 (Tauri)

{
  "build": {
    "beforeDevCommand": "npm run dev",
    "beforeBuildCommand": "npm run build",
    "devUrl": "http://localhost:3000",
    "frontendDist": "../out"
  }
}

(Tauri)

提示:frontendDist 是相对 src-tauri/ 的路径,所以 Next 项目在根目录时通常就是 ../out

3. Next.js 配置:next.config.mjs

这份配置解决三件大事:

  1. 强制静态导出 output: 'export'
  2. next/image 走静态导出时禁用默认优化(否则直接报错)
  3. 开发态设置 assetPrefix,避免资源解析错误(文档建议)
const isProd = process.env.NODE_ENV === 'production';
const internalHost = process.env.TAURI_DEV_HOST || 'localhost';

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    unoptimized: true,
  },
  assetPrefix: isProd ? undefined : `http://${internalHost}:3000`,
};

export default nextConfig;

(Tauri)

补充理解一下 images.unoptimized
静态导出下,Next 默认的 Image Optimization API(按需优化)不可用,所以必须禁用或换方案。官方错误说明写得很明确。 (nextjs.org)

4. package.json scripts:确保 Tauri 能“按脚本驱动”前端

你给的 scripts 很标准,Tauri CLI 会调用你在 beforeDevCommand/beforeBuildCommand 里写的命令,所以这里保证能跑就行:

"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start",
  "lint": "next lint",
  "tauri": "tauri"
}

(Tauri)

5. 运行与打包:你只需要记住两条命令

  • 开发:

    • cargo tauri dev(会先执行 npm run dev,再加载 http://localhost:3000) (Tauri)
  • 构建:

    • cargo tauri build(会先执行 npm run build,把静态导出生成到 out/,再打包) (Tauri)

Next 的静态导出产物就是 out/,构建后你会看到 out/index.htmlout/404.html 等文件结构。 (nextjs.org)

6. 你需要接受的“静态导出”边界

把 Next 变成静态站点后,这些能力要重新规划(否则你会在 build 时报错或运行时缺功能):

  • 不依赖服务端运行时:SSR、需要 Node 运行时的 API Routes、中间件等都要迁移到独立后端服务(保持“客户端 ↔ API”的标准模式)。 (nextjs.org)
  • 动态路由要可静态化:要么在构建期生成,要么改成纯客户端拉取数据再渲染(这和 Tauri 的模型更贴)。 (nextjs.org)

7. 常见坑与排查(很实用)

7.1 打包后白屏

优先按顺序查这三项:

  • out/ 是否真的生成(执行 npm run build 后是否有 out/index.html)。 (nextjs.org)
  • tauri.conf.jsonfrontendDist 是否正确指向 ../out。 (Tauri)
  • 资源路径是否被你自定义了 basePath/assetPrefix 导致找不到 JS/CSS(打开 DevTools 看 Network 404)。

7.2 next/image 报错:Image Optimization 不兼容导出

这是经典报错场景,直接按文档处理:images.unoptimized: true 或换图片策略。 (nextjs.org)

7.3 开发态热更新不工作,和 assetPrefix 相关

社区里确实有人反馈:某些组合下 assetPrefix 会影响 hot reload 表现。你如果遇到“编译提示更新但页面不刷新”,可以把它当作已知问题来对待:

  • 先尝试升级到更新版本的 Tauri/Next
  • 或临时注释 assetPrefix 验证是否是它引起
  • 若必须保留资源解析能力,考虑把 dev server host 配置到可直连的内网地址并调整 devUrl(移动端场景更常见) (GitHub)

Leptos + Tauri 2 前端配置Trunk + SSG + 移动端热重载一次打通(Leptos 0.6 口径)

作者 HelloReader
2026年2月22日 14:58

1. 三条 Checklist:每一条都对应一个真实的坑

1.1 用 SSG(别走 SSR)

Tauri 的工作方式更像“静态站点宿主”:你给它一份静态资源目录(HTML/CSS/JS/WASM),它在 WebView 里加载并运行。官方明确:Tauri 不官方支持基于服务器的方案(SSR) ,因此要用 SSG/SPA/MPA 这类静态路线。 (Tauri)

这对 Leptos 意味着:在 Tauri 里通常跑的是 WASM 前端(客户端渲染),而不是把 Leptos 的服务端渲染端也一起塞进去。

1.2 serve.ws_protocol = "ws":移动端热重载的关键开关

在移动端开发时(Android/iOS 真机或模拟器),热重载 websocket 更容易因为协议/网络环境出现连接问题。官方建议在 Trunk 里显式设置:

  • ws_protocol = "ws"

确保热重载 websocket 能正常连上。 (Tauri)

1.3 开启 withGlobalTauri:让 window.__TAURI__ 可用,WASM 才好“抓”到 Tauri API

Leptos(WASM)要调用 Tauri API,最常见的桥接方式之一就是通过浏览器全局对象拿到 window.__TAURI__,再用 wasm-bindgen 或 JS interop 访问。官方要求在 Tauri 配置里打开:

  • app.withGlobalTauri = true

这样 window.__TAURI__ 才会被注入。 (Tauri)

2. 示例配置 1:src-tauri/tauri.conf.json(告诉 Tauri:怎么跑 Trunk、资源在哪)

把下面这段放到 src-tauri/tauri.conf.json(或合并进你的配置):

{
  "build": {
    "beforeDevCommand": "trunk serve",
    "devUrl": "http://localhost:1420",
    "beforeBuildCommand": "trunk build",
    "frontendDist": "../dist"
  },
  "app": {
    "withGlobalTauri": true
  }
}

这段配置分别解决什么:

  • beforeDevCommand: trunk serve
    你执行 cargo tauri dev 时,Tauri 会先帮你启动 Trunk 的开发服务器。
  • devUrl: http://localhost:1420
    Tauri 开发模式加载的页面地址就是这个(Trunk 默认端口常用 1420)。
  • beforeBuildCommand: trunk build
    你执行 cargo tauri build 时,先把 Leptos 编译成静态资源。
  • frontendDist: ../dist
    Trunk build 的输出目录(注意这是相对 src-tauri/ 的路径,所以通常是 ../dist)。
  • withGlobalTauri: true
    注入 window.__TAURI__,方便 WASM/vanilla JS 访问。 (Tauri)

3. 示例配置 2:Trunk.toml(Trunk 怎么 build、怎么 serve、怎么热重载)

在项目根目录创建/修改 Trunk.toml

[build]
target = "./index.html"

[watch]
ignore = ["./src-tauri"]

[serve]
port = 1420
open = false
ws_protocol = "ws"

这里的重点:

  • [build].target = "./index.html"
    指定构建入口页面(Trunk 以它为入口组织资源与 wasm 输出)。
  • [watch].ignore = ["./src-tauri"]
    避免 Trunk 监听 Rust/Tauri 工程目录导致无意义的重编译或文件句柄压力(特别是 Windows/大型工程时会明显)。
  • [serve].ws_protocol = "ws"
    移动端热重载稳定性的关键项。 (Tauri)

4. 开发与构建:你实际只需要记住两条命令

开发(桌面):

cargo tauri dev

发布构建:

cargo tauri build

因为你已经在 tauri.conf.json 里配置了 beforeDevCommand/beforeBuildCommand,所以通常不需要你手动先跑 trunk serve/build

5. WASM 侧怎么用 Tauri API(思路)

开启 withGlobalTauri 后,window.__TAURI__ 会存在。官方 JS API 文档也明确:使用全局对象需要这个开关。 (Tauri)

在 Leptos/WASM 里常见做法是:

  • wasm-bindgen / web-syswindow 上取 __TAURI__
  • 再调用你需要的模块(例如 event、window、path、plugin 等)

如果你更偏工程化,也可以在前端用一层 thin wrapper:把需要的 Tauri 能力封装成少量 JS 函数,再让 WASM 调这些函数,边界更清晰、类型更可控。

6. 常见问题速查

  • 启动后白屏,但浏览器访问 http://localhost:1420 正常
    优先检查 tauri.conf.json 里的 devUrl 端口是否与 Trunk 一致,以及是否启动了 trunk serve(看终端输出)。
  • 热重载在移动端不工作
    先确认 Trunk.tomlws_protocol = "ws" 已设置。 (Tauri)
  • WASM 里拿不到 window.__TAURI__
    检查 app.withGlobalTauri 是否为 true,并确认你是在 Tauri 窗口里运行(不是纯浏览器环境)。 (Tauri)

Tauri 前端配置把任何前端框架“正确地”接进 Tauri(含 Vite/Next/Nuxt/Qwik/SvelteKit/Leptos/Trunk)

作者 HelloReader
2026年2月21日 19:02

1. 配置清单:先把底层规则记住

把下面三条当作 Tauri 前端接入的硬规则:

  1. 只走静态路线:SSG / SPA / MPA
    Tauri 不原生支持基于服务端的方案(例如 SSR)。(Tauri)
  2. 移动端真机开发必须有“可被设备访问”的 dev server
    需要让 dev server 绑定到你的内网 IP(或按 Tauri CLI 提供的 host),否则 iOS/Android 真机加载不到页面。(Tauri)
  3. 保持标准的 Client ↔ API 模式
    不要把 SSR 那种“前端渲染与 API 混在一起”的混合模式搬进 Tauri(因为 Tauri 本身不是 Node runtime)。(Tauri)

2. Tauri 侧关键配置位:你最常改的是 build 这四个字段

无论你用什么前端,最终基本都要把这几项在 src-tauri/tauri.conf.json 配好:

  • build.devUrl:开发模式加载哪个 dev server 地址
  • build.frontendDist:打包时把哪个目录当作静态资源目录(dist/out/build 等)
  • build.beforeDevCommand:跑 tauri dev 前先执行什么(通常是 npm/pnpm/yarn dev
  • build.beforeBuildCommand:跑 tauri build 前先执行什么(通常是 npm/pnpm/yarn build/generate

官方在 Vite/Next/Nuxt/SvelteKit/Trunk 等指南里都是这个套路。(Tauri)

一个非常典型的(以 Vite 为例):

{
  "build": {
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm build",
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist"
  }
}

(Tauri)

3. 框架推荐配置

3.1 Vite(官方最推荐的 JS 方案)

官方明确:大多数 SPA 框架(React/Vue/Svelte/Solid)推荐用 Vite。(Tauri)

Tauri 配置(重点是 devUrl、frontendDist、两个 before 命令):(Tauri)

{
  "build": {
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm build",
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist"
  }
}

Vite 配置(移动端真机关键:吃 TAURI_DEV_HOST;并忽略 watching src-tauri;HMR 在真机时走 ws):(Tauri)

import { defineConfig } from 'vite';
const host = process.env.TAURI_DEV_HOST;

export default defineConfig({
  clearScreen: false,
  server: {
    port: 5173,
    strictPort: true,
    host: host || false,
    hmr: host
      ? { protocol: 'ws', host, port: 1421 }
      : undefined,
    watch: {
      ignored: ['**/src-tauri/**'],
    },
  },
  envPrefix: ['VITE_', 'TAURI_ENV_*'],
  build: {
    target: process.env.TAURI_ENV_PLATFORM == 'windows' ? 'chrome105' : 'safari13',
    minify: !process.env.TAURI_ENV_DEBUG ? 'esbuild' : false,
    sourcemap: !!process.env.TAURI_ENV_DEBUG,
  },
});

3.2 Next.js(必须静态导出)

核心结论就一句:Next.js 要用静态导出 output: 'export',并把 out/ 作为 frontendDist。(Tauri)

Tauri 配置:

{
  "build": {
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm build",
    "devUrl": "http://localhost:3000",
    "frontendDist": "../out"
  }
}

(Tauri)

Next 配置(两个很关键的坑位:images.unoptimized、开发态 assetPrefix):(Tauri)

const isProd = process.env.NODE_ENV === 'production';
const internalHost = process.env.TAURI_DEV_HOST || 'localhost';

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: { unoptimized: true },
  assetPrefix: isProd ? undefined : `http://${internalHost}:3000`,
};

export default nextConfig;

3.3 Nuxt(SSG:关闭 SSR + generate)

Nuxt 指南同样强调:设置 ssr: false 走 SSG,并用 nuxi build/generate 产物接给 Tauri。(Tauri)

Tauri 配置(build 用 generate,dist 用 ../dist):(Tauri)

{
  "build": {
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm generate",
    "devUrl": "http://localhost:3000",
    "frontendDist": "../dist"
  }
}

Nuxt 配置里对移动端真机/开发体验做了几处“非常工程化”的增强:

  • devServer.host: '0' 让 dev server 可被其他设备发现
  • vite.envPrefixTAURI_ 环境变量也暴露给前端
  • ignore: ['**/src-tauri/**'] 避免 watch 导致文件句柄过多等问题(Tauri)
export default defineNuxtConfig({
  ssr: false,
  devServer: { host: '0' },
  vite: {
    clearScreen: false,
    envPrefix: ['VITE_', 'TAURI_'],
    server: { strictPort: true },
  },
  ignore: ['**/src-tauri/**'],
});

3.4 Qwik(用 Static Adapter 做 SSG)

Qwik 这类偏 SSR 的框架接 Tauri,核心就是:走 SSG(Static adapter),产物目录用 dist/。(Tauri)

Tauri 配置示例(dist + devUrl 5173):(Tauri)

{
  "build": {
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist",
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm build"
  }
}

3.5 SvelteKit(static adapter + 关闭 SSR;prerender 要谨慎)

SvelteKit 官方指南点得很清楚:用 adapter-static 走 SSG/SPA,并把 build/ 作为 frontendDist。(Tauri)

更重要的是:如果你启用了 prerender,构建阶段的 load 函数拿不到 Tauri API;因此更推荐 SPA(不 prerender),让 load 只在 WebView 里执行。(Tauri)

Tauri 配置:

{
  "build": {
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm build",
    "devUrl": "http://localhost:5173",
    "frontendDist": "../build"
  }
}

(Tauri)

SvelteKit 配置(fallback 到 index.html,配合 SPA 路由):(Tauri)

import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const config = {
  preprocess: vitePreprocess(),
  kit: {
    adapter: adapter({ fallback: 'index.html' }),
  },
};

export default config;

并在根布局关闭 SSR:(Tauri)

export const ssr = false;

3.6 Rust 前端(Leptos / Trunk):WASM 工程的两个关键点

Leptos 与 Trunk 的指南里,除了“走 SSG”之外,有两个移动端相关的关键配置:

  • serve.ws_protocol = "ws":确保热更新 websocket 在移动端连接正常
  • withGlobalTauri: true:把 Tauri API 挂到 window.__TAURI__,便于 wasm-bindgen 引入/调用(Tauri)

Leptos(Trunk)示例:(Tauri)

src-tauri/tauri.conf.json

{
  "build": {
    "beforeDevCommand": "trunk serve",
    "devUrl": "http://localhost:1420",
    "beforeBuildCommand": "trunk build",
    "frontendDist": "../dist"
  },
  "app": {
    "withGlobalTauri": true
  }
}

Trunk.toml

[watch]
ignore = ["./src-tauri"]

[serve]
port = 1420
open = false
ws_protocol = "ws"

(Tauri)

4. 移动端真机开发:别硬写 0.0.0.0,优先用 TAURI_DEV_HOST

Tauri 在移动端开发时会通过 TAURI_DEV_HOST 告诉你“应该监听哪个地址”,尤其是 iOS 真机存在更安全的设备地址/隧道地址选择流程。(Tauri)

结论是:

  • 你的 dev server host 要能读取 process.env.TAURI_DEV_HOST
  • HMR websocket 也要按 host 调整(Vite 官方示例已给出)(Tauri)

如果你是用 create-tauri-app 创建的项目,官方也说明:移动端所需的 dev server 配置通常已经帮你配好了。(Tauri)

5. 常见“白屏/资源 404”排坑清单

这些坑我建议你在团队 wiki 里直接当“发布前检查”:

  • 资源路径必须在打包后仍可解析
    很多白屏本质是“静态资源路径错了”,尤其你给 Vite/框架配置了自定义 base path 时,dev 正常、build 后 WebView 找不到 js/css(看起来像 MIME 错/404)。(GitHub)
  • 元框架在 dev 模式下可能需要显式配置 asset 前缀
    Next.js 的 assetPrefix 就是为了让 dev server 下资源解析正确(尤其移动端/非 localhost 情况)。(Tauri)
  • SPA 路由要有 fallback
    SvelteKit adapter-static 的 fallback: 'index.html' 就是典型做法,否则刷新深层路由可能直接 404。(Tauri)

6. 调试体验提醒:Tauri API 只能在 App 窗口里用

一旦你开始调用 Tauri API,你的前端页面就不能“直接用系统浏览器打开”来完全复现了,因为这些 API 只在 Tauri WebView 容器里生效。(Tauri)

如果你特别依赖浏览器 DevTools 的工作流,官方建议用 tauri-invoke-http 把调用桥接成 HTTP 服务来调试。(Tauri)

Tauri 项目结构前端壳 + Rust 内核,怎么协作、怎么构建、怎么扩展

作者 HelloReader
2026年2月21日 18:55

1. 顶层(前端工程):就是一个普通的 Web 项目

Tauri 的项目结构非常“工程化”:通常由两部分组成

  • 可选的 JavaScript/前端工程(负责 UI,最终产出静态资源)
  • 必须的 Rust 工程(在 src-tauri/,负责窗口、系统能力、打包分发、安全边界)

一个典型目录长这样(你贴的结构非常标准):

.
├── package.json
├── index.html
├── src/
│   ├── main.js
├── src-tauri/
│   ├── Cargo.toml
│   ├── Cargo.lock
│   ├── build.rs
│   ├── tauri.conf.json
│   ├── src/
│   │   ├── main.rs
│   │   └── lib.rs
│   ├── icons/
│   │   ├── icon.png
│   │   ├── icon.icns
│   │   └── icon.ico
│   └── capabilities/
│       └── default.json

顶层的 package.json / index.html / src/main.js 和你做一个静态站点或 SPA 没本质区别。你可以用 Vite、Webpack、Next(需适配静态导出)、SvelteKit 等,只要最终能产出静态资源给 Tauri 加载即可。

核心心智模型:

  • 你在开发模式下跑的是 dev server(热更新、调试体验好)
  • 你在构建时要先把前端编译成静态文件(dist 等),再由 Rust 侧打包进应用

所以前端这部分可以自由替换,Tauri 不绑架框架。

2. src-tauri(Rust 工程):这是 Tauri 的“应用外壳 + 能力层”

src-tauri/ 是一个标准 Cargo 项目,只是比普通 Rust 项目多了几类 Tauri 专用文件夹/配置文件。

2.1 tauri.conf.json:Tauri 的总控配置中心

它是最核心的配置文件,典型会包含:

  • 应用 identifier(包名/唯一标识)
  • 窗口标题、窗口行为
  • dev server URL(开发模式加载哪个地址)
  • 构建时静态资源目录
  • 打包配置(安装包类型、签名、图标路径、权限等)

同时,它还是 Tauri CLI 定位 Rust 工程的“标记文件”。CLI 本质上就是先找到 tauri.conf.json,再按配置去启动前端、编译 Rust、打开窗口。

你在项目里最常改动的地方之一就是它。

2.2 capabilities/:安全模型的“许可清单”(命令 allowlist 的关键落点)

这块非常重要,但很多人刚上手会忽略。

一句话:你在 JS 里想调用 Rust 命令(invoke),必须在 capability 文件里允许它。
所以 capabilities/default.json 本质上就是“你的应用允许暴露哪些能力给前端”。

这套机制的价值:

  • 把“前端能做什么”变成显式声明,而不是默认全开
  • 更适合做企业级的权限治理与审计
  • 也让你在插件/命令越来越多时不至于失控

工程建议:

  • 命令按模块分组,不要一股脑全塞 default
  • 对敏感能力(文件系统、执行外部命令、系统信息、网络访问等)单独 capability,方便环境隔离(dev/production、内部版/外部版)

2.3 icons/:应用图标的默认输出与引用目录

通常你会用 tauri icon 之类的命令从一张源图生成多平台图标,输出到 src-tauri/icons/,然后在 tauri.conf.json > bundle > icon 里引用。

建议:

  • 源图尽量用高分辨率正方形(例如 1024×1024 PNG)
  • 图标生成后别手动改一堆尺寸文件,重新生成更可控

2.4 build.rs:接入 Tauri 构建系统的“挂钩”

build.rs 一般会调用 tauri_build::build(),用于:

  • 让 Cargo 在构建时执行 Tauri 的一些构建步骤
  • 参与资源打包/配置生成等流程

你多数时候不需要改它,除非你做很深的构建定制。

2.5 src/lib.rs:你真正该写 Rust 业务逻辑的地方(尤其是移动端)

这里是很多人第一次看到会疑惑的点:为什么不把逻辑写在 main.rs

原因是移动端构建方式不同:

  • 移动端会把你的应用编译成 library,由平台框架(iOS/Android)加载
  • 因此需要一个可复用的入口函数,放在 lib.rs 更合理
  • 你会看到类似 #[cfg_attr(mobile, tauri::mobile_entry_point)] 的标记,用于移动端入口

实践结论很明确:

  • 业务命令(commands)、插件初始化、状态管理等,优先写在 lib.rs
  • 让桌面与移动共用同一套初始化逻辑,减少分叉

2.6 src/main.rs:桌面端入口,尽量别改

通常 main.rs 只做一件事:调用 app_lib::run()(或者你的库名对应的 run)。
文档也强调了:为了让桌面端复用移动端同一入口,main.rs 保持简单,别动它,改 lib.rs

这里的 app_lib 对应 Cargo.toml 里的 [lib.name],也就是你的库 crate 名。

3. Tauri 的构建流程:像“静态站点托管器”一样工作

把 Tauri 想成一个“带系统能力的静态站点宿主”会特别好理解:

开发模式(dev):

  • 启动前端 dev server(如 Vite 5173)
  • Tauri 窗口加载 dev server URL
  • 你改前端代码热更新;你改 Rust 代码触发重编译/重启

构建模式(build/bundle):

  1. 先把前端编译成静态文件(dist)
  2. 再编译 Rust 工程
  3. Rust 把静态资源打包进最终应用(并按配置输出安装包/可执行文件)

所以前端这边你要做的事情,和“发布一个静态网站”高度一致:构建产物、资源路径、路由模式(history/hash)这些依旧是关键点。

4. 如果你只想写 Rust,不要前端怎么办

可以,Tauri 也支持“纯 Rust UI/前端生态”的路线(例如 Yew/Leptos/Sycamore),甚至你可以把顶层 JS 工程完全删掉:

  • 直接把 src-tauri/ 当成仓库根目录
  • 或把它作为 Rust workspace 的一个 member

这时你的项目就是纯 Cargo 结构,Tauri 仍然负责窗口与 WebView,但 UI 的生成方式由 Rust 侧前端方案决定。

5. 工程落地小建议:让结构更“可维护”

如果你准备做中大型应用,我建议你从一开始就把边界划清:

  • 前端:只负责 UI 与状态,不直接接触敏感能力
  • Rust:用 commands 暴露最小能力面,所有权限控制、输入校验、文件路径规范化都放 Rust
  • capabilities:把“能调用什么”当成发布治理点,代码评审时重点看它有没有被滥开
昨天以前首页

做 IM 客户端,选 Tauri 还是 Qt一篇把坑讲清楚的选型与架构指南

作者 HelloReader
2026年2月20日 12:12

1、先给结论:IM 默认更倾向 Tauri 2,但有 3 类场景更该选 Qt

默认推荐:Tauri 2(文字/图片/文件为主的 IM)

原因很直接:IM 的 UI 以信息密集型为主(会话列表、消息流、搜索、设置、管理页),Web 技术栈迭代效率高;同时 Tauri 以系统 WebView 渲染 + Rust 后端二进制的形态来构建跨平台应用。(GitHub)
更关键的是,Tauri 2 提供了 capabilities/permissions,把“前端能调用哪些本地能力”做成可声明、可收敛的授权边界,IM 这种高风险输入面(富文本、链接、图片、文件、插件)非常吃这一点。(Tauri)

明显更该选 Qt 的 3 类 IM

  1. 音视频通话/会议/屏幕共享是核心卖点
    WebView + WebRTC 能做,但平台差异与边界更敏感。比如 iOS 侧,WKWebView 的 getUserMedia 从 iOS 14.3 开始支持,从而让 WebRTC 在 App 内 WebView 跑起来成为可能,但你仍然需要严肃评估权限弹窗、设备枚举、前后台、回声消除等细节差异。(Apple Developer)
    Qt 的多媒体模块则提供跨平台音视频、摄像头/麦克风、屏幕或窗口采集等能力,做深度音视频链路通常更“原生”。(Qt 文檔)
  2. 你要求跨平台 UI/输入/渲染高度一致,且交互很重
    Qt Quick/QML 天生为复杂交互、动画、模型视图与自绘效果服务。(Qt 文檔)
  3. 你需要明确的 LTS 与长期维护窗口(典型企业级、终端侧 IM)
    Qt 6.8 起 LTS 维护周期提升到 5 年(商业用户),对“要活很久”的客户端非常关键。(Qt)

2、把 IM 拆成“3 层 12 件事”,你就知道该怎么选

无论你选哪个框架,IM 都建议拆成三层:UI 层、核心层、系统层。框架选择会影响每一层“你要自己解决多少”。

A. UI 层(高频迭代)

  • 会话列表/消息流(虚拟列表、富文本、消息状态)
  • 搜索(本地索引 + 服务端索引)
  • 群管理/联系人/设置/多窗口

Tauri 更顺:直接复用 Web 组件体系。
Qt 更稳:一致性更强,尤其复杂交互。

B. 核心层(稳定性与正确性)

  • 长连接(心跳、重连、退避、网络切换)
  • 消息可靠性(至少一次/恰好一次语义、去重、顺序、回执)
  • 离线存储(会话、消息、索引、媒体缓存)
  • 加密(端到端、密钥管理、设备绑定)
  • 大文件/断点续传/多路上传下载
  • 可观测性(日志、崩溃、埋点、性能)

这里 Tauri 的 Rust 后端Qt 的 C++ 核心都能胜任,差别在于团队能力栈与生态依赖。

C. 系统层(“像一个真正的桌面软件”)

  • 系统托盘/快捷键/开机自启
  • 通知(点击跳转到具体会话)
  • 文件系统权限、拖拽、剪贴板、截图
  • 自动更新与签名发布

Tauri 的亮点是:系统层能力建议显式授权到窗口/WebView 上(capabilities),默认更收敛。(Tauri)
Qt 的亮点是:更传统的原生客户端工程方式,能力边界主要靠你自己的工程规范治理。

3、Tauri 2 做 IM:一套“可落地”的参考架构

3.1 架构形态

  • 前端(Web) :会话列表、消息渲染、设置页
  • 本地核心(Rust) :连接管理、消息队列、加密、SQLite、索引、文件传输调度
  • IPC(前后端桥) :只暴露必要命令,并用 capabilities/permissions 做最小授权

Tauri 的基本架构就是“Rust 后端 + WebView UI + 消息传递”。(Tauri)

3.2 为什么 capabilities 对 IM 特别重要

IM 天然会展示“外部输入内容”(对方发来的富文本、链接、图片、文件、可能还有小程序/插件),安全面非常大。Tauri 的 capabilities/permissions 用来约束“哪些窗口能调用哪些命令/权限”,可以把风险窗口(比如预览窗口、外链窗口)做成低权限甚至零权限。(Tauri)

一个典型策略(思路,不是唯一做法):

  • 主窗口:允许网络、数据库、通知、文件下载(受限目录)
  • 外链/预览窗口:只允许打开链接,不允许文件系统与敏感命令
  • 登录窗口:只允许 OAuth 流程相关命令

3.3 Tauri IM 的关键坑位

  1. WebView 差异:字体、输入法、拖拽、媒体能力、通知表现会在各平台不一致(这是系统 WebView 模型带来的结构性成本)。
  2. 权限配置复杂度:capabilities/permissions 一开始会觉得麻烦,但对 IM 这种安全敏感应用,后期会“越用越值”。(Tauri)
  3. 音视频:能做,但你必须把“平台兼容性测试矩阵”前置,尤其 iOS WKWebView 的 getUserMedia/WebRTC 边界要做专门验证。(Apple Developer)

4、Qt 做 IM:一套“工业级客户端”的参考架构

4.1 UI 选 Widgets 还是 QML?

  • Widgets:传统桌面控件体系,适合偏工具型 IM(企业内部、工位端)
  • Qt Quick/QML:现代 UI(动画、模型视图、自绘效果),更适合体验要求高、消息卡片复杂、需要高一致性的 IM。Qt Quick/QML 的能力边界很清晰:动画、模型/视图、粒子/Shader 等都在标准库里。(Qt 文檔)

4.2 音视频/屏幕共享更好“贴近原生”

Qt Multimedia 提供音视频播放、摄像头/麦克风、录制以及屏幕/窗口采集等能力(模块化提供 QML 类型与 C++ 类)。(Qt 文檔)
如果你的 IM 未来要走“会议、共享、录制、虚拟背景”这类路线,Qt 这边的工程组织往往更顺。

4.3 Qt 的关键坑位

  1. 许可证策略必须前置:Qt LTS 与商业支持很香,但你必须把许可证与分发合规先算清楚(建议拉法务/合规一起做)。
  2. 工程栈门槛:C++/QML 工程化、跨平台构建与部署、性能调优,需要团队有对应能力或预留学习成本。
  3. 包体与依赖:Qt 模块选得多,发布体积通常会涨,但换来的是一致性与能力上限。

5、IM 选型的“POC 验证清单”(建议 7~14 天内完成)

你不用靠争论,靠 POC 的数据就能拍板。建议按下面清单做两套最小原型(Tauri/Qt 各一):

5.1 文字 IM 必测(两者都要)

  • 10 万条消息本地库:冷启动加载、滚动流畅度、搜索耗时
  • 图片/文件:断点续传、失败重试、并发下载、磁盘占用策略
  • 通知:点击通知定位到会话/消息
  • 多窗口:主窗口 + 图片预览 + 外链窗口,窗口间状态同步
  • 崩溃恢复:重启后未发完消息恢复、草稿恢复
  • 日志与诊断:关键链路埋点(连接、收发、解密、落库、渲染)

5.2 音视频 IM 必测(如果你要做)

  • 摄像头/麦克风权限:首次授权、拒绝后的引导、系统设置跳转
  • 前后台切换:通话是否掉线、音频路由是否异常
  • 屏幕共享:窗口枚举、共享过程中性能与稳定性
  • 弱网:抖动、丢包、切网(Wi-Fi/4G)下体验

如果你打算用 WebView 走 WebRTC,尤其 iOS,需要把 WKWebView 的 getUserMedia/WebRTC 行为单列出来测(从 iOS 14.3 开始支持,但细节仍需验证)。(Apple Developer)

6、最后给你一条“决策树”,直接落锤

  • 你的 IM 核心是文字/图片/文件/通知/托盘,团队 Web 更强,希望包体小、迭代快、权限可控
    Tauri 2(再用 capabilities 把风险窗口做低权限)(GitHub)
  • 你的 IM 把 音视频/会议/屏幕共享当核心卖点,或你必须 跨平台体验高度一致,或你需要 LTS 长期维护
    Qt(优先 Qt Quick/QML) ,并把 Qt Multimedia 与 LTS 策略纳入规划(Qt 文檔)

Tauri 2 创建项目全流程create-tauri-app 一键脚手架 + Tauri CLI 手动接入

作者 HelloReader
2026年2月20日 11:55

1. 你应该选哪条路

路线 A:create-tauri-app(推荐新项目)

适合:

  • 你要从零开始
  • 想最快跑起来一个可用的 Tauri 工程
  • 想用官方维护的模板(稳定、省心)

优势:

  • 交互式选择项目名、包管理器、框架模板
  • 会自动提示你系统缺哪些依赖
  • 产出结构规整,适合团队协作

路线 B:Manual Setup(Tauri CLI 初始化到现有项目)

适合:

  • 你已经有一个前端项目(Vite/Next/Nuxt/SvelteKit 等)
  • 你希望前端工程保持原样,只“加一层 Tauri 外壳”
  • 你想完全掌控 dev server、build 命令和资源目录

优势:

  • 对现有工程侵入性小
  • 适配各种前端脚手架与 monorepo

2. create-tauri-app:一键创建项目

2.1 支持哪些官方模板

create-tauri-app 目前内置了这些模板(官方维护):

  • Vanilla(纯 HTML/CSS/JS,不依赖框架)
  • Vue、Svelte、React、SolidJS、Angular、Preact
  • Yew、Leptos、Sycamore(Rust 前端生态)
    另外也可以从 Awesome Tauri 找社区模板,或者自己扩展模板。

2.2 运行脚手架命令

在你想创建项目的目录里执行(Linux/macOS 推荐 Bash,Windows 推荐 PowerShell):

sh <(curl https://create.tauri.app/sh)

然后跟着提示一路选下去即可。

2.3 交互式选项怎么选才不踩坑

你会看到几类关键选择:

① 项目名与 Identifier(包名)

  • Project name:工程目录名与默认显示名
  • Identifier:类似 com.company.app 的唯一标识(移动端更敏感,建议提前按公司域名规划)

示例提示类似:

  • ? Project name (tauri-app) ›
  • ? Identifier (com.tauri-app.app) ›

建议:

  • 团队/产品线统一命名规则:com.company.productcom.company.department.product
  • Identifier 一旦发版,后期迁移成本高(尤其移动端),别随便填

② 前端语言生态(这一步很关键)

create-tauri-app 会让你先选“前端开发语言/生态”:

  • Rust(cargo)
  • TypeScript / JavaScript(pnpm/yarn/npm/bun)
  • .NET(dotnet,Blazor)

怎么选:

  • 绝大多数团队:选 TypeScript/JavaScript(配 React/Vue/Svelte 等)
  • 想全 Rust:选 Rust(配 Yew/Leptos/Sycamore)
  • .NET 团队:选 Blazor

③ 包管理器(pnpm/yarn/npm/bun)

如果你选 TS/JS,会再问包管理器:

pnpm / yarn / npm / bun

建议:

  • 新项目、单体应用:pnpm 很稳(依赖管理干净、安装快)
  • 你团队已有统一:跟随团队标准最重要

④ UI Template 与 Flavor

TS/JS 会让你选 UI Template(Vanilla/Vue/Svelte/React/Solid/Angular/Preact),再选 TypeScript 或 JavaScript。

建议起步组合(最稳、最不绕):

  • UI Template:Vanilla
  • UI Flavor:TypeScript
    原因很简单:先把 Tauri 心智模型跑通,再决定框架也不迟。

2.4 启动开发服务器(跑起来)

脚手架完成后,进入目录并安装/启动。文档示例给的是 cargo 安装 tauri-cli 并启动:

cd tauri-app
cargo install tauri-cli --version "^2.0.0" --locked
cargo tauri dev

执行后会发生什么:

  • Rust 侧开始编译(src-tauri 后端)
  • 前端 dev server 启动(如果模板是前端框架)
  • 自动弹出一个桌面窗口加载你的页面

看到窗口跑起来,就说明“工具链 + WebView + Rust 编译链路”全部通了。

3. 手动接入:给现有前端项目加上 Tauri(Tauri CLI)

如果你已经有前端工程(比如 Vite/Next/Nuxt/SvelteKit),推荐这条路线。整体思路是:

1)先确保你的前端能在浏览器里跑(有 dev server)
2)安装 tauri-cli
3)告诉 Tauri:dev server URL 是什么,build 命令是什么,产物目录在哪
4)cargo tauri dev 让 Tauri 编译并打开窗口加载 dev server

3.1 以 Vite 为例创建一个前端(示例)

如果你还没有前端项目,文档用 Vite 举例:

mkdir tauri-app
cd tauri-app
npm create vite@latest .

3.2 安装 Tauri CLI

用 cargo 全局安装(文档示例):

cargo install tauri-cli --version "^2.0.0" --locked

3.3 找到你的 dev server URL

比如 Vite 默认是:

http://localhost:5173

这个 URL 非常关键:Tauri 开发模式下就是加载它。

3.4 初始化 Tauri(生成 src-tauri)

在项目目录执行:

cargo tauri init

它会问一系列问题,典型如下:

  • App name:应用名
  • Window title:窗口标题
  • Web assets location:静态资源目录(构建后产物)
  • Dev server url:开发服务器 URL(例如 Vite 的 5173)
  • Frontend dev command:前端启动命令(例如 pnpm run dev
  • Frontend build command:前端构建命令(例如 pnpm run build

完成后,你会看到项目里多了一个 src-tauri/ 目录,这就是 Tauri 的 Rust 后端与配置中心。

3.5 启动 Tauri 开发模式

直接:

cargo tauri dev

它会:

  • 编译 Rust
  • 启动/连接你的前端 dev server
  • 打开桌面窗口加载页面

到这里,你的“现有前端工程”就正式变成了一个 Tauri App。

4. 实战建议:如何少走弯路

4.1 先跑通“最小闭环”

强烈建议第一天只干三件事:
1)把 create-tauri-app 跑起来
2)把 cargo tauri dev 跑起来
3)确认窗口打开、能加载页面、热更新能用

闭环通了,再开始做:

  • invoke 调 Rust 命令
  • 文件/系统能力插件
  • 打包与签名

4.2 不确定选什么就从 Vanilla 开始

Vanilla 最大价值是减少变量:

  • 你只在学习 Tauri,不被框架配置分散注意力
  • 后面要换 React/Vue 只是前端层替换,不影响你理解 Tauri 的核心工作方式

4.3 dev server URL 与 build 目录别填错

手动接入时最常见错误就是:

  • dev server URL 填错端口/协议
  • build 输出目录填错,导致打包后窗口白屏

经验:

  • dev server 先在浏览器里打开确认没问题
  • build 后的产物目录(dist/build/.output)要和你前端框架一致

4.4 tauri-cli 版本要对齐

文档示例明确安装 ^2.0.0,尽量保证 CLI 与项目依赖版本一致,减少“能编译但跑不起来”的奇怪兼容问题。

5. 你应该得到什么结果

不管你走哪条路线,最终你都会获得一个可运行的 Tauri App,并且开发时只需要记住一个核心命令:

cargo tauri dev

Tauri 用“系统 WebView + 原生能力”构建更小更快的跨平台应用

作者 HelloReader
2026年2月19日 22:39

1. Tauri 是什么

Tauri 是一个用于构建跨平台桌面与移动应用的框架,目标是产出“tiny, fast binaries”(体积小、启动快、性能好)的应用包。它允许你使用任何能够编译到 HTML / JavaScript / CSS 的前端框架来构建用户界面,同时在需要时用 Rust 来编写后端逻辑(也支持通过插件提供 Swift / Kotlin 绑定)。

一句话概括: Tauri = Web UI(你选框架) + 系统 WebView(不自带浏览器内核) + Rust/原生能力(安全与性能)

2. 为什么选择 Tauri:三大优势

官方把 Tauri 的核心优势总结为三点,我用更工程化的方式展开一下,便于你做技术选型。

2.1 安全底座:Rust 带来的“默认更安全”

Tauri 基于 Rust 构建,因此天然能受益于 Rust 的内存安全、线程安全、类型安全等特性。对应用开发者而言,即使你不是 Rust 专家,也能“默认吃到”一部分安全红利。

更重要的是,Tauri 对发布版本会进行安全审计,覆盖的不仅是 Tauri 组织内的代码,也会关注其依赖的上游依赖库。它不能消除所有风险,但能把底座风险压到更可控的范围内,适合更严肃的企业/生产场景。

你在安全治理上可以怎么落地:

  • 尽量把高权限操作封装为少量、明确的命令(command),减少暴露面
  • 针对 invoke 入口做参数校验与权限校验
  • 插件选型优先官方/高活跃社区插件,减少引入“不可审计黑盒”的概率

2.2 更小体积:利用系统原生 WebView

Tauri 的一个关键设计是:使用用户系统自带的 WebView 来渲染 UI。这意味着你的应用不需要像一些方案那样把整个浏览器引擎打包进安装包里。

因此,Tauri 应用的包体通常更小。官方提到极简应用甚至可以做到小于 600KB(具体体积会随功能、资源、平台不同而变化)。对于“分发成本”“冷启动”“增量更新”等维度,这一点非常有价值。

你在体积优化上可以进一步做:

  • 前端资源按需加载、路由懒加载、压缩图片与字体
  • 关闭不需要的特性与插件
  • 按平台做差异化资源打包

2.3 架构更灵活:前端随意选,原生能力可扩展

Tauri 对前端框架几乎没有限制:只要你的 UI 能编译成 HTML/JS/CSS,就能塞进 Tauri。React、Vue、Svelte、Solid、Angular,甚至纯静态页面都可以。

而当你需要更深层的系统集成时,Tauri 提供了多层扩展路径:

  • 直接用 invoke 做 JS 与 Rust 的桥接

  • 通过 Tauri Plugins 扩展能力,并提供 Swift / Kotlin 绑定(更贴近移动端生态)

  • 如果你需要更底层的窗口与 WebView 控制,还可以直接使用 Tauri 维护的底层库

    • TAO:窗口创建与事件循环
    • WRY:WebView 渲染与封装

这种分层非常“工程化”:你可以先用框架能力快速交付,后续再逐步下沉到插件或更底层库来解决复杂需求。

3. 快速开始:create-tauri-app 一键起项目

Tauri 推荐用 create-tauri-app 来创建项目。最简单的方式之一是直接执行脚本(Bash):

sh <(curl https://create.tauri.app/sh)

创建完成后,你应该马上去看两块内容:

  • Prerequisites(前置依赖):不同平台需要不同依赖(例如 macOS 的 Xcode、Windows 的构建工具链等)
  • Project Structure(项目结构):搞清楚哪些是前端目录、哪些是 Tauri/Rust 侧目录、配置文件分别控制什么

如果你想快速对照学习,也可以参考官方示例仓库的项目结构与特性组合(例如 tauri、plugins-workspace 等示例集合)。

4. 核心工作方式:前端渲染 + 后端命令

Tauri 的开发体验通常长这样:

  1. 前端负责页面与交互
  2. 需要系统能力(文件、系统信息、加密、数据库、通知、窗口控制等)时
  3. 前端通过 invoke 调用 Rust 侧命令(command)
  4. Rust 执行并返回结果给前端渲染

一个“最小心智模型”示例:

前端(JavaScript)调用:

import { invoke } from "@tauri-apps/api/core";

const res = await invoke("greet", { name: "Tauri" });
console.log(res);

后端(Rust)提供命令:

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

你可以把它理解为:前端发起 RPC,Rust 侧提供受控的能力接口。这也是 Tauri 安全模型常见的落点:尽量减少命令数量、缩小参数面、做严格校验。

5. 插件体系:把“常用系统能力”模块化

真实项目里,你不可能所有能力都自己从零写。Tauri 维护了一组官方插件,同时社区也提供了大量插件可选。插件的价值在于:

  • 把常见能力(如文件系统、对话框、通知、系统托盘等)标准化
  • 降低跨平台差异处理成本
  • 提供 Swift / Kotlin 绑定,让同一能力在移动端更自然地调用

选型建议(很实用):

  • 能用官方插件优先官方
  • 社区插件重点看:维护频率、issue 响应速度、最近版本发布时间、平台覆盖情况
  • 企业场景建议做一次“插件清单 + 权限与风险评估”,尤其是涉及敏感权限时

6. 什么时候 Tauri 特别合适

如果你符合下面任意一条,Tauri 通常会是很舒服的选择:

  • 想用 Web 技术做 UI,但不想承受“应用包巨大”的成本
  • 对安全与稳定性有要求,希望底座更可审计、更可控
  • 应用需要调用大量系统能力,但希望接口边界清晰
  • 需要跨平台,同时希望后端逻辑更接近系统、性能更好

反过来,如果你的应用强依赖某个特定浏览器内核特性,或者你希望所有用户环境完全一致(不受系统 WebView 差异影响),那你需要额外评估系统 WebView 的兼容边界与测试策略。

7. 总结:Tauri 的“设计哲学”

Tauri 的哲学其实很清楚:

  • UI 用 Web:开发效率高、生态成熟
  • 渲染用系统 WebView:体积小、分发轻
  • 能力层用 Rust/原生:更安全、更稳定、更可控
  • 通过插件与底层库(TAO/WRY)提供从“快速交付”到“深度定制”的梯度

如果你准备开始上手,建议路径是:

  1. 用 create-tauri-app 起项目
  2. 把核心 UI 跑起来
  3. 把系统能力用 invoke 串起来
  4. 再引入必要插件,逐步打磨工程结构与安全边界

Tauri 开发环境 Prerequisites 全攻略(桌面 + 移动端)

作者 HelloReader
2026年2月19日 22:37

1. 先做一个选择题:你要做哪种目标

你只需要安装与你的目标匹配的依赖:

  • 只做桌面端(Windows/macOS/Linux)

    • System Dependencies + Rust
    • 如果 UI 用 React/Vue 等,再装 Node.js
  • 做移动端(Android/iOS)

    • 桌面端全部依赖 + 移动端额外依赖(Android Studio / Xcode 等) (Tauri)

2. Linux:系统依赖怎么装(以 Debian/Ubuntu 为例)

Tauri 在 Linux 上需要 WebView(GTK WebKit)、构建工具链、OpenSSL、托盘/图标相关库等。不同发行版包名会有差异。 (Tauri)

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

几个经验点:

  • 看到 openssl-sys 相关报错,优先检查 libssl-dev / openssl 开发包是否安装齐全;必要时设置 OPENSSL_DIR。 (GitHub)
  • 如果你在对照旧文章(Tauri v1)装 libwebkit2gtk-4.0-dev,在新系统(如 Ubuntu 24)可能会遇到仓库里没有的情况;v2 文档用的是 4.1。 (GitHub)
  • 打包 Debian 包时,运行时依赖一般会包含 libwebkit2gtk-4.1-0libgtk-3-0,托盘用到还会带 libappindicator3-1(这有助于你排查“运行环境缺库”问题)。 (Tauri)

装完 Linux 依赖后,下一步直接装 Rust。

3. macOS:Xcode 是关键

macOS 上 Tauri 依赖 Xcode 及其相关开发组件,安装来源两种:

  • Mac App Store
  • Apple Developer 网站下载

安装后一定要启动一次 Xcode,让它完成首次配置。 (Tauri)

仅做桌面端:装好 Xcode → 继续安装 Rust 要做 iOS:除了 Xcode,还要按 iOS 章节继续装 targets、Homebrew、CocoaPods(后面会写)。 (Tauri)

4. Windows:C++ Build Tools + WebView2(MSI 还可能需要 VBSCRIPT)

4.1 安装 Microsoft C++ Build Tools

安装 Visual Studio C++ Build Tools 时,勾选 “Desktop development with C++”(桌面 C++ 开发)。 (Tauri)

4.2 安装 WebView2 Runtime

Tauri 在 Windows 用 Microsoft Edge WebView2 渲染内容。

  • Windows 10(1803+)/ Windows 11 通常已预装 WebView2,可跳过安装步骤
  • 如果缺失,安装 WebView2 Runtime(文档建议 Evergreen Bootstrapper) (Tauri)

4.3 只有当你要打 MSI 安装包时:检查 VBSCRIPT

当你的 tauri.conf.json 使用 "targets": "msi""targets": "all",构建 MSI 可能会依赖系统的 VBSCRIPT 可选功能;若遇到类似 light.exe 执行失败,可去 Windows 可选功能里启用 VBSCRIPT。 (Tauri)

做完 Windows 依赖后,下一步装 Rust。

5. Rust:所有平台都必须装(用 rustup)

Tauri 基于 Rust,因此开发必装 Rust 工具链。官方推荐 rustup: (Tauri)

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

安装后建议:

  • 关闭并重开终端(有时需要重启系统)让 PATH 生效 (Tauri)

6. Node.js:只有当你用 JS 前端生态时才需要

如果你的 UI 用 React/Vue/Svelte 等 JavaScript 生态,就安装 Node.js(建议 LTS),并验证:

node -v
npm -v

想用 pnpm / yarn 等,可以按需启用 corepack:

corepack enable

同样建议重开终端确保命令可用。 (Tauri)

7. 移动端额外依赖:Android / iOS

7.1 Android(跨平台都能做)

核心步骤:

  1. 安装 Android Studio
  2. 设置 JAVA_HOME(指向 Android Studio 的 JBR)
  3. 用 SDK Manager 安装:Platform、Platform-Tools、NDK(Side by side)、Build-Tools、Command-line Tools
  4. 设置 ANDROID_HOMENDK_HOME
  5. 用 rustup 添加 Android targets (Tauri)

环境变量示例(Linux/macOS):

export JAVA_HOME=/opt/android-studio/jbr
export ANDROID_HOME="$HOME/Android/Sdk"
export NDK_HOME="$ANDROID_HOME/ndk/$(ls -1 $ANDROID_HOME/ndk)"

添加 targets:

rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android

常见坑:

  • tauri android initNDK_HOME environment variable isn't set:基本就是 NDK 没装或环境变量没指到正确 NDK 目录。 (GitHub)

7.2 iOS(仅 macOS)

iOS 开发必须是 macOS + Xcode(注意是 Xcode 本体,不是只装 Command Line Tools)。 (Tauri)

步骤:

  1. rustup 添加 iOS targets
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
  1. 安装 Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. 安装 CocoaPods
brew install cocoapods

完成后就可以进入创建项目/初始化移动端的流程。 (Tauri)

8. 快速自检清单(装完别急着开写代码)

你可以用这几个“最小验证”确认环境 OK:

  • Rust 是否可用:rustc -Vcargo -V
  • Node 是否可用(如需要):node -vnpm -v
  • Windows:是否装了 C++ Build Tools;WebView2 是否存在(Win10 1803+ 通常无需额外装) (Tauri)
  • Linux:libssl-dev / WebKitGTK dev 包是否装齐(遇到 openssl-sys 错误优先查这块) (GitHub)
  • Android:ANDROID_HOMENDK_HOME 是否指向正确目录 (GitHub)
❌
❌