WSの小屋

Hello, I'm wsvaio 👋

热爱技术,热爱生活,用一个博客记录所思所学。

关于我

我是一名前端开发者,常年游走在 JavaScript / TypeScript 的世界里。从最初写 jQuery 写到怀疑人生,到后来拥抱 Vue、React,再到现在沉迷于各种构建工具和 CSS 原子化方案——技术栈在变,但那股折腾的劲儿一直没变。

我相信「工具是为人服务的」,所以我不追新技术本身,而是追新技术背后解决问题的思路。一个好的工程师不只是写出能跑的代码,更应该理解每一行代码为什么存在、有没有更好的替代方案。

工作之外,我喜欢把学到的东西写成文章。一方面是沉淀自己的知识体系,另一方面也希望能帮到正在踩同样坑的人。如果某天你在搜索引擎里搜到我的某篇文章,然后解决了你的问题,那这篇文章就值了。

这个博客的故事

这个博客不是一蹴而就的,中间经历了好几次大的重构。

最早用的是现成的博客框架,改改主题就上线了。但用着用着总觉得不顺手——想要的功能没有,不想要的功能一堆。于是决定自己从零搭一个。

为什么又造了一个轮子?

市面上已经有很多优秀的博客系统了:Hexo、Hugo、VuePress、VitePress……每个都很好用,但我有一些自己的执念:

  • 我想要全栈能力——不只是静态生成,还要有评论、统计、后台管理
  • 我想要数据库驱动——文章存数据库,可以随时编辑,而不是一堆 Markdown 文件
  • 我想要最新的技术栈——Nuxt 4、Drizzle ORM、UnoCSS,用着最前沿的工具
  • 我想要完全可控——每一行代码都是自己写的,出了问题不用翻文档猜

所以,这个博客本质上是一个「技术练手项目」+「个人表达空间」的结合体。它不追求功能大而全,但追求每一处细节都让自己满意。

技术选型

整个项目追求「现代」和「简洁」,没有引入太多重型依赖:

  • Nuxt 4 — 全栈 Vue 框架,SSR + 文件路由 + 自动导入。选它是因为 Vue 的开发体验足够好,而 Nuxt 在 SSR、路由、SEO 方面的开箱即用让我不用折腾基础设施。
  • Drizzle ORM — TypeScript 优先的 ORM,贴合 SQL 思维。比起 Prisma,它更轻量、更透明,生成的 SQL 一目了然,迁移文件也更好理解。用的是 1.0 beta 版本,新版的 defineRelations() API 写起来很舒服。
  • UnoCSS — 原子化 CSS 引擎,Tailwind 的超集。按需生成、零运行时、配置灵活,presetAttributify 让我可以直接用属性写样式,presetIcons 让我不用装 icon 库。
  • Pinia — Vue 官方状态管理,简洁直觉。配合 pinia-plugin-persistedstate 做 token 持久化,配合 @pinia/colada 做异步数据缓存。
  • valibot — 轻量级 Schema 校验,API 设计和 Zod 很像但体积更小。前后端通用,服务端校验完直接报中文错误信息。
  • oxlint / oxfmt — 基于 Rust 的 Lint & Format 工具。相比 ESLint + Prettier,速度快了一个量级,而且配置更少。
  • jose — JWT 签发与验证,标准的 HS256 方案,简单可靠。

不使用 ESLint、不使用 Prettier、不使用 Zod —— 不是因为它们不好,而是想试试更轻、更快的工作流。折腾本身就是乐趣的一部分。

架构设计

项目采用 Nuxt 4 的 app/ 目录结构,前后端代码清晰分离:

  • 前端在 app/ 下,按功能组织:页面、组件、布局、状态管理、组合式函数、插件
  • 后端在 server/ 下,Nitro 提供文件路由 API,Drizzle 处理数据库操作
  • 数据库用 PostgreSQL,Redis 虽然配了但目前还没有重度使用
  • Docker 本地跑数据库,一行 docker compose up -d 就能起飞

API 设计遵循统一模式:valibot 校验输入 → OpenAPI 元数据 → 处理逻辑 → 直接返回原始数据(不做 { code, data, message } 包装)。认证用 JWT,GET 请求公开,写操作需要 Bearer Token。

功能一览

这个博客不是只有「写文章」这一个功能,它是一个相对完整的系统:

  • 📝 文章管理 — Markdown 编辑器、分类、标签、软删除、前后篇导航
  • 💬 嵌套评论 — 支持回复和楼层嵌套,带审核状态管理
  • 📊 文章统计 — 浏览量、点赞数、分享数、评论数,独立统计表
  • 🛠️ 管理后台 — 文章 / 评论 / 标签 / 分类 / 用户的全套 CRUD
  • 🔐 JWT 认证 — 登录后 token 自动注入,全局 $fetch 拦截
  • 🖼️ 图片上传 — 5MB 限制,写入本地文件系统,元数据入库
  • 📱 PWA 支持 — 可安装到桌面 / 手机的渐进式 Web 应用
  • 🌙 暗黑模式 — 跟随系统配色方案,class 策略切换
  • 🤖 MCP 服务器 — 暴露 /api/mcp 端点,AI 工具可以直接调用博客的所有 API
  • 🌸 樱花特效 & 点击特效 — 纯粹因为好玩
  • 📧 邮件通知 — 通过 nodemailer 发邮件,QQ 邮箱 SMTP

一些设计小心思

除了功能本身,我还塞了一些私货进去:

  • 首页打字机会随机展示一句话,每次打完等两秒再换下一句,让首页不那么静态
  • 关于页顶部也有一句轮播语,通过 /api/common/message 接口返回
  • 颜色主题可以根据一个主色生成完整的 1–10 阶色阶,用 colord 库实现 HSL 插值
  • 后台登录按钮用了 RGB 渐变动画,因为好看的按钮能让写文章更有动力
  • Live2D 看板娘藏在角落里,偶尔陪你逛逛
  • 页面可见性监听会在你切走标签页时暂停一些不必要的操作
  • 点击特效会在你点页面时弹出一个小小的涟漪

这些功能没什么「用」,但它们让这个博客有了一种「活」的感觉,而不是一个冷冰冰的内容管理系统。

写在最后

这个博客会一直迭代下去。可能某天我会换个技术栈,可能某天我会重新设计整个 UI,也可能某天我就不怎么写了——但至少现在,我很享受这个过程。

技术最终是服务于人的。如果我的某篇文章帮到了你,或者这个博客的某个细节启发了你,那就再好不过了。

感谢你的来访,祝你今天也是好心情。✨

联系我

  • GitHub: @wsvaio
  • Email: wsvaio@qq.com

这个博客是开源的,如果你对实现细节感兴趣,欢迎去 GitHub 仓库 转转。

上一篇

留言板

Comments | 0条评论