Tauri 2.0 + Alpine.js 起步笔记(零构建方案)

核心目标:避开 Node.js / npm / Vite 等复杂前端工具链,专注 Rust 后端的系统级功能(托盘、硬件读取、网络通信),快速跑通"从简单起步"的 MVP(最小可行性产品)。

1. 为什么选这个组合?

  • Tauri 2.0:提供原生系统托盘、窗口管理、安全的后端通信桥接。
  • Alpine.js :仅需引入一个 <script> 标签(15KB),提供类似 Vue 的响应式指令(x-data、x-model),无需构建步骤。
  • 纯原生 HTML/CSS/JS:零学习成本,熟悉 HTML 即可上手,完美避开前端工程化陷阱。

2. 环境准备

  • Rust :已安装并配置好 cargo。
  • Node.js :仅用于安装 Tauri CLI(后续开发中不需要用它构建前端)。也可以安装 cargo-tauri 纯 Rust 命令行工具。

3. 项目创建过程

3.1 初始化项目

使用 npm 创建 Tauri 应用(选择 Vanilla 模板,即原生 HTML/CSS/JS):

bash 复制代码
npm create tauri-app@latest
# 按提示输入项目名(如 it-asset)
# 选择"Vanilla" (HTML/CSS/JS) 模板
# 选择 TypeScript 或 JavaScript 均可,JavaScript 更直接
cd it-asset
npm install

3.2 配置 Tauri(去掉 Vite 构建步骤)

打开 src-tauri/tauri.conf.json,修改 build 部分,让其直接指向静态文件目录,不依赖任何 beforeDevCommand:

json 复制代码
{
  "build": {
    "beforeDevCommand": "",
    "beforeBuildCommand": "",
    "devUrl": "http://localhost:1420",
    "frontendDist": "../src"
  }
}

注意:如果不使用 devUrl,也可以配置 "devUrl" 指向一个本地静态服务器,但为了方便,直接将 frontendDist 指向 ../src 目录(或您存放 HTML 的目录)。

3.3 引入 Alpine.js

在 src/index.html 的 <head> 中引入 CDN(或下载到本地):

html 复制代码
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>

4. Rust 后端:实现系统托盘

编辑 src-tauri/src/lib.rs:

rust 复制代码
use tauri::{
    menu::{Menu, MenuItem},
    tray::TrayIconBuilder,
    Manager,
};

#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .setup(|app| {
            // 创建托盘菜单
            let quit_i = MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?;
            let show_i = MenuItem::with_id(app, "show", "显示主界面", true, None::<&str>)?;
            let menu = Menu::with_items(app, &[&show_i, &quit_i])?;

            // 构建托盘图标
            let _tray = TrayIconBuilder::new()
                .icon(app.default_window_icon().unwrap().clone())
                .menu(&menu)
                .on_menu_event(|app, event| match event.id.as_ref() {
                    "quit" => app.exit(0),
                    "show" => {
                        if let Some(window) = app.get_webview_window("main") {
                            let _ = window.show();
                            let _ = window.set_focus();
                        }
                    }
                    _ => {}
                })
                .build(app)?;

            Ok(())
        })
        .invoke_handler(tauri::generate_handler![greet, get_gpu_info])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

注 :这里用到的 get_gpu_info 就是我之前用 windows crate 写好的函数。

5. 前端:简单登录界面(Alpine.js)

在 src/index.html 中,使用 Alpine.js 实现登录逻辑:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>资产登记工具</title>
    <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
<body>
    <div x-data="{ username: '', password: '', loading: false, error: '', gpuList: [] }">
        <!-- 登录表单 -->
        <div x-show="!username">
            <input type="text" x-model="username" placeholder="用户名">
            <input type="password" x-model="password" placeholder="密码">
            <button @click="login()" :disabled="loading">登录</button>
            <div x-text="error"></div>
        </div>

        <!-- 登录成功后展示 GPU 信息 -->
        <div x-show="username">
            <h1>欢迎,<span x-text="username"></span></h1>
            <button @click="fetchGpu()">读取显卡信息</button>
            <ul>
                <template x-for="gpu in gpuList" :key="gpu">
                    <li x-text="gpu"></li>
                </template>
            </ul>
        </div>
    </div>

    <script>
        const { invoke } = window.__TAURI__.core;

        // 登录函数
        async function login() {
            this.loading = true;
            this.error = '';
            try {
                // 假设 Rust 后端有 validate_user 命令
                const res = await invoke('greet', { name: this.username });
                console.log(res);
                // 登录成功,隐藏登录框,显示主内容
                this.loading = false;
            } catch (e) {
                this.error = e;
                this.loading = false;
            }
        }

        // 读取显卡函数
        async function fetchGpu() {
            try {
                // 调用 Rust 端的 get_gpu_info
                this.gpuList = await invoke('get_gpu_info');
            } catch (e) {
                this.error = e;
            }
        }
    </script>
</body>
</html>

6. 运行与调试

bash 复制代码
# 在项目根目录下运行(无需 npm run build)
npm run tauri dev

Tauri 会自动编译 Rust 后端,并启动原生窗口加载 src/index.html。系统托盘图标会在右下角出现,右键即可点击"显示主界面"或"退出"。

7. 平滑升级路线(关键)

  • 起步阶段(当前):Alpine.js + 原生 HTML,快速跑通PC信息读取、登录、托盘。
  • 升级阶段(类 QQ 需求出现时) :
    1. 将 index.html 改名为 App.vue。
    2. 将 x-data 换成 Vue 3 的 <script setup>。
    3. 将 CDN 引入的 Alpine.js 替换为 npm install vue naive-ui。
    4. Rust 后端代码和托盘逻辑完全不需要改动,直接无缝衔接。

总结:先用 Alpine.js 把核心业务逻辑(硬件读取、托盘)跑通,把最复杂、最耗时的 Rust 部分搞定。等到界面交互需求变得极其复杂时,再引入 Vue 3 和 Naive UI 来完善视觉效果,这样既能实现快速起步,又能保证未来架构的平滑演进。

复制代码
相关推荐
gopher951120 小时前
RUST:序列化与反序列化 serde + derive 详解
开发语言·后端·rust
遇码1 天前
流式调用中途断连别直接报错:瞬态故障识别、退避重试与中文根因诊断的搭建方法
大数据·人工智能·ai·rust·数据分析·大模型·agent
DongQiShanRen1 天前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
alwaysrun2 天前
Web之wasm-pack详解
前端·rust·web·wasm
DongQiShanRen2 天前
六根硬件映射(下):物理闭环五步法,抽一条已实装的看
大数据·jvm·人工智能·算法·rust·哈希算法·集成学习
Zenova EdgeOS2 天前
Rust TUI 实战:用 ratatui 构建工业边缘终端界面
开发语言·后端·rust·工业网关
遇码2 天前
不用转场引擎做幻灯片转场:相机滑动、黑场淡入与真全屏的完整做法
人工智能·数码相机·ai·rust·大模型·agent
lpfasd1232 天前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
Flynt2 天前
我把真实的 ES 查询怼到 7059 星的 Rust 搜索引擎上:1366/1369 的兼容承诺,裂了 3 个缝
elasticsearch·搜索引擎·rust
小杍随笔2 天前
egui 0.37 升级实录:卡顿修复与5倍性能回退
windows·rust·egui