









为啥要写一个新的博客系统呢?这篇文章会介绍我的心路历程(bushi
本站最早于 2020 年建立。当时正值网课时期,我就想着搭建一个博客记录一下自己的编程 / 学习过程。一路磕磕绊绊,尝试了多种不同的博客系统:
使用 Hugo 搭建的博客是存活时间最长的。我一共尝试了两个主题:MemE,以及自己移植的 Tony。这套配置的易用性极高,同时高度可定制化,生成速度也十分令人满意。但是 人心不足蛇吞象,有了一个能用的博客,没地方折腾了,怎么办呢?首先想到的一个优化点就是在线编辑文章。在本地 / 云端编辑固然好,还能实时预览,但难免受到开发环境的影响。
有一个轻量级的解决方案是以 HexoPlusPlus、Wexagonal、Qexo 等为代表的在线编辑器(不是开发环境)。这一类项目的特点是 基于 Github API、无服务器,通过前端的富文本预览,然后再利用 Github API 上传博客源文件,从而模拟出一个在线编辑文章的环境,配合上集成部署实时生成网页,能够满足极大部分下的使用场景。不过,它们的适配对象都是 Hexo,Hugo 怎么办呢??理论上,在这些项目上添加支持也不难,但 CYF 和 Abudu 写的代码确实 屎山 质量不高,难不成自己再造一个轮子???
好吧,确实去造轮子了() 既然造了轮子,那我们就造个大的,直接造个博客系统罢!
由于我们要做的是一个无服务器的博客系统,由于运行环境的限制(诸如性能、FS),我们无法做到上传主题、实时更改主题、从模板渲染等操作。同时,我们最好做到前后端分离,让每个部分各司其职,发挥最高的效能:比如后台就没必要和 API 捆绑在一起,可以独立部署;前端也如此。那我们的项目大体结构如下:
API 最初的技术栈是 Node(Koa),打算部署在 Vercel 上。但是 Vercel 的 Node 运行时速度实在感人,常常超时,遂放弃。
后面我了解到 Deno 背后的公司 Deno Land Inc. 推出了一个在线部署服务,叫做 Deno Deploy,可以将 Deno 项目部署到云端,同时节点众多,访问速度理想;其又针对 Deno 进行了大量的优化,性能极高。于是,API 的技术栈就定为了 Deno(Oak)。
这里插一个题外话,Oak 是一个受到 Koa 启发而创建的 Deno HTTP 框架,二者 API 基本相同,可以毫不费力地把 Koa 项目迁移过去。
随后是后台。后台的开发过程稍显曲折,最开始的技术栈是 Vue3 + Quasar,但是 Quasar 的 API 稍显不足,许多功能都需要自己手动实现。后面看到抖音开源了一个 SemiUI,说实话,挺漂亮的,于是捣鼓了很久,把完成了一半的后台迁移到了 React。技术栈为:React + SemiUI + UnoCSS。
最后,是前端。写前端我的第一反应是使用一个 SSR 框架,即 Nuxt / Next,但 Next 貌似支持的 Serverless 平台并不丰富,同时 Nuxt3 声称基于 Nitro 原生支持多平台(其中就包括 Deno Deploy)。卧槽这不得给他冲爆,技术栈为 Nuxt3,移植了一个 hugo-theme-meme。
当然,前端并非只能使用我做的这个 dolan-client-meme。由于其本质只是从 API 获取数据并渲染(这也是为什么它叫做 client 而不是 theme 的原因),因此任何人都能够做自己的 client。
再插个嘴:目前 Nuxt3 和 Nitro 对 Deno Deploy 的支持并没有在文档中体现出来,不过 Nitro 已经有了对它的初步支持。我发起了一个 PR(目前已经合并)来修复一些 bug,但目前包含这个 Commit 的版本还没发布,因此我自己先发布了一个包(@so1ve/nitropack)暂时用着,同时做了一些黑魔法,见 dolan-client-meme/deno-fix.ts。
众所周知,开发初期搭建项目结构是最搞人心态的一件事了…… 不过好在 Deno 所需的配置并不多,最多就是 import_map.json、deno.jsonc 两个配置文件。同时 Oak 也是一个很轻量级的框架,因此主要的目录结构如下:
│ .env│ .gitignore│ config .ts│ deno .jsonc│ deno .lock│ import_map .json│ LICENSE│ README .md├─── .vscode├───src│ ├───protected_routes .ts│ ├───server .ts│ └───unprotected_routes .ts│└───────controller ├───lib │ └───init_values ├───middleware ├───types └───utils
其中两个 *_routes.ts 结尾的文件是路由文件,分为需要登录 / 不需要登录的两组路由。
后台的 UI 前面已经说过选择了 SemiUI,迎面而来的还有另一个问题:Markdown 编辑器选什么呢?我考虑了以下几个编辑器:
后面两个首先出局,for-editor 界面古早而且很久没更新,react-markdown-editor 倒是挺活跃,不过它的功能不多而且不能通过插件扩展功能,于是放弃。
为什么最后选择了 Milkdown 而不是 ByteMD 呢?嗯我也不太清楚为什么,到后面想重构一下换成 ByteMD 发现工作量挺大的,于是搁置了() 主要原因是 ByteMD 默认会对 HTML 内容进行序列化,无法在文章中直接插入 HTML,但是 Milkdown@7 则支持插入 HTML。
然后是配置编辑器 / MD 第二编辑器,Monaco Editor,这个没啥好说的
TODO
目前文档在 https://dolan.js.org,大家可以先看看
TODO
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。