项目结构 #

一、整体目录结构 #

1.1 完整结构 #

text
my-tauri-app/
├── src/                        # 前端源码目录
│   ├── assets/                # 静态资源
│   │   └── logo.svg
│   ├── components/            # 组件目录
│   │   ├── Header.tsx
│   │   ├── Footer.tsx
│   │   └── Sidebar.tsx
│   ├── hooks/                 # 自定义 Hooks
│   │   └── useTauri.ts
│   ├── pages/                 # 页面组件
│   │   ├── Home.tsx
│   │   └── Settings.tsx
│   ├── services/              # 服务层
│   │   └── api.ts
│   ├── types/                 # 类型定义
│   │   └── index.ts
│   ├── utils/                 # 工具函数
│   │   └── helpers.ts
│   ├── App.tsx                # 主组件
│   ├── App.css                # 主样式
│   ├── main.tsx               # 入口文件
│   └── vite-env.d.ts          # Vite 类型
│
├── src-tauri/                 # Tauri 后端目录
│   ├── icons/                 # 应用图标
│   │   ├── 32x32.png
│   │   ├── 128x128.png
│   │   ├── 128x128@2x.png
│   │   ├── icon.icns          # macOS 图标
│   │   └── icon.ico           # Windows 图标
│   ├── src/                   # Rust 源码
│   │   ├── commands/          # 命令模块
│   │   │   ├── mod.rs
│   │   │   ├── file.rs
│   │   │   └── system.rs
│   │   ├── models/            # 数据模型
│   │   │   ├── mod.rs
│   │   │   └── user.rs
│   │   ├── utils/             # 工具模块
│   │   │   ├── mod.rs
│   │   │   └── error.rs
│   │   ├── lib.rs             # 库入口
│   │   └── main.rs            # 主入口
│   ├── Cargo.toml             # Rust 配置
│   ├── Cargo.lock             # 依赖锁定
│   ├── tauri.conf.json        # Tauri 配置
│   ├── capabilities/          # 权限配置
│   │   └── default.json
│   └── build.rs               # 构建脚本
│
├── public/                    # 公共资源
│   └── favicon.ico
│
├── .vscode/                   # VS Code 配置
│   ├── settings.json
│   ├── launch.json
│   └── extensions.json
│
├── index.html                 # HTML 模板
├── package.json               # 项目配置
├── pnpm-lock.yaml            # 依赖锁定
├── tsconfig.json             # TypeScript 配置
├── tsconfig.node.json        # Node TypeScript 配置
└── vite.config.ts            # Vite 配置

二、前端目录详解 #

2.1 src 目录 #

text
src/
├── assets/            # 静态资源
│   ├── images/       # 图片
│   ├── fonts/        # 字体
│   └── styles/       # 全局样式
│
├── components/        # 可复用组件
│   ├── common/       # 通用组件
│   │   ├── Button.tsx
│   │   ├── Input.tsx
│   │   └── Modal.tsx
│   └── layout/       # 布局组件
│       ├── Header.tsx
│       ├── Footer.tsx
│       └── Sidebar.tsx
│
├── hooks/             # 自定义 Hooks
│   ├── useTauri.ts   # Tauri 相关 Hooks
│   └── useStore.ts   # 状态管理 Hooks
│
├── pages/             # 页面组件
│   ├── Home.tsx
│   ├── Settings.tsx
│   └── About.tsx
│
├── services/          # 服务层
│   ├── api.ts        # API 调用
│   └── storage.ts    # 存储服务
│
├── types/             # TypeScript 类型
│   ├── index.ts      # 导出所有类型
│   ├── api.ts        # API 类型
│   └── models.ts     # 数据模型类型
│
├── utils/             # 工具函数
│   ├── format.ts     # 格式化工具
│   ├── validate.ts   # 验证工具
│   └── constants.ts  # 常量定义
│
├── App.tsx            # 根组件
├── main.tsx           # 应用入口
└── App.css            # 全局样式

2.2 组件示例 #

tsx
// src/components/common/Button.tsx
import { ButtonHTMLAttributes, ReactNode } from 'react';
import './Button.css';

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
    variant?: 'primary' | 'secondary' | 'danger';
    children: ReactNode;
}

