1. 配置清单:先把底层规则记住
把下面三条当作 Tauri 前端接入的硬规则:
- 只走静态路线:SSG / SPA / MPA
Tauri 不原生支持基于服务端的方案(例如 SSR)。(Tauri) - 移动端真机开发必须有“可被设备访问”的 dev server
需要让 dev server 绑定到你的内网 IP(或按 Tauri CLI 提供的 host),否则 iOS/Android 真机加载不到页面。(Tauri) - 保持标准的 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.envPrefix把TAURI_环境变量也暴露给前端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)