用 Go/Rust 构建轻量级网页版小工具

在开发个人工具或内部系统时,我们往往追求的是开发速度分发便捷性。如果只是为了做几个输入框和图表,就去折腾 Node.js 环境和复杂的构建工具,显然是“大炮打蚊子”。

对于偏好 GoRust 的开发者,以下方案可以让你只写 HTML/CSS 就能构建出精美的 Web UI,且生成的工具只有一个二进制文件。


核心架构:HTMX + 原子化 CSS

要跳过编译步骤,我们需要改变前端逻辑的实现方式:

  • 交互逻辑:HTMX 它允许你直接在 HTML 标签中定义请求(如 hx-get="/api"),并动态更新页面局部。你不需要写一行 JavaScript,就能实现类似 Ajax 的异步刷新。
  • 视觉样式:Pico.css 或 Tailwind CDN
    • Pico.css:极简主义者的首选。它没有复杂的类名,只要你写标准的语义化 HTML(如 <button><nav>),它就会自动适配出一套高级感十足的 UI。
    • Tailwind Play CDN:如果你离不开 Tailwind 的灵活,可以直接引入官方运行时脚本,无需本地编译。

方案一:Go 语言(极简、高效)

Go 的标准库 net/http 配合 embed 特性,是处理这类需求的最强组合。

代码示例:main.go

package main

import (
	"embed"
	"html/template"
	"net/http"
)

//go:embed index.html
var content embed.FS

func main() {
	tmpl := template.Must(template.ParseFS(content, "index.html"))

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		tmpl.Execute(w, nil)
	})

	// HTMX 接口:只返回 HTML 片段
	http.HandleFunc("/clicked", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("<p>来自 Go 后端的响应:操作成功!</p>"))
	})

	println("服务运行在 http://localhost:8080")
	http.ListenAndServe(":8080", nil)
}

页面示例:index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Go Mini Tool</title>
    <link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
    <script src="https://unpkg.com/htmx.org"></script>
</head>
<body class="container">
    <header>
        <h1>我的轻量级工具</h1>
    </header>
    <main>
        <button hx-post="/clicked" hx-target="#result">
            点击触发后端逻辑
        </button>
        <div id="result">等待操作...</div>
    </main>
</body>
</html>

方案二:Rust 语言(高性能、类型安全)

在 Rust 中,使用 AxumActix-web 配合模板引擎 Askama,可以确保你的 HTML 在编译期就是类型安全的。

tera

推荐组合

  • Axum: 目前最主流、性能卓越的 Web 框架。
  • Maud: 如果你连 .html 文件都不想创建,可以使用 Maud。它是一个宏,允许你直接在 Rust 代码里用 DSL 写 HTML,运行速度极快。

Rust (Maud 示例)

use axum::{response::Html, routing::get, Router};
use maud::{html, DOCTYPE};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(index));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn index() -> Html<String> {
    let markup = html! {
        (DOCTYPE)
        html {
            head {
                link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css";
                title { "Rust Tool" }
            }
            body class="container" {
                h1 { "Rust + Maud 驱动" }
                button { "提交任务" }
            }
        }
    };
    Html(markup.into_string())
}

维度 HTMX + Go/Rust (之前的建议) Leptos (全栈 Rust)
开发语言 后端 Rust/Go,前端 HTML 属性 全栈 Rust (前端也写 Rust)
是否需要编译/打包 完全不需要 (引入 CDN 即可) 必须编译 (需要将 Rust 编译为 WebAssembly)
性能 极佳 (后端渲染) 极致 (WASM 运行速度接近原生)
学习曲线 极低 (懂 HTML 就能上手) 较高 (需要理解 Signals, WASM, 借用检查)
分发方式 单个二进制文件 (含内嵌 HTML) 单个二进制文件 (含内嵌 WASM 资源)
交互复杂度 适合中低交互 (表单、列表) 适合极高交互 (富文本、绘图、复杂仪表盘)

总结

对于“不希望折腾前端工程化”的后端开发者,我的建议是:

  1. UI 库:首选 Pico.css,因为它不需要记忆类名,专注于 HTML 结构即可。
  2. 交互逻辑:拥抱 HTMX,把复杂的逻辑留给熟悉的 Go 或 Rust,让前端回归展示。
  3. 分发方式:利用 Go 的 embed 或 Rust 的宏,将所有资源压入单一执行文件,实现单文件分发,零依赖运行

这种“回归原始”的开发方式,往往能让你找回最初写代码的乐趣。

收藏一下 写的非常