export function Button({ variant = 'primary', children, ...props }: ButtonProps) {
    return (
        <button className={`btn btn-${variant}`} {...props}>
            {children}
        </button>
    );
}

2.3 服务层示例 #

typescript
// src/services/api.ts
import { invoke } from '@tauri-apps/api/core';

export const api = {
    async getFiles(path: string) {
        return invoke<string[]>('get_files', { path });
    },

    async readFile(path: string) {
        return invoke<string>('read_file', { path });
    },

    async writeFile(path: string, content: string) {
        return invoke<void>('write_file', { path, content });
    },
};

三、后端目录详解 #

3.1 src-tauri/src 目录 #

text
src-tauri/src/
├── commands/          # 命令模块
│   ├── mod.rs        # 模块导出
│   ├── file.rs       # 文件操作命令
│   ├── system.rs     # 系统信息命令
│   └── window.rs     # 窗口操作命令
│
├── models/            # 数据模型
│   ├── mod.rs
│   ├── config.rs     # 配置模型
│   └── user.rs       # 用户模型
│
├── utils/             # 工具模块
│   ├── mod.rs
│   ├── error.rs      # 错误处理
│   └── path.rs       # 路径工具
│
├── lib.rs             # 库入口
└── main.rs            # 主入口

3.2 模块组织 #

rust
// src-tauri/src/lib.rs
mod commands;
mod models;
mod utils;

use commands::{file, system, window};

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_shell::init())
        .invoke_handler(tauri::generate_handler![
            file::read_file,
            file::write_file,
            system::get_info,
            window::resize,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
rust
// src-tauri/src/commands/mod.rs
pub mod file;
pub mod system;
pub mod window;
rust
// src-tauri/src/commands/file.rs
use std::fs;
use std::path::PathBuf;

#[tauri::command]
pub fn read_file(path: String) -> Result<String, String> {
    fs::read_to_string(&path)
        .map_err(|e| format!("Failed to read file: {}", e))
}

#[tauri::command]
pub fn write_file(path: String, content: String) -> Result<(), String> {
    fs::write(&path, content)
        .map_err(|e| format!("Failed to write file: {}", e))
}

3.3 错误处理 #

rust
// src-tauri/src/utils/error.rs
use serde::Serialize;

#[derive(Debug, Serialize)]
pub struct AppError {
    pub code: String,
    pub message: String,
}

impl From<std::io::Error> for AppError {
    fn from(error: std::io::Error) -> Self {
        AppError {
            code: "IO_ERROR".to_string(),
            message: error.to_string(),
        }
    }
}

impl From<serde_json::Error> for AppError {
    fn from(error: serde_json::Error) -> Self {
        AppError {
            code: "JSON_ERROR".to_string(),
            message: error.to_string(),
        }
    }
}

四、配置文件详解 #

4.1 tauri.conf.json #

json
{
    "$schema": "https://schema.tauri.app/config/2",
    "productName": "my-tauri-app",
    "version": "0.1.0",
    "identifier": "com.mycompany.myapp",
    "build": {
        "beforeDevCommand": "pnpm dev",
        "devUrl": "http://localhost:1420",
        "beforeBuildCommand": "pnpm build",
        "frontendDist": "../dist"
    },
    "app": {
        "withGlobalTauri": true,
        "windows": [
            {
                "title": "My Tauri App",
                "width": 800,
                "height": 600,
                "minWidth": 400,
                "minHeight": 300,
                "resizable": true,
                "fullscreen": false,
                "center": true
            }
        ],
        "security": {
            "csp": null
        },
        "trayIcon": {
            "iconPath": "icons/icon.png",
            "iconAsTemplate": true
        }
    },
    "bundle": {
        "active": true,
        "targets": "all",
        "icon": [
            "icons/32x32.png",
            "icons/128x128.png",
            "icons/128x128@2x.png",
            "icons/icon.icns",
            "icons/icon.ico"
        ],
        "windows": {
            "certificateThumbprint": null,
            "digestAlgorithm": "sha256",
            "timestampUrl": ""
        },
        "macOS": {
            "minimumSystemVersion": "10.13"
        }
    },
    "plugins": {}
}

4.2 Cargo.toml #

toml
[package]
name = "my-tauri-app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = ["tray-icon"] }
tauri-plugin-shell = "2"
tauri-plugin-dialog = "2"
tauri-plugin-fs = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }
anyhow = "1"
thiserror = "1"

[dev-dependencies]
tauri = { version = "2", features = ["test"] }

[features]
default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]

[profile.release]
panic = "abort"
codegen-units = 1
lto = true
opt-level = "s"
strip = true

4.3 package.json #

json
{
    "name": "my-tauri-app",
    "version": "0.1.0",
    "private": true,
    "type": "module",
    "scripts": {
        "dev": "vite",
        "build": "tsc && vite build",
        "preview": "vite preview",
        "tauri": "tauri",
        "tauri:dev": "tauri dev",
        "tauri:build": "tauri build"
    },
    "dependencies": {
        "@tauri-apps/api": "^2.0.0",
        "@tauri-apps/plugin-dialog": "^2.0.0",
        "@tauri-apps/plugin-fs": "^2.0.0",
        "@tauri-apps/plugin-shell": "^2.0.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
    },
    "devDependencies": {
        "@tauri-apps/cli": "^2.0.0",
        "@types/react": "^18.2.0",
        "@types/react-dom": "^18.2.0",
        "@vitejs/plugin-react": "^4.0.0",
        "typescript": "^5.0.0",
        "vite": "^5.0.0"
    }
}

五、权限配置 #

5.1 capabilities 目录 #

text
src-tauri/capabilities/
├── default.json       # 默认权限
└── admin.json         # 管理员权限

5.2 权限配置示例 #

json
// src-tauri/capabilities/default.json
{
    "$schema": "https://schema.tauri.app/config/2/capability",
    "identifier": "default",
    "description": "Default capabilities for the app",
    "windows": ["main"],
    "permissions": [
        "core:default",
        "shell:allow-open",
        "dialog:allow-open",
        "dialog:allow-save",
        "fs:allow-read-text-file",
        "fs:allow-write-text-file"
    ]
}

六、最佳实践 #

6.1 目录组织原则 #

text
原则一:按功能模块组织
├── commands/    # 按功能划分命令
├── models/      # 数据模型集中管理
└── utils/       # 工具函数独立模块

原则二:前后端对应
src/
├── services/    # 对应后端 commands
└── types/       # 对应后端 models

原则三:配置集中管理
├── tauri.conf.json    # Tauri 配置
├── Cargo.toml         # Rust 配置
└── package.json       # 前端配置

6.2 命名规范 #

类型 规范 示例
Rust 文件 snake_case file_system.rs
Rust 函数 snake_case read_file
TypeScript 文件 PascalCase Button.tsx
TypeScript 函数 camelCase handleClick
CSS 类名 kebab-case btn-primary
常量 SCREAMING_SNAKE_CASE MAX_SIZE

6.3 模块导出 #

rust
// 使用 mod.rs 统一导出
// src-tauri/src/commands/mod.rs
mod file;
mod system;
mod window;

pub use file::*;
pub use system::*;
pub use window::*;

七、环境区分 #

7.1 开发环境配置 #

typescript
// src/config/index.ts
const isDev = import.meta.env.DEV;

export const config = {
    apiUrl: isDev ? 'http://localhost:3000' : 'https://api.example.com',
    debug: isDev,
};

7.2 构建配置 #

rust
// 条件编译
#[cfg(debug_assertions)]
const DEBUG_MODE: bool = true;

#[cfg(not(debug_assertions))]
const DEBUG_MODE: bool = false;

八、总结 #

8.1 核心要点 #

要点 说明
前端目录 src/ 目录,标准前端项目结构
后端目录 src-tauri/src/ 目录,Rust 模块化组织
配置文件 tauri.conf.json 为核心配置
权限配置 capabilities/ 目录管理权限

8.2 下一步 #

现在你已经了解了 Tauri 项目结构,接下来让我们学习 架构设计,深入理解 Tauri 的工作原理!

最后更新:2026-03-28