前言
这肯定是一次非常神奇的经历,在我从事代码这么多年的工作当中,我尝试过很多次搭建自己的个人网站。
在我的潜意识我觉得它非常的简单,而事实是,它确实很简单,但比我想象中的‘简单’要难上很多。
背景
我想了很多个网站的名字,最好的是 mochen.com,很明显这是不太可能的域名。我也想过弄一个好听的拼接词 sumocen.com,看起来很酷吧。
wsmochen.com 这是我最终定下来的网站域名,因为我觉得它对我来说很亲切,拼音翻译过来就是"我是墨尘"。
我之前很喜欢 surmon 博主的博客,现在也很喜欢。是在使用 vue-awesome-swiper 这款插件的过程中知道的,现在这款插件已经 12.8k 的 Star,感谢博主的无私开源。
最开始我有尝试临摹 surmon 的博客来搭建自己的个人网站,他的博客代码是开源的,这个过程可谓是一波三折,因为我想完全由自己写出来,在临摹的过程中我遇到时间、成长、认知上面的多重阻碍。
现在停止临摹,新的开始,我会收集寻找灵感,设定目标,有了我自己喜欢的风格,加上AI的加持,感觉一切都水到渠成,保留了原创的开发风格。
架构
三个端,三个仓库,各自独立部署。
- web - 博客(面向读者)
- manage - 管理后台(面向自己)
- server - 服务端(支撑两端)
web - Nuxt 3 + Tailwind CSS
博客是面向读者的,页面体验和加载速度是第一优先级。Nuxt 3 的 SSR 能力解决了两个核心问题:SEO 友好(搜索引擎能抓到完整内容)和首屏速度(避免了传统 SPA 的白屏闪烁,服务端直出 HTML 能让读者在 JS 还在下载/执行时就能看到内容骨架)。
Tailwind CSS 推荐,以前写样式,一半时间在纠结 class 叫什么名字,container-box-left 这种东西写了不知道多少重名的。Tailwind 直接在 class 里写样式,虽然初看满屏都是 utility class 显得有些杂乱,但用过之后就再也回不去了。而且它天然约束了项目里的间距、颜色、字号,从一定程度上统一了风格。
页面结构是经典的左中右三栏:左侧导航,中间内容区,右侧小组件,同时做了一些细节上的优化:
- 骨架屏过渡,加载完成淡入显示
- 最少 300ms 加载动画,避免闪烁
- Markdown 渲染 + highlight.js 代码高亮 + DOMPurify 防 XSS
manage - Vue 3 + Element Plus + Pinia
管理后台不需要 SEO,也不需要服务端渲染,纯 SPA 就够了。Element Plus 提供了开箱即用的各类组件,做后台很省事。
核心功能就三个:创建文章、图片上传、标签管理。
文章编辑器用的 Vditor,一个 Markdown 编辑器。写文章的时候标题、摘要、分类、标签、封面图都在同一个页面操作,支持 Ctrl+S 保存草稿,也可以直接发布。
图片上传后,后端用 Sharp 自动校正方向、压缩并转成 WebP 格式,上传限制 8MB,输出质量 88%,最大尺寸控制在 1600x1200 以内。常见的 JPG、PNG、WebP、GIF 都支持,也补上了 HEIC/HEIF 的转换兜底;封面图在后台会先做裁切预览,再把最终图片写入文章。
server - NestJS + Prisma + PostgreSQL
对于服务器框架的选择,我做了一番考究,最终选择了 NestJS。不仅是使用它的人多,NestJS 是一种长期思维架构,装饰器和 DI 构造了 NestJS 优雅、易维护的代码风格,强制分层架构模块化(Module)、控制器(Controller)、服务(Service),保证了代码质量,同时它还拥有非常庞大的生态。
Prisma ORM 定义好数据模型,一条命令生成迁移脚本和类型安全的查询客户端,不需要手写 SQL,也不需要担心类型对不上。改个字段,npx prisma migrate dev 就自动生成迁移,开发过程非常丝滑。
API 分了两套:
/api/web/ — 公开接口,不需要登录,给博客前端用
/api/manage/ — 管理接口,需要 JWT,给后台用
还做了接口限流,三档:短时间 3次/秒,中等 20次/10秒,长周期 60次/分钟。
感悟
网站上线后,回味下感觉还挺有意思。不巧的是,对这里不满意,对那里也不满意,功能好像还少点的想法也会跟着冒出来,或许这就是乐趣所在吧。当然最重要的是博客的建立,一种自我表达的方式,一种深度的思考。
网站虽然上线了,但它永远处于‘未完成’的状态,就像我们的人生一样。