4

无服务器动态博客系统Dolan:从设想到现实

 1 year ago
source link: https://mk1.io/posts/hey-dolan
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

无服务器动态博客系统Dolan:从设想到现实

 2022.12.06 2022.12.06 开发 3779

本站最早于 2020 年建立。当时正值网课时期,我就想着搭建一个博客记录一下自己的编程 / 学习过程。一路磕磕绊绊,尝试了多种不同的博客系统:

  1. 免费的 WordPress 部署平台(三蛋host),不过其国内访问速度实在不尽人意,承诺SLA为0%,同时还在网站中强制添加广告,这换谁不跑路啊;
  2. Hexo,一个静态博客生成器,目前使用人数十分庞大,同时有丰富的插件,是一个比较理想的博客系统。但是Hexo的坑实在是太多了,经常碰到因为Node版本过高 / 过低引起的问题虽然用一个fnm就能解决,同时生成速度在插件多了之后直线下滑,完全无法接受,遂弃用;
  3. Gridea,一个国人做的带GUI静态博客系统,好用,但是可拓展性不高,主题也不是很丰富,用了一段时间后也抛弃了;
  4. Hugo,一个用Go编写的静态网站生成器,生成速度很快,同时也具有插件系统与强大的自定义功能,是我使用时间最长的博客系统。

使用Hugo搭建的博客是存活时间最长的。我一共尝试了两个主题:MemE,以及自己移植的Tony。这套配置的易用性极高,同时高度可定制化,生成速度也十分令人满意。但是人心不足蛇吞象,有了一个能用的博客,没地方折腾了,怎么办呢?首先想到的一个优化点就是在线编辑文章。在本地 / 云端编辑固然好,还能实时预览,但难免受到开发环境的影响。

有一个轻量级的解决方案是以HexoPlusPlusWexagonalQexo等为代表的在线编辑器(不是开发环境)。这一类项目的特点是基于Github API无服务器,通过前端的富文本预览,然后再利用Github API上传博客源文件,从而模拟出一个在线编辑文章的环境,配合上集成部署实时生成网页,能够满足极大部分下的使用场景。不过,它们的适配对象都是Hexo,Hugo怎么办呢??理论上,在这些项目上添加支持也不难,但CYF和Abudu写的代码确实屎山质量不高,难不成自己再造一个轮子???

好吧,确实去造轮子了() 既然造了轮子,那我们就造个大的,直接造个博客系统罢!

由于我们要做的是一个无服务器的博客系统,由于运行环境的限制(诸如性能、FS),我们无法做到上传主题、实时更改主题、从模板渲染等操作。同时,我们最好做到前后端分离,让每个部分各司其职,发挥最高的效能:比如后台就没必要和API捆绑在一起,可以独立部署;前端也如此。那我们的项目大体结构如下:

  1. API,提供数据支持。部署在Serverless上。
  2. 后台,提供管理页面。静态网页,部署在哪都行。
  3. 前端,用户访问界面。理论上可以是一个SPA,也可以进行服务端渲染,这个看自己有没有SEO需求了。

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.jsondeno.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,这个没啥好说的

如何使用呢?

目前文档在https://dolan.js.org,大家可以先看看


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK