这个站点最初只有一个 index.html,CSS 和 JavaScript 全部内联。单页阶段这样最省事,但一旦要加文章、复用导航和页脚,单文件就会变成维护负担。v0.2 的目标不是改版,而是在视觉零变化的前提下把工程结构立起来。

为什么先拆资源

单文件的问题不在于体积,而在于改动的连带风险:

  • 改一处颜色要全文件搜索
  • 导航、页脚无法在多个页面复用
  • 浏览器无法单独缓存 CSS 和 JavaScript
  • 任何一次改动都会让整个 HTML 的哈希变化

拆分后,样式按职责分成设计令牌、基础、组件、首页、工具类五层,脚本独立为 main.js,页面骨架与内容分离。

构建器做了什么

构建器 scripts/build.py 只依赖 Python 标准库,负责四件事:

  1. 读取 templates/base.html 与页面模板,渲染 partials
  2. 合并 assets/css/*.css 与 assets/js/*.js
  3. 按内容计算 8 位哈希,生成 site.<hash>.css / site.<hash>.js
  4. 对 site/ 做一致性校验,供 CI 与提交前检查

核心命令只有两条:

python scripts/build.py
python scripts/build.py --check

--check 会把模板重新渲染一遍,与 site/ 中的产物逐字节比较。只要有人手改了产物而没改源文件,校验就会失败。

资源哈希与缓存

静态站点最容易被忽略的问题是缓存。如果 CSS 文件名固定,Cloudflare 或浏览器可能继续使用旧版本,表现为「代码更新了,页面样式没变」。

构建期哈希解决了这个问题:

版本输出文件缓存行为
v1site.a1b2c3d4.css可长期缓存
v2site.e5f6a7b8.css新 URL,立即生效

HTML 本身保持不缓存,资源文件带哈希后可以放心设置长缓存。

如何验证没有改坏

拆分前后分别用 Playwright 在 1440、768、375 三档宽度和亮暗主题下截图,再做像素比对。结果:

  • 1440 亮色与暗色:逐像素完全一致
  • 375 亮色与暗色:最大通道差 2,属于抗锯齿噪声

这比「看起来差不多」可靠得多。视觉重构最怕的不是大改,而是某个间距、圆角或阴影在拆分时悄悄变了。

下一步

v0.3 会在这套结构上加入文章系统:Markdown 源文件、归档页、文章页、目录与上下篇。因为模板和构建器已经就位,新增页面只需要增加模板与渲染函数,不再动首页。

发布链路保持不变:构建产物仍然提交入库,服务器 git pull 后由 deploy.sh 同步到 Nginx。