BDI 官网深度代码审计与精简报告
对 BDI 官网全量代码逐行深度审计,聚焦 Next.js v16、Nextra v4、Tailwind CSS v4 的最佳实践合规性,识别死代码、架构冗余和优化空间,实施代码精简与文件合并。
以下是正文
一、背景与目标
BDI 官网基于 Next.js 16.1.6 + React 19.2.4 + Nextra v4.6.1 + Tailwind CSS v4 构建。经过多轮功能迭代和前序审计修复后,本轮对项目全量代码进行逐行深度审计,核心目标:
- 最佳实践合规 — 确保代码充分利用 Next.js v16、Nextra v4、Tailwind CSS v4 的官方能力
- 代码极简 — 删除死代码,合并冗余文件,减少代码量和文件个数
- 架构清晰 — 识别职责不清或过度工程化的模块
二、审计范围
本次审计覆盖项目全部源代码文件,按层次分类如下:
| 层次 | 文件 |
|---|---|
| 配置层 | next.config.ts、tsconfig.json、biome.json、proxy.ts、package.json、postcss.config.mjs |
| 全局层 | app/layout.tsx、app/globals.css、app/global-error.tsx、app/robots.ts、app/sitemap.ts |
| 路由层 | app/[locale]/layout.tsx、app/[locale]/page.tsx、app/[locale]/not-found.tsx |
| 博客层 | blog/page.tsx、blog/[slug]/page.tsx、blog/[slug]/loading.tsx |
| 文档层 | docs/layout.tsx、docs/[[...mdxPath]]/page.tsx |
| 服务层 | services/page.tsx |
| 组件层 | 所有 components/ 目录(约 20 个文件) |
| 工具层 | lib/utils.ts、lib/db.ts、lib/locale-path.ts、lib/styles.ts、lib/actions/*.ts |
| 国际化 | i18n/config.ts、i18n/dictionary-provider.tsx、i18n/get-dictionary.ts、dictionaries/*.json |
| MDX | mdx-components.tsx、content/ 目录 |
三、发现与问题分类
3.1 死代码(已删除)
在 lib/utils.ts 中发现 3 个全项目未被任何文件调用的导出函数:
| 函数 | 行数 | 说明 |
|---|---|---|
clampText() | 25 行 | 按视觉宽度截断文本,已被 CSS line-clamp 替代 |
getBadgeStyles() | 3 行 | 独立使用的徽章样式,已被碰撞避免版 getBadgeStylesByIndex() 替代 |
getCategoryNavColors() | 3 行 | 独立使用的导航颜色,已被 getCategoryNavColorsByIndex() 替代 |
处理: 已全部删除,减少约 31 行死代码。
3.2 冗余文件(已合并)
| 文件 | 内容 | 处理 |
|---|---|---|
lib/styles.ts | 仅含 1 个常量 circularButtonClass | 已合并到 lib/utils.ts,删除文件 |
处理: 项目文件数减少 1 个,scroll-to-top.tsx 和 mobile-toc.tsx 的导入已统一为 @/lib/utils。
3.3 CSS 过度工程化(已精简)
问题: app/globals.css 中存在约 113 行 .prose-blog 自定义排版样式,包括:
- 自定义
line-height: 1.85(覆盖 Typography 插件的prose-lg默认值1.778) - 蓝色主题链接、过渡动画
- Blockquote 蓝色边框 + 背景
- 图片圆角和阴影
- 内联代码样式
- 表格斑马纹
- 大量
.dark变体
根因: Tailwind CSS @tailwindcss/typography 的 prose-lg 默认值已经是行业最佳实践,不应覆盖。
处理:
- 删除全部
.prose-blog自定义样式(113 行) - 博客容器 class 从
prose-blog prose prose-lg prose-slate dark:prose-invert简化为prose prose-lg dark:prose-invert - 仅保留 Shiki 语法高亮 CSS(因 Nextra headless 模式需要)和表格边框(项目要求)
3.4 语言一致性问题(已修复)
| 文件 | 问题 | 修复 |
|---|---|---|
app/global-error.tsx | lang="zh" 但文本全英文("Something went wrong"、"Retry") | 文本已改为中文 |
dictionaries/en.json | 导航 "洞察与分享" 英文翻译 "Insights" 缺少"分享"含义 | 改为 "Blog & Insights" |
3.5 数据库查询优化(已修复)
lib/actions/blog.ts 中 getInteractions() 函数使用 stmt.all()[0] 获取单条记录,改为更语义化的 stmt.get()(Node.js node:sqlite 的 StatementSync 支持 .get() 方法)。
3.6 垃圾文件清理(已删除)
| 文件 | 原因 |
|---|---|
bdi_blog.db(根目录) | 数据库文件在 data/bdi_blog.db,根目录的副本未被代码引用 |
tsconfig.tsbuildinfo | TypeScript 增量编译缓存,已在 .gitignore 中 |
build-output.txt | 构建调试临时文件 |
.env.example | 仅含 NEXT_PUBLIC_APP_URL,代码中已有硬编码 fallback,README 已说明 |
四、架构评估与建议
4.1 已确认合规的最佳实践
| 项目 | 状态 | 说明 |
|---|---|---|
| App Router | ✅ | 使用 app/ 目录,无 Pages Router |
proxy.ts | ✅ | 使用 Next.js 16 推荐的 proxy.ts 替代 middleware.ts |
| React Compiler | ✅ | reactCompiler: true 已启用 |
params 为 Promise | ✅ | 所有动态路由 params 声明为 Promise<{}> 类型 |
| Server Components | ✅ | 仅交互组件添加 "use client",默认服务端渲染 |
| Server Actions | ✅ | toggleReaction、submitComment 使用 "use server" |
| CSP 安全头 | ✅ | 完整实现 7 项安全响应头 |
server-only | ✅ | lib/db.ts 使用 "server-only" 防止客户端引入 |
| Tailwind CSS v4 | ✅ | @plugin 语法、@custom-variant 正确使用 |
| shadcn/ui | ✅ | 统一使用 radix-ui 包,cn() 函数 |
| React 19 Context | ✅ | DictionaryProvider 使用 use() 和新的 value prop |
| Nextra Code 组件 | ✅ | mdx-components.tsx 集成 Nextra Code 组件 |
| MDX 安全防护 | ✅ | iframe 阻止 + 警告,script 返回 null |
| biome lint/format | ✅ | 统一代码规范 |
4.2 保留的必要自定义 CSS
以下 CSS 保留在 globals.css 中,各有充分理由:
| CSS | 理由 |
|---|---|
Shiki 双主题 CSS(--shiki-light/--shiki-dark 变量解析) | Nextra headless 模式不含 code-block.css(其使用 x: 前缀不可用) |
pre 背景色(#f6f8fa/#0d1117) | 覆盖 Typography 插件默认深色背景,匹配 Shiki github-light/dark 主题 |
| 表格边框 | 项目要求"MDX 表格全部带边框" |
| 表格首列 padding | 覆盖 Typography 插件首列 padding-left: 0 |
html { overflow-y: scroll } | 防止弹窗/语言切换时滚动条引起的水平抖动 |
4.3 后续建议(未在本轮实施)
以下问题已识别但未修改,因涉及较大架构调整或需产品确认:
| 优先级 | 问题 | 建议 |
|---|---|---|
| P2 | blog/[slug]/page.tsx 465 行过大 | 拆分 CommentSection、InteractionSection 到独立文件 |
| P2 | services/page.tsx 416 行过大 | 拆分 5 个 section 到 components/services/ |
| P2 | getComments/getInteractions 标记 "use server" 但仅做读取 | 拆分只读函数到非 Server Action 模块 |
| P3 | 首页缺少专属 generateMetadata 和 JSON-LD | 首页是 SEO 最重要页面,建议添加结构化数据 |
| P3 | sitemap 缺少 docs 子页面 | 遍历 docs pageMap 补充 |
| P3 | 未使用 next/font | 项目规范要求使用 next/font 优化字体加载 |
| P3 | locale as Locale 类型断言重复 | 在解构后统一转换一次 |
五、变更统计
| 指标 | 数值 |
|---|---|
| 删除的 CSS 行数 | ~113 行(.prose-blog 全部) |
| 删除的 TS 函数 | 3 个(clampText、getBadgeStyles、getCategoryNavColors) |
| 合并/删除的文件 | 5 个(lib/styles.ts、build-output.txt、根目录 bdi_blog.db、tsconfig.tsbuildinfo、.env.example) |
| 修复的一致性问题 | 2 处(global-error.tsx 语言、导航翻译) |
| 优化的数据库调用 | 1 处(.all()[0] → .get()) |
| 构建结果 | 25/25 ✅ |
六、结论
本轮审计的核心主题是**"信任框架默认值"**。项目此前存在过度自定义排版样式的问题(113 行 .prose-blog CSS),试图覆盖 Tailwind Typography 插件的默认值。实际上,prose-lg 的行高、间距、排版参数经过大量用户测试,已经是行业最佳实践。
删除所有自定义排版样式后,页面排版回归标准 prose-lg 表现,视觉效果专业且一致。仅保留了 Shiki 语法高亮和表格边框两类确有必要的自定义 CSS。
项目现已达到:
- 代码精简 — 无死代码、无冗余文件
- 框架合规 — 充分利用 Next.js 16、Nextra v4、Tailwind CSS v4 的默认能力
- 维护友好 — 自定义 CSS 最小化,减少未来升级时的兼容风险
- 版本: 1.0.0
- 时间: 2026-02-20 21:30:00
- 作者: Claude Opus 4.6
- 简介: BDI 官网逐行深度代码审计,删除死代码和冗余文件,精简 113 行自定义 CSS,修复语言一致性和数据库查询问题