使用 Rust+Tauri 重构 API 模拟服务器 - 项目结构
一、项目结构
gui-test
├── public
│ ├── tauri.svg
│ └── vite.svg
├── src
│ ├── assets
│ │ └── react.svg
│ ├── App.css
│ ├── App.tsx
│ ├── main.tsx
│ └── vite-env.d.ts
├── src-tauri
│ ├── capabilities
│ │ └── default.json
│ ├── gen
│ │ └── schemas
│ │ ├── acl-manifests.json
│ │ ├── capabilities.json
│ │ ├── desktop-schema.json
│ │ └── windows-schema.json
│ ├── icons
│ ├── src
│ │ ├── lib.rs
│ │ └── main.rs
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ └── tauri.conf.json
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
从项目结构看,分为:
- 前端部分(React + TypeScript + Vite)
- 后端部分(Rust)
- 配置文件
1. 项目整体结构
gui-test/
├── public/ # 前端静态资源目录
├── src/ # 前端源代码目录(React + TypeScript)
├── src-tauri/ # 后端Rust代码目录
├── 配置文件 # 各种构建和配置文件
2. public/ - 前端静态资源目录
public/tauri.svg
- 作用:Tauri官方Logo图标
- 功能:在网页上显示Tauri标志
- 使用场景:可以用于网站Header、关于页面等展示品牌标识
public/vite.svg
- 作用:Vite构建工具的Logo图标
- 功能:展示Vite框架标识
- 使用场景:通常在开发环境中使用
3. src/ - 前端源代码目录
src/assets/react.svg
- 作用:React框架的SVG图标
- 功能:在应用中显示React Logo
- 使用场景:用于演示React组件加载
src/App.css
- 作用:主应用组件的样式文件
- 功能:定义App组件的CSS样式
- 示例:
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafb);
}
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
...
src/App.tsx
- 作用:React主应用组件
- 功能:应用的根组件,定义整个应用的结构和布局
- 示例:
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import { invoke } from "@tauri-apps/api/core";
import "./App.css";
function App() {
const [greetMsg, setGreetMsg] = useState("");
const [name, setName] = useState("");
async function greet() {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
setGreetMsg(await invoke("greet", { name }));
}
return (
<main className="container">
<h1>Welcome to Tauri + React</h1>
<div className="row">
<a href="https://vite.dev" target="_blank">
<img src="/vite.svg" className="logo vite" alt="Vite logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img src="/tauri.svg" className="logo tauri" alt="Tauri logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<p>Click on the Tauri, Vite, and React logos to learn more.</p>
<form
className="row"
onSubmit={(e) => {
e.preventDefault();
greet();
}}
>
<input
id="greet-input"
onChange={(e) => setName(e.currentTarget.value)}
placeholder="Enter a name..."
/>
<button type="submit">Greet</button>
</form>
<p>{greetMsg}</p>
</main>
);
}
export default App;
src/main.tsx
- 作用:React应用的入口文件
- 功能:将App组件渲染到DOM中
- 示例:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
src/vite-env.d.ts
- 作用:Vite环境的TypeScript类型声明文件
- 功能:为Vite提供类型支持,避免编译错误
- 内容:主要声明Vite的环境变量类型
4. src-tauri/ - Rust后端代码目录
src-tauri/capabilities/default.json
- 作用:定义Tauri应用的能力和权限
- 功能:控制前端可以调用哪些Rust函数、访问哪些系统资源
- 示例:
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default"
]
}
src-tauri/gen/schemas/ - 生成的schema文件
acl-manifests.json
- 作用:访问控制清单(ACL)的schema
- 功能:定义访问控制规则的结构
capabilities.json
- 作用:能力配置的schema
- 功能:定义应用能力的JSON结构
desktop-schema.json
- 作用:桌面应用相关的schema
- 功能:定义桌面API的数据结构
windows-schema.json
- 作用:窗口管理的schema
- 功能:定义窗口配置的数据结构
src-tauri/icons/ - 应用图标目录
-
作用:存放应用的各种尺寸图标
-
功能:用于Windows、macOS、Linux系统的应用图标
-
包含:
-
icon.icns(macOS图标) -
icon.ico(Windows图标) -
icon.png(Linux/通用图标) -
32x32.png,128x128.png等不同尺寸图标
-
src-tauri/src/lib.rs
- 作用:Rust库文件(可选项)
- 功能:定义可复用的Rust函数和模块
- 示例:
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
src-tauri/src/main.rs
- 作用:Rust主程序入口
- 功能:启动Tauri应用,注册命令,配置窗口
- 示例:
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
gui_test_lib::run()
}
src-tauri/Cargo.toml
- 作用:Rust项目的配置文件
- 功能:定义依赖、元数据、构建配置
- 示例:
[package]
name = "gui-test"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
# The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "gui_test_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
src-tauri/Cargo.lock
- 作用:Rust依赖锁文件
- 功能:确保每次构建使用相同版本的依赖
- 自动生成:不要手动修改
src-tauri/build.rs
- 作用:Rust构建脚本
- 功能:在编译前执行自定义构建逻辑
- 示例:
fn main() {
tauri_build::build()
}
src-tauri/tauri.conf.json
- 作用:Tauri应用的主配置文件
- 功能:配置应用窗口、权限、图标、打包等
- 示例:
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "gui-test",
"version": "0.1.0",
"identifier": "com.lkpcomputer.gui-test",
"build": {
"beforeDevCommand": "npm run dev",
"devUrl": "http://localhost:1420",
"beforeBuildCommand": "npm run build",
"frontendDist": "../dist"
},
"app": {
"windows": [
{
"title": "gui-test",
"width": 800,
"height": 600
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": [],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
5. 配置文件
README.md
- 作用:项目说明文档
- 功能:描述项目的功能、安装、使用方法
6. 构建
index.html
- 作用:HTML入口文件
- 功能:引入React应用,设置根节点
- 示例:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri + React + Typescript</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
package.json
- 作用:npm项目配置文件
- 功能:定义依赖、脚本、项目信息
- 示例:
{
"name": "gui-test",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"react": "^19.1.0",
"react-dom": "^19.1.0",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-opener": "^2"
},
"devDependencies": {
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^4.6.0",
"typescript": "~5.8.3",
"vite": "^7.0.4",
"@tauri-apps/cli": "^2"
}
}
package-lock.json
- 作用:npm依赖锁文件
- 功能:确保依赖版本一致性
- 自动生成:不要手动修改
tsconfig.json
- 作用:TypeScript配置文件
- 功能:配置TypeScript编译选项
- 示例:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
tsconfig.node.json
- 作用:Node.js环境的TypeScript配置
- 功能:配置Vite工具链的TypeScript
- 示例:
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
vite.config.ts
- 作用:Vite构建工具的配置文件
- 功能:配置开发服务器、构建、插件等
- 示例:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// @ts-expect-error process is a nodejs global
const host = process.env.TAURI_DEV_HOST;
// https://vite.dev/config/
export default defineConfig(async () => ({
plugins: [react()],
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
//
// 1. prevent Vite from obscuring rust errors
clearScreen: false,
// 2. tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true,
host: host || false,
hmr: host
? {
protocol: "ws",
host,
port: 1421,
}
: undefined,
watch: {
// 3. tell Vite to ignore watching `src-tauri`
ignored: ["**/src-tauri/**"],
},
},
}));
二、文件功能总结
1. 前端开发
| 文件/目录 | 功能 | 何时修改 |
|---|---|---|
src/App.tsx | 主应用组件 | 添加页面布局、组件 |
src/main.tsx | 应用入口 | 通常不需要修改 |
src/App.css | 应用样式 | 添加自定义样式 |
src/assets/ | 静态资源 | 添加图片、字体等 |
package.json | npm依赖 | 添加前端依赖 |
2. 后端开发
| 文件/目录 | 功能 | 何时修改 |
|---|---|---|
src-tauri/src/main.rs | Rust入口文件 | 注册Tauri命令 |
src-tauri/src/lib.rs | Rust库文件 | 定义可复用函数 |
src-tauri/Cargo.toml | Rust依赖 | 添加Rust依赖 |
src-tauri/capabilities/ | 权限配置 | 添加新权限 |
3. 配置与构建
| 文件 | 功能 | 何时修改 |
|---|---|---|
src-tauri/tauri.conf.json | Tauri配置 | 修改窗口、打包设置 |
vite.config.ts | Vite配置 | 修改开发服务器、构建选项 |
tsconfig.json | TypeScript配置 | 修改编译选项 |
package.json | npm脚本 | 添加自定义脚本 |
三、常用命令
# 开发模式
npm run tauri dev
# 构建应用
npm run tauri build