如何利用本地 Git 历史为 Fumadocs MDX 文档输出最后修改时间?
2026/9/15 15:03:25 网站建设 项目流程

如何利用本地 Git 历史为 Fumadocs MDX 文档输出最后修改时间?

【免费下载链接】fumadocsThe beautiful & flexible React.js docs framework.项目地址: https://gitcode.com/GitHub_Trending/fu/fumadocs

如果你在用 Fumadocs(fumadocs)搭建文档站,想给每个页面展示"最后更新时间",fumadocs-mdx提供了一个lastModified插件:它在构建时读取你本地的 Git 提交历史,为每个 MDX 文档计算并导出lastModified属性(类型为Date),之后就能在页面上展示出来。整个过程依赖一个前提:你的机器上安装了 Git,且仓库不是浅克隆(shallow clone),因为插件解析时间时会执行本地git log

在 source.config.ts 中启用插件

在 MDX 处理器配置文件(Fumadocs 项目里是source.config.ts)中引入插件并加入plugins数组:

import { defineConfig } from 'fumadocs-mdx/config'; import lastModified from 'fumadocs-mdx/plugins/last-modified'; export default defineConfig({ plugins: [lastModified()], });

本仓库的 source.config.ts 就是这样配置的(同时使用了satteri编译器和jsonSchema插件)。

这个插件本质上是一个快捷方式:它会为配置中每个文档集合(collection)设置lastModified选项,但已经自行设置了lastModified的集合会被原样保留、不做覆盖(见 插件实现)。

可选:自定义时间来源

插件接受一个versionControl参数,默认值是'git'(见 LastModifiedPluginOptions):

  • 保持默认'git':直接从本地 Git 历史读取。文档特别提醒:如果你使用 Vercel 部署,需要把环境变量VERCEL_DEEP_CLONE设置为true,避免浅克隆导致没有完整历史。
  • 传入一个函数:签名为(filePath: string) => Promise<Date | null | undefined>,由你自己决定如何为某个文件路径返回最后修改时间(例如调用 GitHub API 或 CMS),返回null/undefined表示未知。

插件还支持filter参数,按集合名称筛选哪些集合应用该配置。

了解 Git 时间是如何解析的

默认路径下,插件按集合的内容目录解析时间(实现见 loaders/mdx/last-modified.ts):

  1. 先执行git rev-parse --show-toplevel找到仓库根目录;
  2. 再执行git -c core.quotepath=off log --format=commit:%aI --name-only -- <内容目录>,把提交范围限定在文档目录内(不做限定的话会为每个进程缓冲整个仓库历史);
  3. 按"新提交在前"的顺序处理,为每个文件保留第一次出现的提交日期,即该文件最近一次被修改的时间。

由此可以得到两条使用上的边界:

  • 文件必须已提交到 Git;未提交的文件查不到时间,lastModified会是undefined
  • 仓库若是浅克隆,历史不完整,解析出的时间可能不准或查不到。

在代码中读取 lastModified 属性

启用插件并重新生成/构建后,每个文档都会导出lastModified属性。按 Last Modified Time 文档,通过 source 读取:

import { source } from '@/lib/source'; const page = source.getPage(['...']); console.log(page.data.lastModified); // 或惰性加载 const { lastModified } = await page.data.load(); console.log(lastModified);

这里['...']替换为你要查询的文档 slug 路径。console.log的输出是一个Date,这就是验证插件生效的方式:如果打印出Date对象(而不是undefined),说明 Git 历史解析成功。

在页面上展示时间

Fumadocs UI 的DocsPage布局组件提供了PageLastUpdate,见 Page 布局文档的 Last Updated Time 一节:

import { DocsPage, PageLastUpdate } from 'fumadocs-ui/layouts/<layout>/page'; const lastModifiedTime = page.data.lastModified; <DocsPage> {/* Other content */} {lastModifiedTime && <PageLastUpdate date={lastModifiedTime} />} </DocsPage>;

注意两点:

  • 导入路径中的<layout>占位符要替换为你实际使用的布局名(如default),文档原文就用这个形式表示"按你的布局选择";
  • 展示前用lastModifiedTime && ...做了判空——因为未提交的文件取不到时间,属性可能是undefined,不能假设它一定有值。

限制与排查

  • Git 未安装或仓库是浅克隆:文档中明确以 warning 提示,默认依赖本地 Git 历史,浅克隆下git log拿不到完整提交记录,时间会缺失或错误。
  • 文件未提交:解析函数在"未知"(例如文件没提交)时返回null/undefined,页面上对应的时间区域就不会渲染。
  • 自行设置过lastModified的集合:插件不会覆盖它们,如果你自定义了时间来源,以集合自己的配置为准。
  • Vercel 部署:必须设置VERCEL_DEEP_CLONE=true,否则构建环境是浅克隆,本地 Git 历史不完整。

完成以上配置后,验证路径就是:文档已提交 → 重新构建 →page.data.lastModified能取到Date→ 页面通过PageLastUpdate显示出来。如果你不需要 Git 而是想按 GitHub 仓库在线查询,文档还介绍了另一个方向——GitHub API 方式(见 Page 布局文档 中的getGithubLastEdit用法),但那属于不同的实现路径,与本文的本地 Git 历史方案二选一即可。

【免费下载链接】fumadocsThe beautiful & flexible React.js docs framework.项目地址: https://gitcode.com/GitHub_Trending/fu/fumadocs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询