1 年前,我在玩 Next.js App Router。 在我的玩具项目 No Deploy 上实验时,我计划构建文档。 然而,Nextra 不支持 App Router。
为了处理这个问题,我使用 Contentlayer 和 App Router 的新功能,仅凭借它们实现了一个小型文档站点。 它运行得很好,看起来闪电般快速且简洁。 我从 No Deploy 克隆了逻辑,并构建了这个文档框架。 经过几个月的发展,它很快变得强大且稳定。
它最初名为 next-docs,我将其重命名为 Fumadocs,因为它与 Next.js Docs 冲突。
多亏了 Next.js 社区的支持,我一路上收到了许多建议。 Fumadocs 现在是一个用于我的库和其他一些出色项目的框架。
我的观点
在 Web 开发中,大多数“强大”的框架/库都极其庞大而华丽,但这确实让我们的开发者体验变得花哨。
在 JavaScript 之上,人们构建了打包器、转译器,甚至 TypeScript。 JavaScript 作为一种高级脚本语言,在现代 Web 开发中感觉更像汇编代码,这让人感到非常惊讶。 我们很少不使用 Webpack 等工具就使用它们。这也适用于 CSS,至少根据我的经验,我很少不使用 PostCSS 就使用 CSS。
虽然它们可能对于兼容性和 DX 是必要的,但 React Server Component 和 Next.js App Router 的引入让体验变得更加令人惊叹。 感觉像魔法一样。这些狡猾的魔法框架,以及 Web 开发的奇迹。 这种设计很疯狂,但它也让我们盲目地忘记了界限。
初学者使用 Metadata API,而他们不知道 meta 标签是如何工作的。 他们将服务器端逻辑放在服务器组件中,而他们不知道计算的开销有多大。 即使我们查看代码,也无法在不以生产模式运行的情况下预测结果。 我看到了太多这样的误解。
这种情况发生在许多框架上,它们过于魔法。 我想让它减少魔法,至少对于大多数 Next.js 开发者来说更直接明了。
Fumadocs MDX
作为推荐的内容源,它实际上是一个 webpack 黑客。
由于 Next.js 只能优化静态导入,它首先将你的 .map.ts 转换为大致产生以下内容的文件:
export default [import("./my/file.mdx"), ...];然后使用自定义加载器转换 MDX 文件。这让所有魔法成为可能,但它没有懒加载 MDX 文件的能力。 与 Nextra 相比,这可能是一种次优方法。
Nextra 做得更简单,它直接将 MDX 文件转换为页面。因为 Pages Router 将 JavaScript 文件适应为单个页面,这是可能的。 在 App Router 中,这不再可能。因此,我没有采用这种方法。
Fumadocs Core
Fumadocs 的核心是一堆实用工具和 MDX 插件。
- Source API 从内容源构建页面树,与其他内容提供者集成。
- Headless 组件 加速 Fumadocs UI 和其他自定义 UI 实现。
- MDX 插件 为所有集成带来完美的开发者体验。
- 搜索实用工具 使实现文档搜索变得更容易。
此外,它还建立了页面树和页面约定的定义。 总体而言,没有 Fumadocs UI,它还不是一个框架。
在我看来,代码库中最有价值的部分是 MDX 插件。 在开发它们时,我学到了更多关于 AST 和 remark/rehype 生态系统的东西。 绝对是一次惊人的体验。
Fumadocs UI
Fumadocs 使用 Tailwind CSS 和 Radix UI 实现的 UI。 它的设计系统受 Shadcn UI 启发,使用 CSS 变量作为颜色实用工具。
虽然 Fumadocs UI 的结构甚至比核心更简单,但我使用了一些微妙的黑客来解决 "use client" 指令的问题。
我使用的打包器 TSX 无法处理像从服务器组件导入的客户端组件这样的嵌套结构。
因此,我做了一个小黑客,将服务器组件和客户端组件作为单独的入口构建,然后在处理后注入导入语句。
另外,我花了一些时间想出 预设方法,用于将 Fumadocs UI 与 Tailwind CSS 项目集成。
文档生成器
我们有几个内置集成,比如 fumadocs-openapi,它接受 OpenAPI 模式并输出 MDX 文件。
对于 OpenAPI,它简单地解析模式并通过字符串模板将其转换为 MDX 文件。
TypeScript 集成做了更多,它使用 TypeScript Compiler API 获取类型信息。根据这些信息,它生成 MDX 文件。
你可以在服务器组件中使用它,这就是 <AutoTypeTable /> 的工作方式。
CI/CD
作为一个贡献者很少的项目,我将 CI/CD 过程构建得尽可能方便,以提高效率。 整个发布过程由 Changesets 处理,我编写了脚本来自动更新 模板仓库。 到目前为止,它运行得很好。
致谢
Fumadocs 的 GitHub 仓库 在 2024 年 3 月达到了 300 个星标,这对我来说是一个新成就。 欢迎给它一个星标来支持我的工作!
Written by
Fuma Nama
At
Wed May 15 2024