使用 Astro 作为 Tauri 的前端
Tauri 通常被描述为“Rust 后端加 Web 前端”的应用框架。它并不要求前端一定使用 React、Vue 或 Svelte,只要前端最终能够提供一个静态目录,或者在开发阶段启动一个兼容的开发服务器,就可以作为 Tauri 的界面。
Astro 很适合内容型应用:页面可以在构建阶段生成,Markdown 可以直接作为内容源,最终产物不需要 Node.js 运行时。本文以一个已经存在的 Tauri 2 项目为例,说明如何把 Astro 接入其中,并继续支持桌面端和 Android 调试。
工作方式
Astro 和 Tauri 的职责可以这样划分:
| 部分 | 负责内容 |
|---|---|
| Astro | 页面、组件、Markdown、CSS 和静态资源 |
| Astro build | 将站点输出到 dist |
| Tauri | 创建窗口、调用 Rust 命令、打包应用 |
| Android 工程 | 将 Tauri 应用编译为 APK |
Tauri 不需要理解 Astro 的组件语法。它只需要知道两个目录:
开发阶段:Astro dev server
生产构建:dist/
项目目录结构
本文示例中,Astro 项目和 Tauri 项目使用同一个仓库根目录。Astro
不是放在另一个嵌套的子目录中,因此 package.json、astro.config.mjs
和 src/ 位于同一级:
Tauri-project/
├── package.json
├── astro.config.mjs
├── tsconfig.json
├── public/
│ └── images/
├── src/
│ ├── pages/
│ │ └── index.astro
│ ├── components/
│ ├── content/
│ ├── config/
│ ├── styles/
│ └── content.config.ts
├── dist/
└── src-tauri/
├── tauri.conf.json
└── src/
├── lib.rs
└── main.rs
这些文件的路径和职责如下:
| 路径 | 作用 |
|---|---|
astro.config.mjs |
Astro 的站点、Markdown 和开发服务器配置 |
src/pages/ |
Astro 页面入口;文件路径会映射为网站路由 |
src/components/ |
可复用的 Astro 组件 |
src/content/ |
Markdown 等内容文件 |
src/styles/ |
全局样式和组件样式 |
public/ |
原样复制到构建产物根目录的静态资源 |
dist/ |
npm run build 生成的静态站点 |
src-tauri/ |
Tauri 的 Rust 代码、权限和应用配置 |
例如,src/pages/about.astro 会生成 /about/ 页面,public/images/avatar.svg 会在构建后对应dist/images/avatar.svg。这里的 src/ 是 Astro 的源码目录,
不是另一个独立的 Node 或 Astro 项目;项目根目录只有一个package.json。
安装依赖
项目应该只在根目录有一个 package.json,包含 Astro 和 Tauri 的依赖。
然后把 package.json 中的脚本改为:
{
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"tauri": "tauri"
}
}
tauri 脚本仍然保留,之后可以使用 npm run tauri 调用 Tauri CLI。
所有命令都应从仓库根目录执行。不要在 src/ 目录中再次执行npm install 或 npm run dev,否则 Astro 可能找不到根目录的
配置和页面。
配置 Astro
根目录下的 astro.config.mjs 可以这样配置:
// @ts-check
import { defineConfig } from "astro/config";
const host = process.env.TAURI_DEV_HOST;
export default defineConfig({
site: process.env.PUBLIC_SITE_URL,
server: {
host: host || false,
port: 1420,
strictPort: true,
},
});
这里有三个关键点:
port: 1420必须和 Tauri 配置中的devUrl端口一致;strictPort: true可以避免端口被自动改写后导致 Tauri 找不到页面;
配置 Tauri
src-tauri/tauri.conf.json 的构建部分应指向 Astro 的开发地址和构建目录:
{
"build": {
"beforeDevCommand": "npm run dev",
"devUrl": "http://localhost:1420",
"beforeBuildCommand": "npm run build",
"frontendDist": "../dist"
}
}
开发时,Tauri 会先执行 npm run dev,然后加载 Astro 开发服务器。构建时,Tauri 会先执行 npm run build,再把 dist 中的静态文件打进应用。
启动桌面端调试
先确认 Astro 单独运行正常:
npm run dev
浏览器打开 http://localhost:1420,确认首页可以访问后,再使用 Tauri 启动:
npm run tauri dev
修改 Astro 页面、组件或 CSS 后,开发服务器会重新构建对应页面,Tauri 窗口通常可以直接看到更新。
生产构建
先单独检查 Astro 静态构建:
npm run build
构建成功后,dist 目录中应包含 index.html 和其他生成页面。接着可以构建 Tauri 应用:
npm run tauri build
Astro 的静态输出有一个重要优点:最终应用不需要在设备上运行 Astro 或 Node.js。页面、样式、脚本和图片会作为应用资源随 Tauri 一起分发。
路由和资源路径
如果页面使用绝对路径,例如:
<img src="/images/avatar.svg" alt="头像" />
资源应放在 Astro 的 public/images/avatar.svg。Astro 构建后会将它复制到 dist/images/avatar.svg。
对于多页面站点,建议让 Astro 生成目录形式的页面:
dist/
├── index.html
├── about/
│ └── index.html
└── archive/
└── index.html
这样既适合静态部署,也适合 Tauri 的本地资源加载。
常见问题
页面显示空白
依次检查:
npm run build是否成功;src-tauri/tauri.conf.json中的frontendDist是否为../dist;devUrl是否和 Astro 的端口一致;- 页面是否依赖服务端 API,而这些 API 在应用内并不存在。
使用 window 导致构建失败
Astro 默认会在构建阶段渲染页面。访问 window、document 或 localStorage 的代码应放在客户端脚本中,或者等页面加载后执行:
<script>
const theme = localStorage.getItem("theme");
document.documentElement.dataset.theme = theme ?? "light";
</script>
不要在 Astro 组件的顶层直接执行依赖浏览器环境的代码。
需要调用 Rust 命令
Astro 页面中的客户端脚本仍然可以使用 Tauri API:
import { invoke } from "@tauri-apps/api/core";
const result = await invoke<string>("greet", { name: "Astro + Tauri" });
console.log(result);
这段代码应在浏览器端脚本中运行,而不是在 Astro 的构建阶段运行。Rust 命令则继续在 src-tauri/src/lib.rs 或相关 Rust 文件中定义。
总结
把 Astro 用作 Tauri 前端的核心并不复杂:
- 让 Astro 负责页面和内容;
- 让开发服务器监听 Tauri 使用的端口;
- 让
frontendDist指向 Astro 的dist; - 将需要浏览器环境的代码放进客户端脚本;
- 通过 Tauri API 和 Rust 命令连接本地能力。
这种组合特别适合文章、笔记、文档和个人知识库类应用:Astro 提供内容组织和静态生成能力,Tauri 则负责把同一套前端包装成桌面端和移动端应用。