共 0 条
在开发个人工具或内部系统时,我们往往追求的是开发速度和分发便捷性。如果只是为了做几个输入框和图表,就去折腾 Node.js 环境和复杂的构建工具,显然是“大炮打蚊子”。
对于偏好 Go 或 Rust 的开发者,以下方案可以让你只写 HTML/CSS 就能构建出精美的 Web UI,且生成的工具只有一个二进制文件。
要跳过编译步骤,我们需要改变前端逻辑的实现方式:
hx-get="/api"),并动态更新页面局部。你不需要写一行 JavaScript,就能实现类似 Ajax 的异步刷新。<button>、<nav>),它就会自动适配出一套高级感十足的 UI。Go 的标准库 net/http 配合 embed 特性,是处理这类需求的最强组合。
main.gogopackage 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.htmlhtml
在 Rust 中,使用 Axum 或 Actix-web 配合模板引擎 Askama,可以确保你的 HTML 在编译期就是类型安全的。
tera
.html 文件都不想创建,可以使用 Maud。它是一个宏,允许你直接在 Rust 代码里用 DSL 写 HTML,运行速度极快。rust
| 维度 | HTMX + Go/Rust (之前的建议) | Leptos (全栈 Rust) |
|---|---|---|
| 开发语言 | 后端 Rust/Go,前端 HTML 属性 | 全栈 Rust (前端也写 Rust) |
| 是否需要编译/打包 | 完全不需要 (引入 CDN 即可) | 必须编译 (需要将 Rust 编译为 WebAssembly) |
| 性能 | 极佳 (后端渲染) | 极致 (WASM 运行速度接近原生) |
| 学习曲线 | 极低 (懂 HTML 就能上手) | 较高 (需要理解 Signals, WASM, 借用检查) |
| 分发方式 | 单个二进制文件 (含内嵌 HTML) | 单个二进制文件 (含内嵌 WASM 资源) |
| 交互复杂度 | 适合中低交互 (表单、列表) | 适合极高交互 (富文本、绘图、复杂仪表盘) |
对于“不希望折腾前端工程化”的后端开发者,我的建议是:
embed 或 Rust 的宏,将所有资源压入单一执行文件,实现单文件分发,零依赖运行。这是一份为你准备的博客大纲。它避开了传统的 Vue 路线,专注于 2026 年最适合 Go 开发者的**“现代、轻量、直白”**的技术栈。
作为一名 Gopher,我们习惯了 Go 的简洁、高效和单二进制文件部署。但在做小项目(如:机场 DNS 检测工具、自动化运维面板)时,传统的前端框架(Vue/React)往往显得太重:node_modules 巨肥、打包流程复杂、前后端通信还要写一堆逻辑。
2026 年,前端开发已经进入了“回归自然”的时代。如果你想用 Go 做后端,前端怎么选最“直白”?
Go + HTMX + Tailwind CSS + DaisyUIGo + Svelte 5Runes 语法比 React 简单得多,代码量极少,非常适合追求极致响应速度的工具。Go + React + Shadcn UI传统的开发模式是:
前端发送 JSON -> 后端解析 JSON -> 后端返回 JSON -> 前端渲染 DOM。
HTMX 模式:
前端请求片段 -> 后端直接返回 HTML 片段 -> 浏览器自动替换。
代码直观对比: 在 Go 后端,你只需要一个简单的 Handler:
go
既然不用 Vue,2026 年我们有更好的选择:
| 组件库 | 配合方案 | 评价 |
|---|---|---|
| DaisyUI | Tailwind CSS / HTMX | 最推荐。纯 CSS,不需要 JavaScript。一个 class="btn" 搞定一切。 |
| Shadcn UI | React | 审美巅峰,代码直接拷贝进项目,自由度 100%。 |
| Shoelace | 任意框架 / 原生 HTML | 基于 Web Components,像使用原生标签 <sl-button> 一样简单。 |
在做“机场 DNS 检测”时,最核心的需求是:坏了就切。
在 2026 年,利用 Go 的并发特性配合 Cloudflare API,你可以轻松实现自动化高可用:
net.DialTimeout 每 30s 巡检入口 IP 端口。cloudflare-go 库,动态更新 DNS 解析记录。alpinejs
npm 都不用装。<!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>
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())
}
func handleCheck(w http.ResponseWriter, r *http.Request) {
// 模拟 DNS 检测逻辑
result := "8.138.111.22:30741 - 20ms"
// 直接返回 HTML 片段,前端 HTMX 会自动插入到指定位置
fmt.Fprintf(w, "<div class='badge badge-success'>%s</div>", result)
}