把真正理解过的东西留下来
信息随时可以重新搜索,问题也可以随时问 AI。但那些真正理解过、验证过、实践过的内容,依然值得记录。日后再回来看,这些记录就是自己的知识索引,也是唤起记忆的线索。
网站基于 Next.js 与 React 构建,以 MDX 组织内容,并通过组件与工具链,持续改善内容的组织方式、呈现效果与使用体验。
01
技术栈
网站主要由五个层次组成。
Next.js 16(App Router)+ React 19
负责路由、页面渲染与静态导出。
MDX(@next/mdx)+ remark-gfm / rehype-slug / rehype-pretty-code(Shiki)
长文与 Cheatsheet 以 MDX 编写,并在构建时完成 Markdown 扩展、代码高亮与 React 组件编译。
Tailwind CSS v4 + Radix UI + shadcn + lucide-react
Tailwind 提供样式工具类,Radix 提供无样式交互原语,shadcn 在其上封装站点组件,lucide-react 提供图标。
TypeScript 5 + pnpm
源码使用 TypeScript,依赖与脚本由 pnpm 管理。
Vercel
静态产物部署至 Vercel。
02
依赖项
这里列出本站实际用到的 npm 包。点选分类或包名,查看它负责什么、以及在网站中的具体用途。
"dependencies"
: {// 运行时能力"devDependencies"
: {// 开发工具链03
内容如何发布
网站没有数据库或 CMS。内容以源文件保存,Node.js 脚本提取元数据生成列表,再由 Next.js 构建成静态页面发布。
- 01
撰写中文
MDX / JSON
- 02
翻译英文
LLM + 校对
- 03
生成索引
generate:all
- 04
静态构建
Next.js → out/
- 05
发布
GitHub → Vercel
- 01
先人工写中文
文章、速查和页面文案通常先写中文。文章使用目录名作为 slug;速查使用 metadata.slug,文件名可以不同。翻译版本共用对应的 URL slug。
- 文章:src/content/zh-cn/articles/{slug}/index.mdx
- Cheatsheet:src/content/zh-cn/cheatsheets/{topic}/{article}.mdx
- 页面文案:src/i18n/messages/zh-cn/{namespace}/index.json
- 02
英文由 LLM 翻译,再人工校对
中文定稿后复制到英文目录,再用程序、agent 或 chatbot 翻译。LLM 只提供初稿;代码、命令、链接、事实和术语仍需人工检查。
- 不翻译 id、slug、代码和 URL;翻译标题、摘要、正文和可见标签。
- 未完成的内容使用 _draft 前缀或暂不创建;完成翻译后重新生成索引。
- 03
用 Node.js 从源文件提取元数据,生成列表
pnpm generate:all 会扫描 MDX 里的 export const metadata,以及工具 / Explore 的 meta JSON,写出各语言的 list.json,供首页和列表页渲染。没有使用 MDX formatter 或 CMS 来生成列表,因为 JSON 更容易控制字段结构,中英文也更容易对齐。
- 文章索引按日期倒序;工具和 Explore 元数据保留 sort 字段,展示排序由页面实现决定。
- list.json 和 src/generated/* 是生成结果,不要手改,下次生成会被覆盖
- 04
构建静态站点并发布
pnpm build 会先跑 generate:all,再让 Next.js 把所有语言和路径预渲染到 out/。提交到 GitHub 后,Vercel 按仓库设置构建并发布静态产物。
- 提交前可用 pnpm routes:list 确认中英文 URL 都已生成
- 网站没有数据库或后台 CMS。栏目由目录结构决定,标题、日期、摘要和排序由文件中的 metadata 决定。
- metadata 必须是可序列化的字面量,不能调用函数或引用外部变量,否则生成脚本无法提取。
04
多语言如何实现
这是自研的轻量方案,没有使用 next-intl。英文和简体中文页面都在构建时预先生成,不是浏览器里即时翻译。
URL
/{locale}/...
语言写在网址第一段。/en/about 是英文,/zh-cn/about 是中文。访问 / 时是默认英文首页,没有根据浏览器语言自动跳转。
UI 文案
JSON
标题、按钮、菜单等短文案放在 src/i18n/messages/{locale}/,每种语言一份,字段结构必须一致。
长文内容
MDX
文章和 Cheatsheet 放在 src/content/{locale}/,各语言独立维护正文;列表索引由脚本生成。
构建
静态 HTML
generateStaticParams 为每种语言生成路由,部署后中英文都是预先生成的 HTML。
为什么分成 JSON 和 MDX 两条链路
短文案改动频繁、结构固定,用 JSON 好对齐字段;长文需要 Markdown、代码块和组件,用 MDX。不要把文章正文塞进 UI JSON,也不要把按钮文案写进 MDX。
页面怎么读取文案
普通页面在 Server Component 里按 locale 加载 JSON,再把内容当 props 传给展示组件。只有本身就需要点击、筛选等状态的客户端组件,才包一层 I18nProvider,用 useLocalesT 读文案。
站内链接必须带上当前语言
组件只写业务路径,例如 /articles;LocaleLink 会自动补上 /zh-cn 或 /en。直接用 next/link 会丢掉语言前缀,切到另一页时语言会错。
语言版本独立发布
不需要创建未翻译占位文件。构建根据已发布内容生成语言可用性数据;缺失的长文翻译显示提示页,不进入 sitemap。UI 文案仍需维护中英文相同的字段结构。
05
托管与外部服务
以下是网站当前使用的主要服务。
代码与部署
GitHub
存放仓库代码,并作为 Vercel 部署的代码来源。
免费档Vercel
承接构建与静态站点托管;站点对外访问由 Vercel 提供。
免费档(Hobby)静态资源
Cloudinary
托管并分发站点图片;页面通过自定义 next/image loader 生成 Cloudinary URL。
免费档Cloudflare R2(r2.oceanz.site)
托管较大体积的静态文件(例如 edge-tts 音频样例),经自定义域名对外分发。
免费档jsDelivr(cdn.jsdelivr.net)
edge-tts 等资源的备用地址。主路径走 R2;jsDelivr 在部分网络环境下不稳定,不作为依赖主源。
免费域名
Cloudflare DNS
将域名的 DNS 切换到 Cloudflare 后使用其解析服务;域名本身的注册费用不在此列。
DNS 免费档分析
Vercel Analytics
收集站点访问相关指标(通过 @vercel/analytics 接入)。
免费档(随 Vercel 方案)Vercel Speed Insights
收集 Web Vitals 等性能指标(通过 @vercel/speed-insights 接入)。
免费档(随 Vercel 方案)Microsoft Clarity(clarity.ms)
生产环境注入 Clarity 脚本,用于会话回放与页面行为统计。
免费广告
Google AdSense
生产环境加载 AdSense 脚本(pagead2.googlesyndication.com),用于展示广告。
接入免费;收益按 AdSense 结算