这件事说白了,其实就是“为了买一盘醋,包了一顿饺子”。

之前我碰到了一个特别冷门、也比较难解决的 Bug。Stack Overflow 和 Google 上都翻不出几条真正有用的东西。最后还是硬靠自己一点一点死磕,才终于把问题解决。

问题搞定以后,我第一反应就是要把这个曲折的踩坑经理记录下来。

因为这种坑如果不记下来,过几个月自己都未必还记得当时是怎么想通的;既然都已经受过这份罪了,不把它整理出来,简直有点对不起自己消耗的脑细胞。

但真正的问题很快就来了:

写完了,发哪儿呢?

真正的起点,其实不是“我想建个网站”

我一开始根本没有“我要做个人网站”这种规划。

我的真实想法非常朴素,就是单纯地想找个地方,把那篇 Bug 复盘发出去。

为了这件事,我做了一圈 Research。

国内的平台像博客园、知乎、CSDN,也不是不能发,但总感觉自由度有限,而且听说有些平台不做人,你发上去的内容就不属于你了:一篇本来应该干干净净的技术文章,最后经常会被平台味道包起来,总之不是我想象里那种利利索索的极客博客。

国外的平台像 Medium 或 Blogger,体验确实会轻一点,但本质上还是在别人的地盘上租房子住。你可以装修,但墙不是你的,门牌号也不是你的,哪天平台规则一变,很多东西就不完全由你说了算。

我也不为了最终变现;作为工程师,最后还是很自然地走到了那条老路上:

既然想要 100% 的掌控权,那就自己搭。

而一旦这个念头出来,后面的选择其实就很顺了。静态托管、免费、天然适配 Git 工作流、还能直接跟自己平时的开发习惯接上,基本没有什么比 GitHub Pages 更像“数字自留地”了。

既然要自己搭,那就顺手搭个像样的

在框架选型上,我一开始也看了几家常见选手。

  • Hexo 背后是 Node.js
  • Jekyll 是 GitHub Pages 老牌选手,背后是 Ruby
  • Hugo 则是 Go 生态里出了名的快

经过一番比较,我最终选了 Hugo。

原因非常简单:我看到一个别人的网站,用的就是Hugo,整体是我喜欢的样子,其他technical上的不同,其实在你网站体量做得很小的时候,区别不是非常大。

主题我最后选的是 PaperMod

我挺喜欢它那种克制感:默认样式很干净,没有一上来就把页面做得花里胡哨,文章内容也够靠前。对我这种主要还是想写技术文章、顺便放一点个人页面的人来说,它是个非常好的起点。

如果你也想搭一套一样的,最基础的 Setup 其实就这么几步:

# 1. 安装 Hugo(Mac 环境)
brew install hugo

# 2. 创建网站目录
hugo new site my-blog
cd my-blog
git init

# 3. 用 submodule 引入 PaperMod 主题
git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

这里有个很值得专门提醒一下的小坑:PaperMod 一定要作为 submodule 引进来。

千万别手快直接 git clonethemes/ 里面,然后以为事情结束了。那样你本地看起来是正常的,但后面一旦 push 到 GitHub,很容易因为嵌套仓库的关系把主题目录当成“空壳”处理掉。最后你人还挺淡定地看着 Actions 跑成功了,网站却开始 404,或者直接缺一半样式。别问我为什么对这个坑印象这么深。

这次印象最深的部分,其实是 Vibe Coding 真挺好用

如果把时间拨回几年前,这种项目虽然不算难,但绝对是那种很容易把整个周末都吃掉的东西。

你得先配主题、改 Hugo 配置、想双语怎么做、想部署怎么做、把 GitHub Actions 跑起来、处理自定义域名、调页面样式、处理评论区、处理统计,再顺手解决几个“明明看起来很小但就是很烦”的前端细节。

现在不一样了。

现在有了 Vibe Coding

我自己这次比较深的感受是:AI 真正帮到你的地方,不是“它替你想好了你要做什么”,而是当你的方向已经很明确的时候,它能把大量本来很机械、很碎、很烦的工作快速铺开。

比如这个站,很多东西其实都不是一次写对的,而是我一边想要什么,一边让 AI 帮我试:

  • 双语路由怎么配
  • 中文内容和英文内容怎么配对
  • 语言切换怎么优先跳到当前页面的翻译,而不是傻傻跳首页
  • 首页的背景光晕应该动得多快、多明显
  • 白色主题下颜色不够明显该怎么补
  • 阅读量统计用什么方案,坏了之后怎么换
  • 评论区怎么接、怎么让中英文各自显示对应语言

很多地方都是我们来来回回调了好几轮,甚至十几轮。

比如双语这件事,最后我定下来的约定其实非常简单:

  • 英文站放在根路径 /
  • 中文站放在 /zh/
  • 英文内容文件默认不带后缀
  • 中文翻译文件统一用 .zh.md

也就是像这样:

content/posts/my-post.md
content/posts/my-post.zh.md

虽然vibe coding很省事,但做出来东西也不是一蹴而就的,这个网站不少地方并不是“AI 一次性写了个完美答案”,而更像是我在旁边一直盯着方向,然后不断说:

这个不对,再往左一点。

这个太快了,慢一点。

这个颜色不好看,换一组。

这个交互像磁铁,不像我想要的那种“轻轻推开”的感觉。

这也是我现在越来越喜欢这种工作方式的原因。你不需要自己把每一行实现都亲手敲出来,但你仍然在做设计、在做判断、在定方向。AI 更像一个执行力非常强、而且不嫌你烦的搭档。

双语、部署、域名,一个都没忍住

本来最开始我只是想“有个地方发文章就行”。

但既然都搭到这一步了,脑子里那句危险的话还是冒出来了:

都来了,不如顺手再做完整一点。

然后事情就开始失控了。

1. 双语支持

因为我本来就有中英文切换表达的需求,所以这个站从一开始就不是单语设计。

现在整个站的结构是:

  • 英文站在根路径 /
  • 中文站在 /zh/
  • 文章、搜索页、简历页都是双语思路去配的

技术上看起来只是几行 Hugo 配置,但真正麻烦的其实是那些“边边角角”:菜单要不要双语、搜索页要不要分语言、语言切换是切主页还是切当前页面、评论区语言跟不跟着页面走。这些东西单独看都不大,凑在一起就会决定整个站看起来到底是“真双语”,还是“勉强有两个语言入口”。

2. GitHub Actions 自动部署

部署这块,我也没想走什么复杂路线,直接交给 GitHub Actions。

现在 .github/workflows/gh-pages.yml 里已经配好了 Pages 部署。日常工作流基本就是:

  1. 本地改内容或样式
  2. git add
  3. git commit
  4. git push

剩下的交给 CI/CD 自己跑。

这种体验有个很危险的副作用:你会越来越想改东西。因为每次改动的发布成本都低得离谱,低到有时候你只是突然觉得一句文案不顺眼,也会忍不住顺手修一下。

而且 Hugo 这套静态站的部署链路确实很舒服:构建就是 hugo --gc --minify,产物全在 public/,GitHub Pages 负责托管,Actions 负责发布,整个过程没有什么多余的“运维戏份”。对主要想写内容、顺便享受一点折腾过程的人来说,这种复杂度非常合适。

3. 买域名

本来用 neilmin.github.io 其实已经够用了。

但后来我手痒去域名商那里搜了一下,发现买一个完全属于自己的 .com 域名,一年大概也就十来刀。这个价格实在太容易让人心理防线失守了。花不到一顿饭的钱,给自己在互联网上买一块带名字的地,怎么看都挺划算。

于是就直接拿下了 neilmin.com

说真的,自定义域名这件事对功能没有任何本质提升,但对心情提升极大。你在浏览器里看到那个地址的时候,会很自然地产生一种“这地方真是我自己的”的感觉。

