将单页应用(SPA)嵌入到AXUM应用中
本章我们将讨论如何把单页应用(SPA)嵌入到AXUM二进制文件中。
目标
我们的目标是把一个使用VUE3构建的SPA嵌入到AXUM二进制文件中。
依赖
[dependencies]
tokio = { version = "1", features = ["full"] }
axum = { version = "0.7" }
serde = { version = "1", features = ["derive"] }
chrono = { version = "0.4", features = ["serde"] }
rust-embed = "8.5"
mime_guess = "2"
Rust 代码
资源模块
资源结构体
#[derive(Embed)]
#[folder = "dist/"]
pub struct Assets;
我们的资源结构体将把 dist/
目录里面的资源嵌入到二进制文件中。
注意:为了避免编译错误,请手动在项目根目录下创建
dist
目录。等编写好SPA之后,会自动生成该目录和资源文件
静态文件处理
pub async fn static_handler(uri: Uri) ...
首页渲染
pub async fn index_html() -> Response {
match Assets::get(INDEX_HTML) {
Some(content) => Html(content.data).into_response(),
None => not_found().await,
}
}
- 如果静态资源
index.html
存在,则返回该文件的内容 - 否则,渲染
not_found()
404错误
pub async fn not_found() -> Response {
(StatusCode::NOT_FOUND, "404").into_response()
}
- 返回
StatusCode::NOT_FOUND
响应 - 内容为
404
。你可以写详细点,比如:你请求的资源不存在
主函数
#[tokio::main]
async fn main() {
let tcp_listener = TcpListener::bind("0.0.0.0:9527").await.unwrap();
let app = Router::new()
.route("/now", get(now_handler))
.fallback(asset::static_handler);
axum::serve(tcp_listener, app).await.unwrap();
}
路由处理函数
async fn now_handler() -> String {
Local::now().format("%Y-%m-%d %H:%M:%S").to_string()
}
知识简单的返回当前时间。
前端
创建前端项目
# 创建项目
yarn create vite spa-ui --template vue-ts
cd spa-ui
# 安装依赖
yarn
# 安装tailwindcss
# 参见官方文档 https://tailwindcss.com/docs/guides/vite#vue
# 安装dayjs
yarn add dayjs
创建组件
<!-- spa-ui/src/components/Now.vue -->
<script setup lang="ts">
import dayjs from "dayjs";
import { onMounted, ref } from "vue";
const remoteNow = ref<string>("正在获取");
const loadData = () => {
fetch("/now", {
method: "GET",
})
.then((r) => r.text())
.then((r) => (remoteNow.value = r));
};
onMounted(() => {
loadData();
});
</script>
<template>
<ul>
<li>服务器时间:{{ remoteNow }}</li>
<li>客户端时间:{{ dayjs().format("YYYY-MM-DD HH:mm:ss") }}</li>
</ul>
</template>
<!-- spa-ui/src/App.vue -->
<script setup lang="ts">
import Now from "./components/Now.vue";
</script>
<template>
<div
class="my-6 w-96 mx-auto border rounded-md shadow-md bg-gradient-to-br from-sky-50 to-sky-100"
>
<Now class="space-y-3 p-6" />
</div>
</template>
# 在spa-ui目录下进行
rm -rf ../dist && yarn build --outDir ../dist
至此,我们的SPA已经嵌入的AXUM二进制文件中了,只需要发布、部署一个 cargo build --release
生成的二进制文件即可,无需额外发布、部署SPA页面和文件。
本章代码位于spa
目录。