💻 代码项目
个人空间网站 · 凌空的个人空间
用 Next.js 构建的动态个人站点,承载自我介绍、公开笔记、作品集与私密日记,部署于腾讯云。
2026年9月15日
查看链接Next.jsReact 19TypeScriptPrismaSQLiteTailwind CSSJWTNginx
定位
一套由两个互相独立站点组成的个人空间:极简静态名片页(lingkong.site)与全功能动态主站(resume.lingkong.site),由 Nginx 按域名分流,无代码共享、无构建依赖。主站用于把个人经历以可访问网址呈现给面试官。
架构决策
- 渲染模式:
next build+next start的 Node 服务运行,业务页面显式force-dynamic,避免静态预渲染导致后台新增内容前台不显示。 - 后端即 Route Handler:无独立后端,13 个 Route Handler 提供全部接口;公开读 / 登录写用同一端点 + 鉴权区分。
- 文案入库:首页与关于页文案不写死在代码,存于
SiteContent单例行,后台编辑器维护,getSiteContent()用upsert惰性建行、写入时字段白名单过滤。
踩过的坑与权衡
- 上传图片不走 public/:
next start固化 public 目录清单,构建后新增文件会 404。改为/api/media/[...path]直接读磁盘返回,并用normalizeImageUrl()把历史/uploads/前缀改写,保证旧数据不失效。 - SQLite 决定进程模型:单文件库不支持多进程,PM2 用
fork+instances: 1,设max_memory_restart防轻量服务器内存泄漏。 - 私密性三处保证:导航按登录态过滤、首页日记卡片仅登录后加入、关于页日记入口仅登录后渲染;未登录访客 HTML 不含任何日记痕迹。
- SEO 取舍:主站反向注入
X-Robots-Tag: noindex, nofollow,避免被搜索引擎收录。
技术栈
Next.js 16(App Router)、React 19、TypeScript(strict)、Tailwind CSS v4、Prisma + SQLite、jose(JWT HS256)+ bcryptjs、react-markdown + remark-gfm。