






















一个用 Go 编写的静态站点生成器,最初作为 zhurongshuo.com 的 Hugo 替代品而生,现已成长为一个 AI 友好、内置双语翻译流水线的通用 SSG。
huan 将 Markdown + 单个 YAML 配置 + Go 模板编译为静态网站,其输出可与 Hugo 逐字节对比验证(在参照站点上 99.7% 字节一致,SEO 与 AI 两个维度 0 差异)。它是一个零运行时依赖的单一二进制文件,使用与 Hugo 同源的 goldmark 引擎,将 CJK 内容视为一等公民,并把部署、发布、LLM 翻译都集成在同一个 CLI 中。
huan 是一个用 Go 编写的静态站点生成器。它最初的目标是完全替代 Hugo 来构建 zhurongshuo.com——并带有一条硬性要求:每一个 HTML、RSS、sitemap、搜索索引的字节都必须可复现、可与 Hugo 输出对比验证。在该等价目标基本达成后,huan 已扩展为一个 AI 优先的通用 SSG。
核心特征:
huan.yaml 作为配置(YAML,而非 TOML)llms.txt、内容 API(/api/{section}.json)、每页 Markdown 镜像——为 LLM 爬虫和 AI 消费者而设计,而不仅是 SEO 爬虫.zh-cn/.en 边车文件渲染为完整的本地化站点,并内置一个翻译插件用本地 LLM 补齐缺口Deployer(Cloudflare)和 Translator(Qwen3)内置并共享同一个注册表huan release 跨平台打包,huan deploy 通过直连 API 发布到 Cloudflare,并支持 tag 推送触发 GitHub Actions 自动发版hugo serve 的开发体验:HTTP 服务器 + fsnotify 文件监听 + LiveReload WebSocket,亚秒级浏览器刷新huan 不是 Hugo 的 drop-in 替换。模板迁移一次即可,此后由 huan 接管整个构建流水线。
Hugo 很优秀,但对于单一站点的需求而言,它携带了大量用不上的表面积。huan 存在的理由:
hasCJKLanguage、字数统计、摘要长度、标题 ID 生成默认就考虑中文。llms.txt、JSON 内容 API、每页 Markdown 镜像,让 AI agent 和 LLM 爬虫获得干净、结构化的内容访问。.en.md 边车文件(手写或 LLM 生成),huan 即产出带 parity 审计的本地化站点。scripts/diff-build.sh)将 huan 输出与 Hugo 逐字节对比;2026/2032(99.7%)字节一致基线作为回归门禁被持续跟踪。huan serve 原子重建(重建期间无 404),保存 Markdown 文件后约 1 秒内刷新浏览器。| 命令 | 用途 |
|---|---|
huan build | 构建站点到 publishDir |
huan serve | 启动带文件监听 + LiveReload 的开发服务器 |
huan new <kind>/<path> | 从 archetypes/<kind>.md 脚手架内容(多 archetype) |
huan sync gallery | 为新图片脚手架 content/gallery/<name>.md |
huan toc | 为 books / practices / products 生成 TOC markdown |
huan export | 导出内容为 CSV 归档(通过 i18n collator 复现 zh_CN 排序) |
huan translate qwen3 | 通过本地 Qwen3 LLM 将源 markdown 翻译为 .en.md 边车文件 |
huan translate status | 报告所有源文件的翻译状态(已缓存 / 过期 / 缺失) |
huan translate audit | 对运行中的 serve 审计 zh/en parity 与逐页语言正确性 |
huan deploy cloudflare {pages,r2,worker} | 部署到 Cloudflare Pages / R2 / Workers |
huan plugin {list,info} | 查看已注册的插件 |
huan release | 交叉编译 + 打包 + 校验和到 release/<version>/ |
huan version / env / config / list | 自省命令 |
huan serve 参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--port | 1313 | 监听端口 |
--bind | 127.0.0.1 | 绑定地址(支持 0.0.0.0、::) |
-D / --buildDrafts | false | 包含草稿内容 |
--disableLiveReload | false | 关闭浏览器自动刷新 |
--disableWatch | false | 不监听文件变化 |
--debounce | 400ms | 文件变化防抖延迟 |
unsafe: true + 可配置 typographer;标题 ID 与 Hugo 算法对齐(处理 CJK + 中文标点 + HTML 实体)audio、img;可扩展注册表html/template,约 40 个 Hugo 兼容函数(urlize、safeHTML、markdownify、Scratch、partial、where、sort、index、len,以及数学/字符串/路径辅助函数等)/page/N/,/page/1/ 重定向到 /sitemap.xml、search.jsonllms.txt、/api/{section}.json、每页 index.md 镜像tdewolff/minify 压缩 HTML / CSS / JS / JSON / SVG / XMLrename(2) 换入——重建期间继续服务旧内容,无 404atomic.Bool busy + pending 标志)——连续编辑合并为一次重建alert 消息广播;开发服务器继续运行publishDir从源码(目前推荐):
git clone https://github.com/iannil/huan.git
cd huan
go build -o huan ./cmd/huan
通过 go install:
go install github.com/iannil/huan/cmd/huan@latest
从发布 tarball(无需 Go 工具链):
# 1. 从 /release/<version>/ 或 GitHub Releases 下载 huan_<version>_<os>_<arch>.tar.gz
# 2. 校验 checksum(可选但推荐):
shasum -a 256 -c huan_<version>_checksums.txt
# 3. 解压:
tar xzf huan_<version>_darwin_arm64.tar.gz # 产出 ./huan、./LICENSE、./README*.md
# 4. 移入 PATH:
sudo mv huan /usr/local/bin/
huan version # 确认:"huan <version> (<git sha>)"
Windows 用户:下载 huan_<version>_windows_amd64.zip 并解压 huan.exe。
go install / go build 路径需要 Go 1.26+;预编译 tarball 无 Go 依赖。
huan.yamlbaseURL: "https://example.com/"
title: "My Site"
languageCode: "zh-cn"
publishDir: "public"
paginate: 10
hasCJKLanguage: true
summaryLength: 120
markup:
goldmark:
renderer:
unsafe: true
extensions:
typographer: false
my-site/
├── huan.yaml
├── content/
│ ├── posts/
│ │ └── 2026/
│ │ └── 06/
│ │ └── hello.md # → /posts/2026/06/hello/
│ │ └── hello.en.md # → /en/posts/2026/06/hello/(可选边车)
│ └── _index.md # 首页
├── layouts/ # Go html/templates
│ ├── _default/
│ │ ├── single.html
│ │ └── list.html
│ └── partials/
└── static/ # 原样拷贝
# 构建到 publishDir(默认 ./public)
./huan build
# 启动开发服务器(默认 http://localhost:1313)
./huan serve
# 常见 serve 变体
./huan serve --port 8080 --bind 0.0.0.0 -D
./huan serve --disableLiveReload # 无 WS,仅静态文件
./huan serve --disableWatch # 文件变化时不重建
./scripts/diff-build.sh # 完整重建 + 与 Hugo 字节 diff
./scripts/diff-summary.sh # 仅结构化报告
./scripts/diff-patterns.sh # 按模式归类 diff
hello.md)。hello.en.md——手写,或由翻译插件生成。huan 会将其渲染到本地化的 URL 前缀下(如 /en/...)。huan translate qwen3 遍历每个源文件,通过 Ollama HTTP API 调用本地 Qwen3 模型,写出 .en.md 边车。它是增量的(按 source-hash 缓存)、结构感知的(校验 markdown chunk 结构往返一致)、可观测的(--progress-every 在长任务中打印吞吐 + ETA)。huan translate audit 爬取运行中的 huan serve,枚举 zh 与 en sitemap,报告缺失/孤立边车以及逐页语言正确性(英文页里残留未翻译中文,或反之)。只读,绝不修改内容。# 翻译所有新增或变更的内容(增量)
./huan translate qwen3
# 预览将翻译哪些文件,不调用 LLM
./huan translate qwen3 --dry-run
# 翻译单个文件,强制重跑
./huan translate qwen3 --file posts/2026/06/hello.md --force
# 报告已缓存 / 过期 / 缺失的翻译状态
./huan translate status
# 对运行中的开发服务器审计 zh/en parity
./huan serve &
./huan translate audit --fail # 存在任何 parity/语言问题则非零退出
Translator 能力是统一插件系统的一部分,因此可在 internal/translate/<provider>/ 下新增其他 provider(云端 API、其他本地模型),无需触碰构建流水线。
huan/
├── cmd/
│ ├── huan/ # CLI 入口(main.go + 各命令文件)
│ └── equiv-check/ # 等价检查辅助二进制
├── internal/
│ ├── build/ # BuildSite 核心 + 原子换入
│ ├── config/ # huan.yaml 解析
│ ├── content/ # 内容加载 + tree + frontmatter
│ ├── markdown/ # goldmark 流水线
│ ├── shortcode/ # audio / img
│ ├── template/ # html/template 加载 + funcmap
│ ├── taxonomy/ # tags / categories
│ ├── pagination/
│ ├── output/ # writer + canonify + minify + AI 输出
│ ├── i18n/ # 消息包 + collator + audit + langdetect
│ ├── translate/ # Translator 能力 + qwen3 provider
│ ├── plugin/ # 统一插件注册表
│ ├── deploy/ # Deployer 能力 + cloudflare provider
│ ├── release/ # 交叉编译 + 打包
│ ├── equiv/ # Hugo 等价检查
│ ├── observability/ # 结构化日志 / 追踪
│ ├── version/ # 构建版本信息
│ └── serve/ # HTTP 服务器 + 监听 + LiveReload
├── scripts/ # diff-build.sh + diff-summary.sh + diff-patterns.*
├── docs/ # 见 docs/INDEX.md
├── memory/ # 项目记忆(MEMORY.md + 每日笔记)
├── huan.yaml # 示例配置
├── go.mod / go.sum
└── CLAUDE.md # 贡献者指南(中文)
MIT © 2026 iannil
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。