Blog 项目全解
2026-03-23
博客项目全解
一、项目概览
这是一个基于 Next.js 16 + React 19 + TypeScript 的个人博客系统,使用 App Router 组织页面,内容来源于本地 Markdown 文件,并支持从外部文章仓库按需同步。
项目定位是「深色优先、内容驱动、轻交互」的技术博客,核心能力包括:
- Markdown 文章渲染(含代码高亮、图片灯箱)
- 博客列表与详情页路由生成
- 运行期异步内容同步(拉取远端仓库最新文章)
- Tailwind CSS v4 + Shadcn/ui 风格化界面
二、技术栈详解
1) 前端与框架层
Next.js 16.2.0:全栈 React 框架,负责路由、服务端渲染与构建产物。React 19.2.4:组件与 UI 逻辑核心。TypeScript 5:静态类型系统,提升可维护性与重构安全。
2) 样式与 UI 层
Tailwind CSS v4:原子化样式方案。@tailwindcss/typography:优化 Markdown 排版(prose)。Shadcn/ui(基于 Radix 生态组件):构建一致化基础组件。next-themes:主题(亮/暗)切换基础能力。
3) 内容与渲染层
react-markdown:将 Markdown 转成 React 组件。remark-gfm:支持 GFM 语法(表格、任务列表等)。PrismJS:代码块高亮。Velite:内容集合配置与 Markdown 内容处理能力。rehype-shiki+shiki:可选高质量语法高亮管线(在 Velite 配置中启用)。
4) 工程与质量层
eslint@9 + eslint-config-next:代码规范与静态检查。postcss:样式处理链路。
三、目录结构(核心)
NewBlog/
├─ src/
│ ├─ app/
│ │ ├─ (site)/page.tsx # 站点首页
│ │ ├─ blog/page.tsx # 博客列表页
│ │ └─ blog/[slug]/page.tsx # 博客详情页
│ ├─ components/
│ │ └─ blog/PostImageLightbox.tsx# 图片灯箱
│ └─ lib/
│ ├─ post-source.ts # 读取并解析 Markdown
│ └─ content-sync.ts # 远端内容仓库同步逻辑
├─ content/posts/ # 本地文章目录(Markdown)
├─ public/static/ # 静态资源
├─ velite.config.ts # Velite 配置
└─ package.json # 脚本与依赖
四、关键代码片段与逻辑说明
下面代码为项目内关键逻辑摘录(便于理解整体运行机制)。
1) 启动脚本:内容构建与开发服务并行
{
"scripts": {
"dev": "velite dev & next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
}
}
说明:
npm run dev会同时启动velite dev与next dev。build/start分离,符合生产环境常见流程(先构建,再启动)。
2) 文章同步:运行期异步触发内容拉取
首页/列表/详情页都在请求结束后触发:
after(() => {
void ensureContentFresh();
});
说明:
after让同步任务在响应后执行,降低首屏阻塞概率。ensureContentFresh()内部有 TTL、并发锁与远端 SHA 校验,避免重复拉取。
3) 远端更新判定:基于分支 HEAD SHA
const { stdout } = await runGit(
["ls-remote", authedRepoUrl, `refs/heads/${branch}`],
process.cwd()
);
说明:
- 通过
git ls-remote获取远端分支最新 SHA。 - 若与本地记录一致,则仅刷新检查时间,不做同步。
4) Markdown 读取:递归扫描并解析 Frontmatter
if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) {
files.push(full);
}
说明:
- 递归读取
content/posts下所有.md。 - 同时兼容 YAML (
---) 与 TOML (+++) Frontmatter。 - 最终按日期降序排序,供列表页渲染。
5) 详情页渲染:Markdown + 代码高亮 + 图片灯箱
const highlighted = Prism.highlight(
codeText.replace(/\n$/, ""),
grammar,
language ?? "markup"
);
说明:
react-markdown负责结构化渲染。Prism对代码块做语法高亮。img节点替换为PostImageLightbox,提升阅读体验。
五、本地部署步骤(详细)
1) 环境准备
- Node.js:建议
20.x(LTS) - npm:建议
10.x及以上 - Git:
2.30+
2) 拉取代码并安装依赖
git clone <你的仓库地址>
cd NewBlog
npm install
3) 配置环境变量(可选:启用远端文章同步)
在项目根目录创建 .env.local(若仅本地静态文章可不配置):
# 远端文章仓库地址(示例为加盐脱敏)
POSTS_REPO_URL=https://git.example.com/salt_x7a2/new-blog-posts.git
# 二选一:账号密码 或 Token
POSTS_REPO_USERNAME=usr_salt_8f2c
POSTS_REPO_PASSWORD=pwd_salt_k9q1
POSTS_REPO_TOKEN=tok_salt_t3m9
# 分支与同步策略
POSTS_REPO_BRANCH=main
POSTS_SYNC_TTL_SECONDS=60
POSTS_RUN_VELITE_AFTER_SYNC=false
安全建议:生产环境优先用
POSTS_REPO_TOKEN,并避免明文提交任何凭据。
4) 本地启动
npm run dev
关键访问地址(示例已加盐):
- 首页:
http://127.0.0.1:30_salt_00/ - 文章列表:
http://127.0.0.1:30_salt_00/blog - 单篇文章:
http://127.0.0.1:30_salt_00/blog/<slug_salt_xx>
5) 生产构建验证
npm run build
npm run start
默认启动端口通常为 3000(可通过环境变量覆盖)。
六、发布前检查清单
npm run lint无错误npm run build构建通过- 至少验证 1 篇含代码块文章与 1 篇含图片文章
- 核对
.env*未进入 Git 提交
七、网站内容更新流程(文章侧)
场景 A:本仓库直接维护文章
- 在
content/posts/新建目录并写入index.md - Frontmatter 至少包含:
title、date、description - 本地预览:
npm run dev - 提交并部署网站代码
场景 B:远端文章仓库维护
- 在文章仓库提交新文章到指定分支(如
main) - 访问网站任一页面后,服务端触发
ensureContentFresh() - 若 TTL 到期且远端 SHA 变化,自动拉取并覆盖本地
content/posts - 刷新列表页/详情页确认内容生效
八、网站更新后同步到服务器(操作手册)
以下是通用 Linux 服务器流程(systemd + Nginx),所有关键信息均示例加盐:
1) 登录服务器并进入项目目录
ssh dev_salt_u1@203.0.113.salt.10
cd /srv/www/newblog_salt
2) 拉取最新代码并安装依赖
git pull origin main
npm install
3) 构建并重启应用
npm run build
sudo systemctl restart newblog_salt.service
sudo systemctl status newblog_salt.service --no-pager
如果你使用
pm2,可改为:npm run build pm2 restart newblog_salt pm2 logs newblog_salt --lines 80
4) Nginx 反向代理检查(如有)
常见代理目标(示例):
http://127.0.0.1:3000(Next.js 进程)
建议验证:
- 站点地址:
https://blog_salt.example.com - 列表页:
https://blog_salt.example.com/blog - 随机文章:
https://blog_salt.example.com/blog/<slug_salt_xx>
5) 回滚预案(建议)
git log --oneline -n 5
git checkout <上一个稳定提交sha_salt>
npm run build
sudo systemctl restart newblog_salt.service
九、术语补充(简明)
App Router:Next.js 新路由体系,以目录结构定义路由与布局。Frontmatter:Markdown 文件头部元信息区,常用于标题、日期、摘要。TTL(Time To Live):缓存/检查间隔,避免频繁同步。SHA:Git 提交哈希,用于判断远端是否有更新。SSR:服务端渲染,HTML 在服务器生成后返回浏览器。
十、结论
该项目具备「内容驱动 + 轻量同步 + 现代前端栈」三大特征:
前端使用 Next.js 16 与 React 19 保证工程现代化;内容层通过 Markdown 与同步机制实现低成本更新;部署层可无缝接入传统 Linux 服务管理。
对于个人博客与技术沉淀场景,这套方案在可维护性、扩展性与落地效率之间达到了较好的平衡。