基础跑通之后,最容易上头的就是这些小外挂

网站这种东西,一旦主链路打通,后面最上头的部分往往不是“能不能用”,而是“能不能再顺手加一点小细节”。

然后我就没忍住又折腾了几样。

丝滑的动态光晕背景

如果你现在是用电脑在看这个网站,首页和搜索页的背景里应该能看到几个会动的发光色块。

这个东西不是图片,也不是视频,纯靠 CSS 和一点 JavaScript 撑起来的。我一开始只是想做个 mesh gradient 一样的氛围背景,后来越调越上头,又把鼠标交互也加了进去。

最搞笑的是,这个背景的“手感”其实来回调了很多轮。最早那版动得太机械,后来又一度像磁铁排斥一样乱窜,最后才慢慢调成现在这种更黏一点、更柔和一点的感觉。中间甚至还专门把交互模型换成了更像“泡泡被轻轻推开”的那种写法,用 lerp 去做缓动,再配上更柔和的衰减曲线。你用鼠标去推的时候,它现在应该更像在轻轻拨开几团有点粘滞感的光,而不是在戳三个会弹飞的球。

阅读量统计:从不蒜子到 Vercount

一开始很多人都会用“不蒜子”做访问统计,我最开始也试了。

但这玩意儿现在的稳定性确实有点看心情,时不时就掉链子。后来索性换成了 Vercount

它最让我满意的一点是:对不蒜子的 DOM 结构几乎是 drop-in replacement。

也就是说,原来那套 busuanzi_* 的 HTML ID 你几乎可以不动,很多时候直接把引入的 JS 换掉就能继续跑。对于这种已经接进页面、但你又不想把模板全部推翻重写的场景来说,真的很省事。

Giscus 评论系统

评论区这块,我最后接的是 Giscus

我挺喜欢它的思路:不用自己再额外养一套数据库,底层直接把评论存到 GitHub Discussions 里。对这种本来就以 GitHub 为中心的小站来说,这种方案非常顺手。

而且它和这个站整体也很搭:

  • 不需要单独维护后台
  • 支持暗色模式
  • 可以根据页面语言切换评论组件的界面语言

所以现在你在中文文章页看到的是中文评论区,在英文文章页看到的是英文评论区,这种细节统一起来以后,整个体验就会顺很多。

而且说实话,这种“小而完整”的体验,特别容易让人上头。你本来只是想把评论区接上,最后顺手又会想:那它的语言要不要自动跟着页面走?暗黑模式切换时要不要也一起适配?这种事就是典型的,一旦开始较真,就会一路较真下去。

回头看,这真的是一顿标准的“饺子工程”

最开始我只是想发一篇技术文章。

结果最后变成了:

  • 搭 Hugo
  • 接 PaperMod
  • 配双语
  • 配搜索
  • 配 GitHub Pages
  • 买域名
  • 接统计
  • 接评论区
  • 调背景动画
  • 调交互手感

本来只想买一盘醋,结果最后把整顿饺子都包出来了。

但说实话,我还挺喜欢这种过程的。

一方面它确实解决了一个很现实的问题:我终于有了一个完全属于自己的地方,可以安心发那些我自己真的想写的东西。另一方面,它也让我重新感受到了一种很熟悉的快乐,就是工程师那种“既然都做到这儿了,不如顺手再打磨一下”的快乐。

最后

那篇关于冷门 Bug 的技术文章,现在已经真的发出来了。

而这个网站本身,也算是那篇文章顺手带出来的副产品。

如果你恰好刷到了这篇复盘,欢迎你滑到最下面,用 GitHub 账号登录评论区,给我留一句话。你可以跟我打个招呼,也可以顺手帮我测测这套系统到底稳不稳。

毕竟这个站虽然现在已经挺像样了,但它的出身,说到底还是非常朴素:

我只是想找个地方,好好把一篇值得记下来的文章发出去。