为什么我给自己的主页写了一个构建脚本,而不是用 Hugo
需求其实只有三条
第一,发一个链接给 HR,她点开就能看完我的经历、项目和作品,不需要下载任何东西,也不需要在微信里被拦截。第二,我自己要能持续写东西,写文章的摩擦必须足够低。第三,页面要好看,但不能好看到一眼就知道是套的模板。
这三条里没有一条要求「服务端」。所以静态站是唯一合理的答案 —— 没有数据库要维护,没有证书要续期,托管免费,被人打完也打不挂。
平台约束决定技术选型:以及它是怎么把我上了一课的
一开始我按「要上 Gitee Pages」来做约束核实,规则摆在那儿:仓库必须公开,每次 push 之后要点一次「更新」才生效,地址是 用户名.gitee.io/仓库名/;最要命的是它会按仓库里的文件特征决定用什么引擎编译 —— 部署目录下有 config.toml 之类的配置文件加 content/ 目录就按 Hugo 编译,有 package.json + _config.yml + scaffolds/ 就按 Hexo 编译,其余情况一律丢给 Jekyll。Jekyll 会忽略以 _ 开头的文件,也会改写部分资源路径,所以我的打算是本地构建好只提交产物,并放一个空文件把它挡掉:
dist/
.nojekyll ← 有这个空文件,Jekyll 才会被跳过
index.html
assets/...
一个空文件换掉整个编译不确定性,这笔交易很划算。
然后等我准备去开通这个服务时,发现「服务」菜单里根本没有 Gitee Pages 这一项。查下去的结果不太愉快:官方帮助中心的分类里每一条都标着 「(功能已下线)」,随便打开一个仓库的 /pages 页面写着「因服务维护调整,Gitee Pages 暂停提供服务」,*.gitee.io 全部 404;而官网上那篇介绍文档还挂在那儿,内容停留在下线之前。社区从 2024 年就开始迁移了,只是没人公告。
这件事对我的教训不是「Gitee 不靠谱」,而是:平台的承诺是易耗品,你的产物不该把路径写死在它的承诺上。 好在我一开始就做了两件现在看来很对的事 —— 页面里全部使用相对路径,产物与源码分离并且不依赖平台侧构建。换托管平台要改的只有配置里的一个站点地址字段,页面结构一行没动。如果当时图省事用了需要平台跑 Hugo/Jekyll 的方案,迁移就不是改一行配置,而是把整套构建流程重建一遍。
所以选型依据从「哪个平台更方便」换成了「哪个平台在国内点开最快,而我随时能走」。
为什么不用 Hugo
本机环境是决定性因素:git 2.55 和 Node v24 是现成的,Hugo 和 Go 都没有。为了搭一个个人主页去装一套新的工具链,还要赌平台那一端的构建器版本不比我本地旧 —— 主题用上新特性就构建失败 —— 这是给自己找活干。
Hugo 主题确实好看,但好看的是主题,不是我。用现成主题很难摆脱「一眼模板」的味道,而这恰恰是简历页最不该有的印象。
所以路径是:参考成熟主题的排版语言,规则落到自己的一套 CSS 变量里,构建脚本自己写。零依赖,node tools/build.mjs 一条命令出产物,换机器也不用心跳。
内容和渲染分开
数据全部在 data/*.json,文章在 content/posts/*.md,页面结构在构建脚本里。这意味着以后要做一个本地控制台给我用表单改内容,只需要往这两个目录里写文件,页面长得怎么样完全不用它操心。
data/site.json 站点信息、导航、联系方式
data/resume.json 简历(网页与 A4 打印同一份数据)
data/projects.json 成果展示
data/gallery.json 照片墙相册
content/posts/*.md 文章,构建期渲染成静态 HTML
手机号这类东西直接写在公开页面上会被爬虫永久收走,所以渲染成「点击复制」,值放在 data-copy 属性里,正文文本里没有它。
还没解决的两个问题
图片压缩。2268×4032 的 PNG 原图 9.9MB,直接上站首屏就废了。纯 Node 没有 JPEG 编码器,我拒绝为这件事装原生依赖,打算放到后台里用浏览器 canvas 做。目前的做法是:超标的图构建时直接跳过并警告,宁可相册空着也不拖垮站点。
发布最后一步。原来卡在「push 之后还要人到网页上点一次更新」,我甚至考虑过写脚本模拟登录去点那个按钮 —— 那要在本地存账号凭证,可能撞风控,平台一改版就失效,还有违反服务条款的嫌疑。为省十秒钟背这个债不值。现在平台换了,只要它支持关联仓库自动构建,这一步就从流程里消失了;配置项留空时构建脚本会跳过 sitemap 和 RSS 而不是生成一份指向死域名的文件,这类小护栏比多写一个功能有用。