作为一名经验丰富的 Electron 开发者,当你第一次接触 Tauri 时,可能会感到有些不适应。本文将帮助你快速理解 Tauri 2.0 的核心概念,并通过实际案例完成从 Electron 到 Tauri 的思维转换。
架构对比
Electron 的架构
在 Electron 中,我们习惯了以下架构:
Electron 应用
├── 主进程 (Main Process)
│ ├── 窗口管理
│ ├── 系统API调用
│ └── IPC 通信
└── 渲染进程 (Renderer Process)
├── 前端界面
├── 渲染逻辑
└── IPC 通信
主要特点:
- 基于 Chromium 和 Node.js
- 主进程和渲染进程分离
- 通过 IPC 进行进程间通信
- 直接使用 Node.js API
Tauri 2.0 的架构
Tauri 采用了不同的架构方式:
Tauri 应用
├── 核心进程 (Rust Core)
│ ├── 窗口管理
│ ├── 系统API调用
│ └── 命令系统
└── 前端界面 (WebView)
├── 界面渲染
├── 业务逻辑
└── Tauri API
主要特点:
- 基于系统 WebView
- Rust 核心进程
- 统一的命令系统
- 更安全的权限控制
开发环境搭建
前置依赖
# Electron 项目通常只需要
npm install -g electron
# Tauri 项目需要安装
# 1. Rust 环境
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 2. 系统依赖(以 Ubuntu 为例)
sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \
build-essential \
curl \
wget \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev
项目初始化
# Electron 项目初始化
npm init
npm install electron --save-dev
# Tauri 项目初始化
npm create tauri-app
# 或者使用 yarn
yarn create tauri-app
项目结构对比
Electron 项目结构
my-electron-app/
├── package.json
├── main.js
├── preload.js
└── src/
├── index.html
├── renderer.js
└── styles.css
Tauri 项目结构
my-tauri-app/
├── package.json
├── src/ # 前端代码
│ ├── App.tsx
│ └── styles.css
├── src-tauri/ # Rust 代码
│ ├── Cargo.toml # Rust 依赖配置
│ ├── tauri.conf.json # Tauri 配置
│ └── src/
│ └── main.rs # 核心进程代码
└── index.html
Hello World 对比实现
Electron 版本
// main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Hello Electron</title>
</head>
<body>
<h1>Hello Electron!</h1>
</body>
</html>
Tauri 2.0 版本
// src-tauri/src/main.rs
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
// src/App.tsx
import { invoke } from '@tauri-apps/api/tauri'
import { useState } from 'react'
function App() {
const [greeting, setGreeting] = useState('')
async function greet() {
setGreeting(await invoke('greet', { name: 'Tauri' }))
}
return (
<div>
<h1>{greeting || 'Hello Tauri!'}</h1>
<button onClick={greet}>Greet</button>
</div>
)
}
export default App
开发调试体验
Electron 调试
主进程调试
{ "scripts": { "start": "electron .", "debug": "electron --inspect=5858 ." } }
- 渲染进程调试
- 使用 Chrome DevTools
- 快捷键:Ctrl+Shift+I (Windows/Linux) 或 Cmd+Option+I (macOS)
Tauri 调试
前端调试
# 启动开发服务器 npm run dev
Rust 代码调试
// .vscode/launch.json { "version": "0.2.0", "configurations": [ { "type": "lldb", "request": "launch", "name": "Tauri Development Debug", "cargo": { "args": ["build", "--manifest-path=./src-tauri/Cargo.toml"] }, "cwd": "${workspaceFolder}" } ] }
常见功能对比
1. 窗口创建
Electron:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
width: 800,
height: 600
})
Tauri:
use tauri::Window;
#[tauri::command]
async fn create_window(app_handle: tauri::AppHandle) {
tauri::WindowBuilder::new(
&app_handle,
"new_window",
tauri::WindowUrl::App("index.html".into())
)
.title("New Window")
.inner_size(800.0, 600.0)
.build()
.unwrap();
}
2. IPC 通信
Electron:
// 主进程
ipcMain.handle('get-data', async (event, arg) => {
return 'data'
})
// 渲染进程
const result = await ipcRenderer.invoke('get-data')
Tauri:
// Rust
#[tauri::command]
fn get_data() -> String {
"data".into()
}
// TypeScript
import { invoke } from '@tauri-apps/api/tauri'
const result = await invoke('get_data')
3. 文件操作
Electron:
const fs = require('fs')
fs.readFileSync('file.txt', 'utf8')
Tauri:
// Rust
use std::fs;
#[tauri::command]
fn read_file() -> String {
fs::read_to_string("file.txt").unwrap()
}
// TypeScript
import { invoke } from '@tauri-apps/api/tauri'
const content = await invoke('read_file')
性能对比
以下是一个简单的内存占用对比:
应用类型 | 空应用内存占用 |
---|---|
Electron | ~100MB |
Tauri | ~20MB |
主要优势:
- 更小的安装包体积
- 更低的内存占用
- 更快的启动速度
- 更好的系统集成
开发建议
渐进式迁移
- 先熟悉 Tauri 的基本概念
- 从小功能开始迁移
- 保持代码结构清晰
充分利用 Rust 优势
- 性能密集型操作放在 Rust 端
- 使用 Rust 的并发特性
- 注意内存安全
前端代码复用
- UI 代码可以大部分复用
- 抽象化平台相关的 API
- 使用适配器模式
安全性考虑
- 使用 Tauri 的权限系统
- 谨慎开放系统 API
- 做好输入验证
常见问题解决
Node.js API 替代方案
// Electron const path = require('path') path.join(__dirname, 'file') // Tauri import { join } from '@tauri-apps/api/path' await join('file')
进程通信模式转换
// Electron ipcRenderer.send('message') // Tauri await invoke('message')
系统托盘实现
// Tauri use tauri::{SystemTray, SystemTrayMenu}; let tray = SystemTray::new().with_menu( SystemTrayMenu::new() );
下一步学习建议
- 深入学习 Rust 基础知识
- 熟悉 Tauri 的权限系统
- 了解 WebView 的限制和优化
- 实践 Rust 插件开发
小结
Tauri 2.0 的优势:
- 更小的体积
- 更好的性能
- 更安全的架构
- 更现代的技术栈
转换要点:
- 理解架构差异
- 掌握新的 API
- 适应开发模式
- 注重性能优化
建议:
- 循序渐进
- 保持耐心
- 多看文档
- 多做实验
下一篇文章,我们将深入探讨 Tauri 2.0 的窗口管理和系统集成功能,帮助你更好地理解和使用这些核心特性。
如果觉得这篇文章对你有帮助,别忘了点个赞 👍
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。