1. 项目概述:为什么今天还在纠结 Electron 和 Tauri?
Electron 和 Tauri 是当前跨平台桌面应用开发领域绕不开的两个名字。如果你正打算用 Web 技术(Vue、React、Svelte)写一个 Windows/macOS/Linux 都能跑的本地软件——比如内部工具、数据看板、硬件控制面板、甚至轻量级 IDE 插件——那你大概率会卡在“选哪个框架”这一步。这不是技术情怀之争,而是实实在在的工程权衡:体积多大、启动多快、安全边界在哪、后续维护成本几何。我过去三年带过 7 个桌面端项目,从 200KB 的设备配置小工具,到 300MB 的工业数据采集分析平台,全部走的是 Web 技术栈路线。其中 4 个用 Electron,3 个用 Tauri,不是凭感觉切换,而是一次次被安装包大小逼着改方案、被客户投诉“双击图标等 8 秒才出窗口”倒逼优化启动流程、被安全审计团队指着 IPC 通信链路说“这里没做沙箱隔离,算高危漏洞”。所以这篇不是泛泛而谈的对比评测,而是把 Electron 和 Tauri 拆开揉碎,放到真实交付场景里——测体积、掐秒表、翻源码、抓内存、看进程树,告诉你哪一行配置能省下 12MB,哪个 IPC 调用路径实际开了 3 层权限豁免,为什么 Tauri 在 Windows 上默认不带 WebView2 运行时反而更可控。核心关键词就五个:Electron、Tauri、跨平台桌面应用、体积、启动。适合三类人:正在做技术选型的架构师、被打包后体积暴涨吓到的前端开发者、以及刚被安全团队约谈、急需搞懂 IPC 通信风险边界的工程师。它不教你怎么写第一个 Hello World,而是帮你避开上线前最后一公里的坑。
2. 核心设计逻辑拆解:体积与启动背后的底层哲学差异
2.1 Electron 的“全栈搬运工”模式:便利性换来的确定性代价
Electron 的设计哲学非常直白:把 Chromium 浏览器引擎 + Node.js 运行时整个打包进你的应用。它不假设你系统里有没有 Chrome,也不管你装没装 Python 或 .NET Framework,它只做一件事——给你一个“自带浏览器的 Node 环境”。这种“全量携带”的思路带来了极强的确定性:你在 macOS 上调试好的渲染逻辑,打包到 Windows Server 2012 上照样跑;你用的最新版 Vite 构建产物,不用操心目标机器的 WebView 版本兼容性。但代价是物理层面的——Chromium 本身就是一个庞然大物。截至 Electron 28(2024 年 Q2 主流稳定版),其最小可裁剪的 runtime 体积约为125MB(Windows x64)。这个数字怎么来的?我们拆开看:
- Chromium 内核(含 Blink 渲染引擎、V8 JS 引擎、Skia 图形库):约 98MB
- Node.js 运行时(v18.17+):约 18MB
- Electron 自身胶水层(主进程 API、IPC 封装、原生模块加载器):约 9MB
这还只是“空壳”,没算你的业务代码、Vue 组件、图表库、字体文件。一个中等复杂度的 Vue 3 + Element Plus 应用,构建后静态资源约 8–12MB,加上 Electron runtime,最终安装包轻松突破 140MB。更关键的是,这个体积是“刚性”的——你删掉node_modules/electron/dist/resources/default_app.asar,应用直接起不来;你试图用electron-builder的asarUnpack排除某些 DLL,结果发现chrome_elf.dll或d3dcompiler_47.dll被误删,启动时报错STATUS_DLL_NOT_FOUND。这不是配置问题,是架构决定的:Electron 的“全栈搬运”意味着它必须为所有可能的 Web API(WebGL、WebRTC、WebUSB)预置完整依赖,哪怕你只用<img>标签。
提示:很多人以为
--no-sandbox能减体积,这是典型误区。--no-sandbox只是关闭 Chromium 的沙箱进程模型,不删除任何二进制文件,反而因绕过安全校验增加运行时崩溃风险,对体积零影响。
2.2 Tauri 的“按需组装”范式:操作系统原生能力的可信代理
Tauri 走了完全相反的路:它不打包浏览器,而是调用操作系统自带的 WebView 控件。在 Windows 上是 WebView2(基于 Edge Chromium),macOS 上是 WKWebView(基于 Safari),Linux 上是 WebKitGTK。这意味着 Tauri 应用的体积核心只包含三部分:
- Rust 编写的主进程二进制(含 IPC 路由、系统 API 桥接、命令行解析):约 3–5MB
- 你的前端构建产物(HTML/CSS/JS):与 Electron 完全一致,无额外膨胀
- WebView2 运行时(仅 Windows 需要,且可选):0MB(若用户已装 Edge)或 25MB(若需静默安装)
我们实测一个相同功能的设备监控面板(Vue 3 + Chart.js + Tailwind CSS):
- Electron 打包后:142.6MB(
electron-builder默认配置) - Tauri 打包后:28.3MB(含 WebView2 运行时)或3.8MB(仅主程序+前端资源,依赖系统 WebView2)
这个数量级差异源于根本性设计选择。Tauri 的主进程是 Rust 编译的原生二进制,没有 V8 引擎、没有 Blink 渲染器、没有庞大的 Chromium 网络栈。它只做一件事:当渲染进程(即你的网页)发来一个 IPC 请求(如invoke('get_device_list')),主进程通过 Rust 的tauri::command宏解析参数,调用系统 API(如 Windows 的SetupDiEnumDeviceInfo),再把结果序列化回 JSON 发给前端。整个过程不经过 Node.js,不启动额外进程,不加载第三方模块。因此,它的体积增长是线性的——你加一个新命令,主进程二进制只增几 KB;而 Electron 是指数级的——你加一个require('usb')原生模块,就得打包整个 libusb 二进制及其所有依赖 DLL。
注意:Tauri 的“轻量”有前提——它要求目标系统具备现代 WebView。Windows 7 不支持 WebView2(官方已终止支持),Windows 10 1803+ 才能用。如果你的客户还在用 Win7,Tauri 不是选项,这是硬性约束,不是配置问题。
2.3 启动速度的本质:进程创建 vs 进程复用
启动时间差异比体积更直观,也更能暴露底层机制。我们用Process Explorer和Windows Performance Analyzer对比同一台 i7-11800H 笔记本(32GB RAM,PCIe SSD)上的冷启动:
| 指标 | Electron(v28.2.0) | Tauri(v1.6.0) | 差异根源 |
|---|---|---|---|
| 进程创建耗时 | 1200–1800ms | 180–320ms | Electron 需 fork 主进程 → 启动 Chromium GPU 进程 → 启动 Renderer 进程 → 加载 V8 上下文;Tauri 直接 exec 原生二进制,WebView 由 OS 复用已有实例 |
| 首屏渲染(空白页) | 850–1100ms | 220–380ms | Electron 的 Renderer 进程需初始化完整 Blink 渲染管线;Tauri 的 WebView 由系统管理,首次调用webview::new()仅需绑定 JS 上下文 |
| 首次 IPC 响应 | 420–650ms | 35–85ms | Electron 的 IPC 经过 Node.js event loop → 主进程 V8 → 原生模块桥接;Tauri 的tauri::command是 Rust 函数直接调用,无 JS 中间层 |
关键洞察在于:Electron 的启动是“启动一个浏览器”,而 Tauri 的启动是“启动一个调用浏览器的程序”。前者必须完成整个 Chromium 初始化流水线(包括 GPU 进程同步、字体缓存加载、网络栈预热),后者只需让 OS 的 WebView 控件加载你的 HTML 文件。这也是为什么 Tauri 在低端设备(如 Intel Celeron N4020 + 4GB RAM 的工控机)上启动更稳——它不和 Chromium 抢内存,而 Electron 常因内存不足触发 Chromium 的 OOM Killer,导致白屏卡死。
2.4 安全模型重构:从“全权限沙箱”到“最小权限代理”
安全不是附加功能,而是框架基因。Electron 默认采用 Chromium 的多进程沙箱模型:Renderer 进程(网页)被严格限制,不能直接访问文件系统或硬件;所有敏感操作必须通过ipcRenderer.invoke()发送给 Main Process,再由主进程用 Node.js API 执行。听起来很安全?问题出在“信任链”上。一旦主进程被注入恶意代码(如通过eval()动态执行远程脚本),整个沙箱就形同虚设。更现实的风险是:大量 Electron 应用为图方便,在webPreferences中设置nodeIntegration: true和contextIsolation: false,这等于把 Renderer 进程的 JS 直接暴露在 Node.js 全局作用域下,一个 XSS 漏洞就能require('child_process').exec('rm -rf /')。
Tauri 则从设计上切断这条信任链。它的主进程是 Rust 二进制,没有eval、没有Function构造函数、没有动态代码加载能力。所有 IPC 命令都必须在编译期声明(#[tauri::command]),运行时参数经serde_json严格反序列化,类型错误直接拒绝。更重要的是,Tauri 默认禁用所有系统 API,你必须显式在tauri.conf.json中声明所需权限:
{ "permissions": { "fs-read": ["./data/**"], "fs-write": ["./logs/*.log"], "os-locale": true, "shell-open": true } }没有声明的权限,Rust 主进程连std::fs::read_dir都不会执行。这叫“默认拒绝”(deny-by-default),而非 Electron 的“默认允许”(allow-by-default)。我们曾审计过一个 Electron 项目,其主进程main.js里有 17 个ipcMain.handle,其中 3 个接受任意路径字符串并传给fs.readFileSync,构成典型的路径遍历漏洞;而同等功能的 Tauri 实现,tauri.conf.json里只开放了./config/目录读取权限,且命令函数内做了Path::canonicalize校验,攻击者传../../../etc/passwd直接被拒。
3. 实操细节与关键参数:如何把理论差异落到每一行代码
3.1 体积压缩实战:Electron 的“瘦身手术”与 Tauri 的“精准裁剪”
Electron 体积优化四步法(实测有效)
剔除无用 Chromium 组件
Electron 默认打包所有 Chromium 功能模块(PDF Viewer、Flash Player、Widevine DRM),但多数桌面应用用不到。通过electron-builder的extraResources和files配置,可移除特定 DLL:{ "build": { "files": [ "!resources/app.asar.unpacked/node_modules/electron/dist/chrome_100_percent.pak", "!resources/app.asar.unpacked/node_modules/electron/dist/chrome_200_percent.pak", "!resources/app.asar.unpacked/node_modules/electron/dist/icudtl.dat", "!resources/app.asar.unpacked/node_modules/electron/dist/libEGL.dll", "!resources/app.asar.unpacked/node_modules/electron/dist/libGLESv2.dll" ] } }实操心得:
icudtl.dat(Unicode 数据库)删掉会导致中文日期格式异常,必须保留;libEGL.dll和libGLESv2.dll是 OpenGL ES 支持库,若应用不用 WebGL 可删,节省约 3.2MB。我试过删pdf_viewer_resources.pak,结果 PDF 预览功能失效,得不偿失。启用 ASAR 压缩并排除大文件
ASAR 是 Electron 的归档格式,类似 ZIP,但对小文件压缩率高,大文件(如视频、图片)反而增大体积。正确做法是:{ "build": { "asar": true, "asarUnpack": ["assets/videos/**", "assets/images/large/**"] } }这样
assets/videos/下所有文件以原始形式存放,避免 ASAR 解压时内存暴涨。替换 Node.js 为更小的运行时
Electron 28+ 支持--enable-nodejs开关,但默认仍捆绑完整 Node.js。若你只用fs、path等基础模块,可尝试electron-forge的@electron-forge/maker-zip配合自定义node二进制(用nexe编译精简版),但风险极高——nexe编译的 Node 不支持require('child_process'),而很多 CLI 工具依赖它。我们最终放弃此方案,转而用pkg打包独立 Node 二进制,再让 Electron 主进程调用它,体积降了 11MB,但启动慢了 200ms,权衡后未上线。用
electron-packager替代electron-builderelectron-builder功能全但臃肿,其nsis安装包生成器自带 7-Zip 和 NSIS 运行时。改用electron-packager+7z手动压缩:electron-packager . MyApp --platform=win32 --arch=x64 --electron-version=28.2.0 --out=dist 7z a -t7z dist/MyApp-win32-x64.7z dist/MyApp-win32-x64 -mx=9此法将 142MB 的
MyApp-win32-x64目录压缩为 48MB 的.7z包,用户下载后解压即可运行,跳过安装程序,体积感知降低 66%。
Tauri 体积精控三原则(零容错)
Rust 编译配置:Release 模式 + LTO
Cargo.toml中必须启用链接时优化(LTO):[profile.release] lto = true codegen-units = 1 panic = "abort"lto = true让 Rust 编译器在链接阶段全局优化,消除未使用函数,实测使主进程二进制从 4.8MB 降至 3.1MB。panic = "abort"禁用 Rust 的 panic 处理栈展开,节省约 200KB。WebView2 运行时策略:按需静默安装
Windows 用户分两类:已装 Edge(占 Win10+/Win11 用户 92%)和未装用户。Tauri 提供webview_install配置:{ "tauri": { "bundle": { "windows": { "webview_install_mode": { "custom": "C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe" } } } } }这样打包时只嵌入 25MB 的 WebView2 Bootstrapper(
Microsoft.WebView2.Bootstrapper.x64.msi),安装时检测 Edge 版本,自动静默安装或跳过。我们线上统计显示,93% 的安装过程跳过了 WebView2 安装步骤,用户感知体积就是主程序 3.1MB + 前端资源 2.7MB =5.8MB。前端资源极致压缩:Vite + Squoosh
Tauri 对前端无特殊要求,但体积敏感度更高。我们在vite.config.ts中启用:export default defineConfig({ build: { rollupOptions: { output: { manualChunks: { vendor: ['vue', 'vue-router', 'pinia'], chart: ['chart.js'] } } }, assetsInlineLimit: 4096, // 小于4KB的图片转base64 minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true } } } })构建后,再用
squoosh-cli批量压缩 PNG/JPEG:npx squoosh-cli --quality 75 --format webp src/assets/images/**/*此步将 12MB 的图片资源压至 3.4MB,占总包体积比从 42% 降至 12%。
3.2 启动性能调优:从“秒级等待”到“毫秒响应”
Electron 启动加速七项实操
禁用 GPU 进程(谨慎!)
Chromium 的 GPU 进程负责合成、视频解码,但桌面应用若不用 WebGL 或视频播放,可禁用:app.commandLine.appendSwitch('disable-gpu') app.commandLine.appendSwitch('disable-gpu-compositing')实测启动快 180ms,但 UI 动画(如 Vue 的
transition)会卡顿。我们只在后台服务类应用(无 UI)中启用。延迟加载非关键模块
主进程main.js中,把autoUpdater、Tray、Menu等非首屏必需模块移到app.whenReady()之后:app.whenReady().then(() => { createWindow() // 此处再 require('electron-updater') 和 initTray() })避免 Node.js 模块加载阻塞主进程初始化。
Renderer 进程预加载脚本瘦身
preload.js是 Renderer 和 Main 的桥梁,但常被写成“万能胶水”。必须只暴露必要 API:// ❌ 错误:暴露整个 ipcRenderer contextBridge.exposeInMainWorld('ipc', ipcRenderer) // ✅ 正确:只暴露需要的命令 contextBridge.exposeInMainWorld('api', { getDeviceList: () => ipcRenderer.invoke('get-device-list'), saveConfig: (cfg) => ipcRenderer.invoke('save-config', cfg) })这样
preload.js体积从 12KB 降至 1.8KB,V8 初始化更快。启用
app.disableHardwareAcceleration()
在低配设备上,强制禁用硬件加速可避免 GPU 驱动兼容性问题导致的启动失败。我们在线上收集到 3.2% 的 Win10 启动失败日志,均指向gpu-process-crashed,启用此开关后归零。用
app.setAppUserModelId()避免 Windows 资源重载
Windows 任务栏为每个 Electron 实例创建独立 AppID,导致图标、通知模板重复加载。添加:app.setAppUserModelId('com.mycompany.myapp')启动时任务栏识别为同一应用,减少资源初始化开销。
BrowserWindow创建参数优化show: false+ready-to-show事件是标准做法,但常被忽略的是webPreferences:const win = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: false, // 必须 false contextIsolation: true, // 必须 true preload: path.join(__dirname, 'preload.js'), sandbox: true, // 启用沙箱,虽增加启动 50ms,但安全必选 webSecurity: true, allowRunningInsecureContent: false } })sandbox: true是 Chromium 沙箱开关,开启后 Renderer 进程完全无法访问 Node.js,必须通过 IPC,启动略慢但杜绝 XSS 提权。主进程单例锁(防多开)
Electron 默认允许多实例,但app.requestSingleInstanceLock()会触发 IPC 通信。改为用文件锁:const lockFile = path.join(app.getPath('temp'), 'myapp.lock') const fd = fs.openSync(lockFile, 'wx') // 启动成功,fd 为文件描述符 // 退出时 fs.closeSync(fd); fs.unlinkSync(lockFile)避免 IPC 初始化开销,实测多开检测快 120ms。
Tauri 启动提速五要点(Rust 优先)
tauri.conf.json中禁用无用功能
默认tauri.conf.json启用所有功能,但多数用不到:{ "tauri": { "allowlist": { "all": false, "fs": { "all": false, "readFile": true, "writeFile": true }, "shell": { "open": true }, "dialog": { "all": false, "ask": true, "message": true } } } }关闭
all: true,只开必需 API,Rust 编译时会剔除未引用的模块,主进程二进制小 400KB。前端
index.html内联关键 CSS/JS
Tauri 启动时需加载 HTML,再解析<link>和<script>。将首屏必需的 CSS 和 JS 内联:<style>/* 首屏按钮、标题样式 */</style> <script type="module"> // 首屏数据获取逻辑 fetch('/api/init').then(r => r.json()).then(initApp) </script>减少 HTTP 请求,首屏渲染快 150ms。
Rust 主进程
main.rs延迟初始化#[tauri::command]函数是懒加载的,但setup()回调里常做数据库连接、日志初始化等重操作。必须拆分:#[tauri::command] async fn get_device_list() -> Result<Vec<Device>, String> { // 此函数只在被调用时执行,不阻塞启动 Ok(Device::list().await?) } fn main() { tauri::Builder::default() .setup(|app| { // 只做轻量初始化:注册命令、设置窗口 Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }启用
tauri::async_runtime::Tokio的multi_thread
默认 Tokio 运行时是单线程,IO 密集型操作(如文件读取)会阻塞。在Cargo.toml中:[dependencies.tauri] version = "1.6" features = ["shell-all", "fs-all", "process-all"] [dependencies] tokio = { version = "1.33", features = ["full"] }tokio = { features = ["full"] }启用多线程调度器,get_device_list并发读取 10 个设备配置文件时,耗时从 820ms 降至 110ms。Windows 上禁用
WebView2的ScriptNotifyScriptNotify是 WebView2 向宿主发送 JS 事件的机制,但 Tauri 用window.__TAURI_IPC__通信,无需它。在src-tauri/src/main.rs中:#[cfg(target_os = "windows")] tauri::Builder::default() .setup(|app| { let webview_window = app.get_webview_window("main").unwrap(); webview_window.eval("window.chrome.webview.settings.isScriptNotifyAllowed = false;")?; Ok(()) })避免 WebView2 初始化时注册事件监听器,启动快 40ms。
3.3 安全加固实操:IPC 通信的“防火墙”配置
Electron IPC 安全三重加固
contextIsolation+worldSafeExecuteJavaScript组合
这是 Electron 12+ 的安全基石。contextIsolation: true隔离 Renderer 的 JS 上下文,worldSafeExecuteJavaScript: true禁用eval和Function:const win = new BrowserWindow({ webPreferences: { contextIsolation: true, worldSafeExecuteJavaScript: true, preload: path.join(__dirname, 'preload.js') } })preload.js中必须用contextBridge暴露 API,否则 Renderer 无法调用。IPC 参数白名单校验
ipcMain.handle不能直接透传参数。必须用zod或yup校验:import { z } from 'zod' const SaveConfigSchema = z.object({ host: z.string().ip(), port: z.number().min(1).max(65535), timeout: z.number().min(1000).max(30000) }) ipcMain.handle('save-config', async (event, data) => { try { const validated = SaveConfigSchema.parse(data) await fs.writeFile('./config.json', JSON.stringify(validated)) } catch (err) { throw new Error('Invalid config format') } })防止
host: '../../../etc/passwd'类型的路径遍历。主进程权限最小化
Node.js 的fs、child_process模块默认全局可用。用vm模块沙箱化主进程:const { VM } = require('vm2') const vm = new VM({ sandbox: { fs: require('fs').promises, path: require('path') } }) ipcMain.handle('safe-fs-read', async (event, path) => { return vm.run(`fs.readFile(path, 'utf8')`, { path }) })即使 IPC 被劫持,攻击者也只能调用
fs.readFile,无法fs.rm或child_process.exec。
Tauri 安全配置四准则
tauri.conf.json权限粒度控制
如前所述,permissions必须精确到目录和文件名:"fs-read": ["./config/app.json", "./data/schema/*.json"], "fs-write": ["./logs/{date}.log"]{date}是 Tauri 的通配符,匹配2024-06-15.log,但不匹配../etc/shadow。Rust 命令函数内路径规范化
即使配置了权限,也要在 Rust 代码中校验:#[tauri::command] async fn read_config_file(path: String) -> Result<String, String> { let abs_path = std::env::current_dir() .map_err(|e| e.to_string())? .join(&path); let canonical = abs_path .canonicalize() .map_err(|e| e.to_string())?; // 检查是否在允许目录内 if !canonical.starts_with("./config") { return Err("Access denied".to_string()); } std::fs::read_to_string(canonical).await.map_err(|e| e.to_string()) }禁用
tauri::api::shell::open的任意 URLshell::open默认允许打开任何 URL,可能被用于file://协议读取本地文件。必须限制协议:#[tauri::command] async fn safe_open_url(url: String) -> Result<(), String> { if url.starts_with("https://") || url.starts_with("http://") { tauri::api::shell::open(&url).await.map_err(|e| e.to_string()) } else { Err("Only http/https URLs allowed".to_string()) } }启用
tauri::api::process::Command的白名单
若需执行外部命令,必须硬编码白名单:#[tauri::command] async fn run_tool(tool: String, args: Vec<String>) -> Result<String, String> { match tool.as_str() { "ping" => { let output = Command::new("ping") .args(args) .output() .await .map_err(|e| e.to_string())?; Ok(String::from_utf8(output.stdout).unwrap_or_default()) } _ => Err("Tool not allowed".to_string()), } }tool参数只能是"ping",无法传"cmd"或"sh"。
4. 常见问题与排查技巧实录:那些文档里不会写的坑
4.1 Electron 常见问题速查表
| 问题现象 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
| 启动黑屏,DevTools 无法打开 | webPreferences.contextIsolation: false且nodeIntegration: true导致 JS 上下文污染 | console.log(process.versions)查看 Node/V8 版本;process.argv检查启动参数 | 强制contextIsolation: true,用contextBridge重构preload.js |
打包后require('fs')报错 | asar: true时fs无法读取 ASAR 内部文件 | console.log(__dirname)确认路径;fs.existsSync(path.join(__dirname, 'app.asar')) | 用fs.createReadStream或app.getAppPath()获取 ASAR 路径,或asarUnpack排除 |
Windows 上link.exe not found | electron-rebuild需 Visual Studio Build Tools,但未安装 C++ 构建工具 | where link.exe;npm config get msvs_version | 安装 VS Build Tools 2022,npm config set msvs_version 2022 |
Mac 上签名后启动报Library not loaded | 原生模块(如usb)未正确签名或rpath错误 | otool -L node_modules/usb/build/Release/usb_bindings.node | 用electron-rebuild重新编译,或codesign --deep --force --sign "Developer ID Application: XXX" |
app.getGPUInfo('complete')返回空 | Chromium GPU 进程未启动或驱动不支持 | app.commandLine.appendSwitch('enable-logging')查看debug.log | 添加app.commandLine.appendSwitch('disable-gpu'),或更新显卡驱动 |
实操心得:Electron 的
link.exe not found是新手最大坑。根本不是 Tauri 的问题,而是electron-rebuild依赖 VS Build Tools 的link.exe。我们曾让客户在无 VS 的生产环境跑npm rebuild,结果报错。解决方案是:所有原生模块编译必须在 CI/CD 流水线中完成,打包机预装 VS Build Tools,产出.node文件随安装包分发,用户机器零编译。
4.2 Tauri 常见问题速查表
| 问题现象 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
Windows 启动报WebView2 not found | 用户未装 Edge 或版本过低(< 91) | Get-AppxPackage -Name "Microsoft.Edge"PowerShell 命令;winget list Microsoft.Edge | 在tauri.conf.json中配置webview_install_mode: "download",或提供 Edge 离线安装包 |
Linux 上WebKitGTK渲染空白 | Ubuntu 20.04 默认webkit2gtk-4.0版本太低(< 2.34) | `apt list --installed | grep webkit;ldd target/release/myapp | grep webkit` |
Rust 编译报proc-macro错误 | tauri-build和tauri-codegen版本不匹配 | cargo tree | grep tauri;rustc --version | cargo update -p tauri-build,确保tauri-build、tauri-codegen、tauri三者版本一致(如1.6.0) |
tauri::api::dialog::ask中文乱码 | GTK 主题字体缺失或编码问题 | locale -a | grep zh_CN;fc-list | grep -i simsun | sudo apt install fonts-wqy-zenhei(Ubuntu),或在tauri.conf.json中指定 |