自己写一套博客程序

之前用的是一套很成熟的开源博客程序,用了几年,其实没出过什么毛病。真正让我下决心自己写的,原因挺朴素的:想改的地方,改不动。想动主题,得先读懂人家的模板语法;想加个小功能,得去翻插件源码;碰到一个不合心意的地方,多半只能忍了,或者绕过去。

忍久了就冒出一个念头:我的需求又不多,自己写一套是不是更省事?然后就有了现在这个东西。

选型:能少一个依赖就少一个

不上框架。Node 自带的 http 模块,加一张自己写的路由表,够用了。

数据库一开始用 SQLite:单文件,不用装服务、不用配账号,备份就是复制一个文件,博客这点访问量完全撑得住。后来为了多进程并发(单文件锁在多进程下容易打架),换成了 MySQL——多一个依赖、多一个要维护的服务,换来并发的余量。

模板引擎也是自己写的,语法就是常见的那套双大括号,支持条件、循环、包含子模板。

代价很直接:什么都得自己踩。好处也很直接:不用等上游。想加个字段、改个行为,当天就能改完上线。

还有一个刻意的决定——数据表沿用原来那套的名字和字段。这样从旧站迁数据过来,搬过去就能用,省掉一大堆转换和对不上的麻烦。

结构:三层各管各的

程序分成三块,边界划得比较清楚:

  • 内核:接请求、查数据、渲染、发响应。所有规矩都在这儿。
  • 主题:只管长什么样。模板、CSS、一点 JS,不碰业务。
  • 插件:只管附加功能。评论通知、邮件订阅、友链、对象存储上传,都是插件。

主题可以整套换掉,插件可以随手开关,内核不用动。这三件事要是混在一起,日子久了就没法维护了。

请求进来之后:三层各管各的

请求的路径大概是:浏览器 → CDN → nginx(反代)→ 内核 → 吐出 HTML。静态资源和图片另走对象存储,不占服务器的带宽和磁盘。

钩子:内核留口子,插件往上挂

内核在几个关键位置留了口子,插件挂上去就能介入,分两种:

  • filter:把数据交给你改一改,再往下传。
  • action:通知你「事情发生了」,你做点什么就行,不用管流程。

现在挂着的几个:附件上传时改存到对象存储、评论保存后发通知邮件、正文输出前把链接补成新窗口、页面渲染时插统计代码。

这样加功能基本不用动内核。内核一改,风险是全站的——一个地方没想周全,到处都可能出问题。

钩子:内核留口子,插件往上挂

踩过的坑

挑几个真踩过的:

保存会覆盖。后台保存文章时,如果无条件把所有字段都写一遍,「转草稿」这种只提交一个状态的操作,就会把标题和正文一起清空。后来改成只写请求里明确出现的字段,才算干净。

上传是最大的口子。危险扩展名(html、js、svg、php 之类)一律拒绝,不看后台设置;文件路径必须落在指定目录内,不能靠拼字符串;插件目录只放行静态资源,插件自己的源码一律 404。

外链图片收进自己的域名。评论头像、友链图标这些,与其在安全策略里到处开洞,不如后端代理一下,对外只暴露自己的域名。

渲染得逐字节对齐。因为是从旧站迁过来,正文渲染出来的 HTML 必须跟原来一致——多一个斜杠、少一个空格都可能让版面变形。为此专门写了用例去比对。

缓存分三层。图片、字体这种不会变的,直接缓存一年;CSS 和 JS 必须带版本指纹才给长缓存,不然改了不生效;后台的资源正相反,一点缓存都不给,改完刷新就是新的。

现在的样子

跑了一阵,日常写文章、评论、订阅都稳。

自研这笔账很好算:好处是哪儿都能改、不用求人;代价是安全、性能、兼容性全得自己扛。所以顺手把测试也搭了起来——现在跑一轮有一千多项检查,改代码之前先过一遍。

值不值,看你有多想折腾。只想要个地方写字,现成的程序肯定更快更省心;但你要是想让它长得完全合自己的意,那自己写一遍,说不定反而是最省事的那条路。

本文发布于 ,最近一次编辑于
😊
提交

评论区

共 0 条评论
暂无评论数据