用的是墨推直接生成博客推送到git托管
点击前往
前言
做个人博客,很多人会选择Typecho这类动态博客系统。用起来确实很方便,可视化后台写文章,但是随之而来的维护成本也让人头疼。
需要一直维护一台服务器,PHP、MySQL环境不能出问题;伪静态规则、缓存、防刷配置,一旦出故障就要排查很久。文章多了之后数据库查询压力上来,访问速度也会受影响。想要迁移服务器,备份、还原、修改配置,一套流程下来耗费大量时间。
静态博客方案就很好的解决了这个痛点:文章渲染成纯静态HTML,托管在GitHub Pages,不需要自己的服务器长期运行,访问速度快,几乎零运维。
但市面上主流的Hexo、Hugo都是命令行工具,需要本地环境,对于不想折腾命令行的开发者不够友好。我想要一个拥有网页可视化后台,写完文章一键生成静态页面,自动推送到GitHub仓库的工具。
基于这个想法,我开发了墨推 MoPush。
整体实现思路
整体流程非常清晰:
网页后台编写Markdown文章 → 渲染生成完整静态HTML站点 → Git提交推送 → GitHub Pages完成博客上线
用户在网页后台编辑文章,系统完成Markdown渲染,生成整套静态网页资源,通过Git推送到用户自己的GitHub仓库。仓库开启Pages功能之后,博客就可以直接访问。
几个关键设计取舍
1. 采用全量生成,放弃增量构建 一开始考虑做增量构建,只更新改动的文章。但是博客页面之间耦合度很高,首页列表、分类页、标签页、上下篇导航,修改一篇文章会牵连大量页面。 增量构建逻辑复杂,很容易出现页面不同步bug。个人博客体量下,全量生成虽然耗时略高,但逻辑简单稳定,减少大量隐性bug。
2. 图片双模式:本地存储 / CDN图床 文章图片支持两种模式:
• 本地模式:图片随静态文件一同推送进仓库,所有资源全部保存在自己仓库,数据完全自己掌控;
• CDN图床模式:图片上传至图床,仓库体积更小,页面加载速度更好。
3. 预留插件钩子机制 在文章保存、静态文件生成、Git推送的各个节点预留钩子。后续可以扩展功能,例如自动生成文章摘要、主动提交搜索引擎、自定义Markdown短代码等。
开发踩坑记录
坑1:推送覆盖CNAME文件,自定义域名直接失效
GitHub Pages绑定自定义域名,仓库根目录会生成CNAME文件保存域名信息。 最开始我的推送逻辑是清空目标目录,写入全部新静态文件,结果第一次推送直接把CNAME文件删除,博客自定义域名直接404。
解决办法:建立受保护文件白名单。推送前读取仓库原有文件,CNAME、.gitignore、README.md、.nojekyll这类用户自定义文件保留不动,只覆盖程序生成的静态资源。
//伪代码示例 $protectFiles = ['CNAME','.gitignore','README.md','.nojekyll']; foreach ($repoFiles as $file) { if(in_array($file,$protectFiles)){ continue; } //覆盖静态资源 }
坑2:GitHub密钥权限安全问题
最初想使用Personal Access Token推送仓库,但是PAT权限过大,可以操作账号下全部仓库,存在安全隐患。
最终改用Deploy Key:每个用户绑定仓库时,程序生成SSH密钥对。公钥添加到对应仓库的Deploy Key,私钥加密存储服务端。 密钥仅可以操作当前绑定的仓库,就算密钥泄露,影响范围也被限制。
坑3:代码高亮的渲染时机
如果把代码高亮交给前端JS,页面加载完成后才渲染代码块,会出现明显闪烁。 我选择在静态生成阶段就完成代码高亮处理,使用Parsedown扩展,生成HTML的时候直接输出带样式的代码标签,浏览器直接渲染,消除闪烁问题。
当前项目状态
目前核心流程已经跑通:账号登录 → 绑定GitHub仓库 → 后台编辑文章 → 生成静态站点 → Git推送至仓库。
项目目前处于公测打磨阶段,主要用于个人学习实践。 后续规划:
1. 主题模板系统,支持切换不同博客样式
2. 草稿预览,生成临时预览链接
3. 自定义独立页面功能
总结
静态博客并不是技术倒退,而是把动态渲染开销转移到发布时刻。一次构建完成,之后只需要托管静态文件,不用持续维护服务端环境。
对于厌倦服务器运维,想要简单稳定个人博客的开发者,是一个不错的备选方案。



