Electron 开发者的 Tauri 2.0 实战指南:快速入门与思维转换

原创
01/14 19:13
阅读数 45

作为一名经验丰富的 Electron 开发者,当你第一次接触 Tauri 时,可能会感到有些不适应。本文将帮助你快速理解 Tauri 2.0 的核心概念,并通过实际案例完成从 Electron 到 Tauri 的思维转换。

架构对比

Electron 的架构

在 Electron 中,我们习惯了以下架构:

Electron 应用
├── 主进程 (Main Process)
│   ├── 窗口管理
│   ├── 系统API调用
│   └── IPC 通信
└── 渲染进程 (Renderer Process)
    ├── 前端界面
    ├── 渲染逻辑
    └── IPC 通信

主要特点:

  1. 基于 Chromium 和 Node.js
  2. 主进程和渲染进程分离
  3. 通过 IPC 进行进程间通信
  4. 直接使用 Node.js API

Tauri 2.0 的架构

Tauri 采用了不同的架构方式:

Tauri 应用
├── 核心进程 (Rust Core)
│   ├── 窗口管理
│   ├── 系统API调用
│   └── 命令系统
└── 前端界面 (WebView)
    ├── 界面渲染
    ├── 业务逻辑
    └── Tauri API

主要特点:

  1. 基于系统 WebView
  2. Rust 核心进程
  3. 统一的命令系统
  4. 更安全的权限控制

开发环境搭建

前置依赖

# 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 -->



  <title>Hello Electron</title>


  <h1>Hello Electron!</h1>


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: &amp;str) -&gt; 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 调试

  1. 主进程调试
{
  "scripts": {
    "start": "electron .",
    "debug": "electron --inspect=5858 ."
  }
}
  1. 渲染进程调试
  • 使用 Chrome DevTools
  • 快捷键:Ctrl+Shift+I (Windows/Linux) 或 Cmd+Option+I (macOS)

Tauri 调试

  1. 前端调试
# 启动开发服务器
npm run dev
  1. 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(
        &amp;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) =&gt; {
  return 'data'
})

// 渲染进程
const result = await ipcRenderer.invoke('get-data')

Tauri:

// Rust
#[tauri::command]
fn get_data() -&gt; 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() -&gt; 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

主要优势:

  1. 更小的安装包体积
  2. 更低的内存占用
  3. 更快的启动速度
  4. 更好的系统集成

开发建议

  1. 渐进式迁移

    • 先熟悉 Tauri 的基本概念
    • 从小功能开始迁移
    • 保持代码结构清晰
  2. 充分利用 Rust 优势

    • 性能密集型操作放在 Rust 端
    • 使用 Rust 的并发特性
    • 注意内存安全
  3. 前端代码复用

    • UI 代码可以大部分复用
    • 抽象化平台相关的 API
    • 使用适配器模式
  4. 安全性考虑

    • 使用 Tauri 的权限系统
    • 谨慎开放系统 API
    • 做好输入验证

常见问题解决

  1. Node.js API 替代方案

    // Electron
    const path = require('path')
    path.join(__dirname, 'file')
    
    // Tauri
    import { join } from '@tauri-apps/api/path'
    await join('file')
    
  2. 进程通信模式转换

    // Electron
    ipcRenderer.send('message')
    
    // Tauri
    await invoke('message')
    
  3. 系统托盘实现

    // Tauri
    use tauri::{SystemTray, SystemTrayMenu};
    
    let tray = SystemTray::new().with_menu(
        SystemTrayMenu::new()
    );
    

下一步学习建议

  1. 深入学习 Rust 基础知识
  2. 熟悉 Tauri 的权限系统
  3. 了解 WebView 的限制和优化
  4. 实践 Rust 插件开发

小结

  1. Tauri 2.0 的优势:

    • 更小的体积
    • 更好的性能
    • 更安全的架构
    • 更现代的技术栈
  2. 转换要点:

    • 理解架构差异
    • 掌握新的 API
    • 适应开发模式
    • 注重性能优化
  3. 建议:

    • 循序渐进
    • 保持耐心
    • 多看文档
    • 多做实验

下一篇文章,我们将深入探讨 Tauri 2.0 的窗口管理和系统集成功能,帮助你更好地理解和使用这些核心特性。

如果觉得这篇文章对你有帮助,别忘了点个赞 👍

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部