把个人站从「魔改模板」改成「薄启动器」

我把这个站点的底层换成了 al-folio v1 的薄启动器架构。换句话说:站点仓库不再拥有任何布局、样式和前端脚本,运行时全部由版本化的 gem 提供。

这不是审美问题,是一次故障率的重新分配。

改之前:模板即运行时

传统做法是把主题仓库整个 fork 下来,然后直接改 _layouts/、_includes/、_sass/。好处是灵活,代价是:

  • 每次升级上游都要手动 merge,冲突几乎必然出现在你最不想动的地方;
  • 你的 fork 里到底有多少是「上游的」,多少是「你自己的」,三个月后没人说得清;
  • 主题的一个 CSS 变量改名,能让你的站点样式静默失效,而错误信息是「看起来有点歪」。

改之后:站点只管三件事

薄启动器的边界很硬,仓库里只允许存在这些东西:

  1. 内容 —— _posts/、_projects/、_news/、_data/;
  2. 配置 —— _config.yml 与 Gemfile,两者必须一致;
  3. 接线 —— 在 _config.yml 里声明用哪些插件、在 Gemfile 里锁定版本。

运行时归 gem。想改布局?不改,先找拥有它的那个 gem;确实需要本地覆盖时,允许,但会被记录下来(al-folio upgrade overrides audit),不会变成没人知道的历史包袱。

最贵的部分:静默失败

这个架构里有一个必须记住的坑——特性静默失败:

一个特性要生效,需要同时满足三件事:gem 已加载、开关已打开、页面已声明接入。 任何一件不满足,Liquid 标签会输出一个空字符串,不报错、不警告。

所以「我配置了功能但页面上没有」,绝大多数情况下不是 bug,是三件事里有一件没做。排查顺序应该是固定的:

gem 在 Gemfile 和 _config.yml 里都出现了吗?
→ 配置里的 feature flag 打开了吗?
→ 这一页的 front matter 里接入了吗?

第二个坑是 Gemfile 和 _config.yml 是两张必须对齐的清单。只在一边出现的插件是惰性的——加载了,但什么也不做。

代价

不是白拿的:

  • 想改主题行为,得去插件仓库提 PR,本地无法「快速试一下」;
  • 升级从「merge 冲突」变成了「读 changelog」,但 changelog 读起来比 merge 冲突舒服得多;
  • 多了一层间接:出问题时得先判断问题属于内容层还是运行时层。

对个人站来说,这笔交易是划算的。我的内容迭代频率远高于主题定制频率,把迭代快的部分留在手里、把稳定的部分交给版本化发布,是正确的方向。

怎么确认自己没越界

仓库里有一条自动化检查(npm run lint:style-contract),它会直接拒绝以下路径的存在:

_layouts/   _includes/   _sass/   _scripts/   assets/tailwind/   assets/webfonts/

CI 挂了就是越界了,不用靠自觉。




Enjoy Reading This Article?

Here are some more articles you might like to read next: