ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Docusaurus完全指南:从零搭建高效文档站点

Docusaurus完全指南:从零搭建高效文档站点 1. 为什么我最终选了Docusaurus做文档站点生成器文档站点生成器这个赛道上其实从来不缺选手GitBook、VuePress、VitePress、MkDocs、Docsify随便一抓就是一大把。但如果你跑到一个正经搞开源项目的群里去问“做项目文档用什么”十个人里至少有六七个会甩给你同一个答案Docusaurus。作为一个也踩过不少文档工具坑的人我第一次把项目官网、用户手册、API 说明、博客更新全部迁到 Docusaurus 之后才真正理解了为什么它能成为这个领域的事实标准之一。先说结论Docusaurus 是 Facebook 开源的一套静态站点生成器主打“文档优先”但又不止于文档。它底层用 React 渲染内容层基于 Markdown 和 MDX开箱即用地集成了文档导航、版本管理、国际化、博客、搜索、SEO 等功能。也就是说你想做一个带完整文档、博客、落地页的项目官网用这一套工具就能全都跑起来不需要再单独拼一个博客框架再加一个文档框架。我选择它很重要的一个原因是它在“内容写作体验”和“前端定制能力”之间找到了平衡。纯粹用 GitBook 这类工具写完的东西很规整但想改个样式、加个交互组件很多时候得跟工具本身较劲直接用 Gatsby 这类通用静态站框架定制能力是强了但文档导航、版本切换、页面结构这些又得自己从零搭。Docusaurus 刚好卡在中间常规文档功能开箱即用遇到需要定制的地方又能用 React 组件和 MDX 直接深入进去改不至于被工具锁死。这个工具比较适合的人群我总结下来大概是这几类开源项目的维护者需要给项目做官方文档和官网中小型团队的内部知识库管理员需要一套能长期维护、支持多版本和权限边界清晰的文档体系写技术博客或教程的内容创作者希望文档、博客放在同一个站点里统一管理。当然如果你完全不会前端、也没什么定制需求它可能会让你觉得配置项有点多这种情况我反倒建议你去看更简单的静态文档工具。2. 动手搭建从一个空目录到第一版站点2.1 环境准备与初始化命令现在 Docusaurus 已经到 3.x对 Node 版本有明确要求我建议直接装 Node 20 LTS别用 16 以下的版本硬跑否则构建阶段会碰到各种兼容性报错。确认 Node 和 npm 装好之后初始化一个项目只需要一条命令npx create-docusauruslatest my-website classic这条命令会拉取官方脚手架在当前目录下创建一个叫my-website的文件夹并安装好基础依赖。classic是官方推荐的基础模板已经内置了 docs、blog、主题、站点地图这些最常用的模块适合绝大多数项目直接起步。如果项目偏向纯文档需求也可以关注classic-typescript模板后续想在文档里写 React 组件时类型检查会更舒服。初始化过程中脚手架会问你“要不要现在就用 TypeScript”这类交互问题按需选择即可。装完之后进入目录执行npm run start浏览器打开http://localhost:3000你就能看到模板主页了。从一条命令到能预览整个流程不到三分钟这在一众文档站点生成器里属于相当利索的。2.2 拆解初始化后的目录结构我见过不少新人拿到项目后第一件事就是去改页面文案结果改了src/pages/index.js半天没看到效果。先别急着改页面花五分钟把目录结构摸清楚后面能少走很多弯路my-website/ ├── blog/ # 博客文章的 Markdown 目录 ├── docs/ # 文档正文的 Markdown 目录 ├── src/ │ ├── components/ # 自定义 React 组件 │ ├── css/ # 全局样式 │ └── pages/ # 独立页面如首页、About ├── static/ # 静态资源目录图片、favicon 等 ├── docusaurus.config.js # 站点全局配置 ├── sidebars.js # 文档侧边栏配置 ├── package.json └── babel.config.js这个结构最大的优点是“约定优于配置”。你不需要在工具里登记“我这篇文档放哪”只要按规则把.md文件丢进docs/或blog/目录Docusaurus 就会自动把它们变成可访问的页面。static/目录下的文件会被原样拷贝到构建产物的根路径所以存放图片、下载文件、favicon 都是很自然的做法。这个过程中我唯一想吐槽的是模板自带的docs/intro.md和blog/2019-01-01-welcome.md这两篇文章最好在动手写正式内容前就删掉或彻底改写否则构建出的站点里会残留默认示例内容下载下来的站点看起来总是“差一步没收拾干净”。2.3 核心配置 docusaurus.config.js 深度解读docusaurus.config.js是整个站点的心脏我在这里吃过不少亏单独把几个关键字段拿出来讲。module.exports { title: 我的文档站点, tagline: 专注于项目文档与知识管理, url: https://your-domain.com, baseUrl: /, favicon: img/favicon.ico, organizationName: your-github-name, projectName: your-repo-name, themeConfig: { navbar: { title: 文档站点, items: [ { to: docs/intro, label: 文档, position: left }, { to: blog, label: 博客, position: left }, { href: https://github.com/your-github-name, label: GitHub, position: right } ], }, }, presets: [ [ classic, { docs: { sidebarPath: require.resolve(./sidebars.js), editUrl: https://github.com/your-github-name/your-repo/edit/main/, }, blog: { showReadingTime: true, }, theme: { customCss: require.resolve(./src/css/custom.css), }, }, ], ], };url和baseUrl这两个字段是构建部署时的地基。url填域名baseUrl填的是“站点挂在域名下的哪个路径”比如部署在https://example.com/my-project/那么baseUrl就要写成/my-project/。很多朋友本地预览正常一上传到 GitHub Pages 就白屏、样式全丢大概率就是这里没配好。presets里的classic预设相当于把多个官方插件打包在一起使用。docs配置中的sidebarPath指向侧边栏文件editUrl配置后每个文档页面会自动出现“编辑此页”按钮这对开源项目的协作维护非常有用。我第一次配editUrl时以为要填完整分支名后来发现main/结尾的写法才符合官方约定填错了构建时不一定报错但页面跳转链接点进去是 404。3. 结构化内容侧边栏、导航与搜索3.1 文档目录组织与 sidebars 配置文档站点生成器的核心体验就是读者能否在几秒钟内找到自己想要的内容。侧边栏在这里承担了“信息架构”的角色而 Docusaurus 的侧边栏配置理想情况下应该保持简单直接。在项目模板里sidebars.js默认是这么一段module.exports { tutorialSidebar: [{ type: autogenerated, dirName: . }], };autogenerated的意思是根据docs/目录下的文件夹结构和文件名自动生成侧边栏。这种模式在文档数量少、层级简单的时候效率奇高新增一篇 Markdown 放进去就自动出现在侧边栏里完全不用手工维护条目。但等文档量涨到几十篇、上百篇的时候自动生成就有麻烦了英文文件名排序不一定符合你的阅读顺序中间夹着的目录结构也可能不是你想要的导航层级。我自己从更早的版本踩过来总结出的规律是文档少用自动生成文档多就改成手工模式把sidebars.js里的每个条目显式列出来确保章节顺序、分组、间隔都完全可控。折中方案是用混合模式顶层分类手工定分类内部再挂一个autogenerated目录兼顾维护成本和灵活性。3.2 用 MDX 在文档里写组件和交互Docusaurus 支持 Markdown 和 MDX后者是它的一个强力卖点。MDX 的语法本质上是“在 Markdown 里写 JSX”也就是说你可以在文档中导入并使用 React 组件。举个我实际用到的例子。在写 API 文档时我们经常需要展示不同方法的请求参数表格手写表格又长又容易出错。我写了一个ParamsTable组件传入一个配置数组即可自动渲染成表格import ParamsTable from site/src/components/ParamsTable; ParamsTable params{[ { name: id, type: string, required: true, desc: 资源唯一标识 }, { name: page, type: number, required: false, desc: 页码默认 1 }, ]} /构建之后页面里就会渲染出规范的表格改数据只需要改那一处数组不用到处复制粘贴。这里有两个细节值得注意第一MDX 文件的后缀必须是.mdx如果文件是.md即使里面写了组件语法构建时也会按普通 Markdown 处理第二在 MDX 里导入文件要使用site别名指向项目根目录这样无论文档嵌套在哪一层目录路径都不会写错。3.3 让搜索真正可用Algolia DocSearch 与本地方案文档站点最大的痛点之一就是站内搜索。Docusaurus 默认不提供搜索能力需要额外接入插件或服务。官方文档推荐的方案是 Algolia DocSearch它免费提供给开源项目效果也确实不错。接 DocSearch 的流程在官方文档里写得很清楚但我遇到并解决过的两个真实问题可以提醒一下一是搜索爬虫需要你配置 DNS 验证和docsearch.config.json站点必须能公开访问内网文档站或本地预览是无法被索引的二是如果部署在子路径下docsearch.config.json里的start_urls要精确到子路径否则爬虫抓不到页面。如果你的文档站点并不打算公开或者暂时不想接入第三方服务那么本地搜索插件会更合适。市场上有第三方插件如docusaurus-lunr-search或easyops-cn/docusaurus-search-local前者基于 Lunr后者基于 TypeScript两者都能在构建时为本站生成搜索索引支持中文分词的效果也各有差异。我实测下来easyops-cn/docusaurus-search-local对中文的支持更稳一些毕竟 Lunr 原生分词对中文并不友好不加额外插件的话搜中文关键词容易出现匹配不全的问题。4. 多版本、多语言与博客的一站式用法4.1 文档版本发布流程Docusaurus 的文档版本管理是我认为它相比其他文档站点生成器的最大优势。很多静态站工具想支持多版本得自己写目录切换逻辑而 Docusaurus 把这件事做成了内置能力。假设你现在维护着 v1.0 版本的文档同时日常更新的是docs/目录中的“next”版本。当你准备发布 v2.0 时执行npx docusaurus docs:version 2.0Docusaurus 会做三件事把当前docs/的内容冻结并拷贝到versioned_docs/version-2.0/生成对应的versioned_sidebars/version-2.0-sidebars.json同时在页面上生成版本切换下拉菜单。之后你再在docs/里写的都是 v2.0 的后继版本而访问者可以通过下拉菜单回看 v1.0 和 v2.0 的完整内容。这个流程最容易被忽视的点是版本发布后旧的侧边栏配置文件不会自动更新。如果你在 v2.0 中改动了侧边栏结构那versioned_sidebars/version-1.0-sidebars.json里记录的仍然是旧结构这是符合预期的但你必须自己记住“每个已发布版本都有一份独立的侧边栏快照”这件事。曾经我为了处理旧版本的几个页面跳转问题差点动手去改versioned_docs目录里的原始文件后来才意识到那是不对的正确做法是在旧版本内容里补一个维护说明引导用户查看新版文档。4.2 i18n 国际化配置与文件目录约定如果你的文档站点需要中英文双语Docusaurus 的国际化方案也很成熟。配置主要在docusaurus.config.js里完成module.exports { i18n: { defaultLocale: zh-Hans, locales: [en, zh-Hans], }, };设置完成之后多语言的文件目录约定是源文件仍然放在docs/下作为默认语言内容其他语言放在i18n/zh-Hans/docusaurus-plugin-content-docs/current/下。更准确地说current代表的是未发布版本的“最新文档”而发布后的版本翻译要放在i18n/zh-Hans/docusaurus-plugin-content-docs/version-2.0/下。这套目录结构一开始会觉得绕但搞清楚之后它的对应关系其实很清晰。翻译管理上最大的坑是“缺失文件的回退规则”。Docusaurus 默认是如果某个语言目录下找不到对应文件它会把默认语言的版本内容展示出来。这在站点刚上线、翻译不全时是好事能保证页面不出现 404但也意味着你很容易漏翻某篇文章用户却看到一部分中文、一部分英文混合的内容。建议在正式内容上线前用脚本扫描一遍两种语言目录下的文件差异确保两边一一对应。4.3 博客与文档混排在同一个站点里Docusaurus 内置的博客功能让其产品矩阵在一个站点内变得完整。文档负责工具本身的使用说明博客负责项目更新、发布日志、写作者思考两者互不干扰又共享一套导航和主题。博客文章的 Markdown 格式需要带 YAML front matter至少包含标题、日期和标签--- title: 我们的项目发布了 v2.0 date: 2025-01-15 tags: [release, 产品动态] --- 这里是文章正文...Docusaurus 会根据日期自动生成归档tags会自动生成标签列表页整个博客模块不需要额外配置就能独当一面。加上之前说的 MDX 能力你完全可以在博客文章里放一个可交互的代码演示或其他 React 组件这种“文档 博客 组件演示”的混合体验是单纯的写作工具很难做到的。5. 把我坑得最惨的 6 个 Docusaurus 问题与排查记录5.1 部署到子路径后样式和图片全部 404这个问题的根源基本都在baseUrl。本地开发时baseUrl通常为/预览一切正常部署到 GitHub Pages 的https://用户名.github.io/仓库名/这类地址后页面 HTML 能打开但所有静态资源路径都指向了根路径自然全部 404。解决办法是一条铁律baseUrl必须等于部署路径。放在根域名下就填/放在/my-project/下就填/my-project/。改完配置后需要重启开发服务器再重新构建否则本地缓存可能让你“看到”的还是旧配置。另外Markdown 里写的图片路径如果是/img/xxx.png这种绝对路径部署到子路径时也要注意建议图片引用用相对路径或者site/static方式处理不要写死根路径。5.2 本地开发热更新失效改文件页面不刷新这种情况我遇到过两次。第一次是项目里文件太多开发服务器卡住了删掉.docusaurus目录和node_modules/.cache后重启恢复第二次是因为某个页面写了不规范的 MDX 语法构建过程在“增量编译”时没报错但实际没生效强制刷新也没用。如果遇到改文档没反应我的排查顺序很固定先看终端有没有报错再强制刷新浏览器还不行就停掉npm run start重新跑。这个问题大多数时候不是 Docusaurus 本身的 bug而是增量构建缓存和 MDX 语法错误共同导致的不是大问题但挺消磨耐心。5.3 构建成功但页面里出现“_ 未定义”或“React 未定义”这个报错通常是因为在 MDX 文件里直接使用了 JSX 语法但文件没有用.mdx后缀编译器把组件当成了普通文本处理或者是在普通.md中写了import语句构建器不认识。Docusaurus 3.x 对.md文件里的 MDX 语法已经做了有限的支持但涉及组件导入时必须使用.mdx后缀。排查方法很简单看报错文件的后缀把.md改成.mdx即可。改了之后如果还报错就要检查组件文件里有没有语法错误特别是返回 JSX 时有没有写错闭合标签。5.4 本地搜索插件搜不到中文这个问题在我用 Lunr 搜中文时特别明显搜一个两个字的词经常返回空。排查到最后是分词问题Lunr 默认的分词器是按英文空格拆词中文没有空格整个句子会被当作一个 token 处理。换到easyops-cn/docusaurus-search-local之后中文搜索效果好了一大截但还是需要注意插件的搜索索引在构建时生成新增文章后必须重新构建搜索索引才能搜到新内容。5.5 版本发布后旧版本文档出现 404发布新版本后我在旧版本的侧边栏里新增了几个链接结果点进去 404。原因是旧版本的侧边栏配置已经被“冻结”为独立的历史文件不再读取主sidebars.js我手工添加的链接永远不会出现在旧版本里。这种情况正确做法是去versioned_sidebars/里改对应版本的文件或者接受历史版本不再更新侧边栏结构这件事。5.6 Node 版本升级导致的构建报错Docusaurus 3.x 官方要求 Node 18但我在 Node 21 下构建时遇到过几次依赖警告后来干脆固定使用 Node 20 LTS。如果你用 nvm 管理 Node 版本建议在项目根目录放一个.nvmrc文件里面写上20团队协作时大家进入目录执行nvm use就能统一版本避免“我这能构建你那就报错”的尴尬。典型问题常见根因快速排查/解决部署后资源 404baseUrl 与部署路径不匹配检查并修正 baseUrl重新构建热更新失效MDX 语法错误、缓存问题删除缓存目录重启开发服务器JSX 未生效或报错文件后缀不是 .mdx改用 .mdx 后缀检查组件语法中文搜索不到Lunr 分词不支持中文换用支持中文分词的搜索插件旧版本 404版本侧边栏被冻结修改 versioned_sidebars 对应文件构建报错Node 版本或依赖异常固定 Node 20删除 node_modules 重装6. 关于部署、维护节奏和最后一件事6.1 部署到 GitHub Pages、Netlify 或 VercelDocusaurus 的构建产物是纯静态文件npm run build生成到build/目录所以它能部署到几乎所有静态托管平台。GitHub Pages 部署时docusaurus.config.js里还要设置organizationName和projectName然后执行npm run deploy它会自动完成构建、推送到 gh-pages 分支。这里有一个细节npm run deploy需要你设置 GIT_USER 环境变量而且 GitHub 的鉴权方式要用 Personal Access Token否则 push 不上去。Netlify 和 Vercel 的部署更简单仓库连上后填两个字段构建命令npm run build输出目录build平台会自动处理域名和 HTTPS。我个人的感受是如果站点访问量不大Netlify 的免费额度完全够用了而且它自带全球 CDN国内外打开速度都还能接受。6.2 内容维护的节奏与方法论Docusaurus 这类文档站点生成器真正难的不是“搭建”而是“坚持更新”。我在实践中形成了三个维护习惯分享出来供参考。第一文档和代码同仓库管理提交代码带上文档更新不会出现“代码改完了文档还停在上一版”的脱节第二每次发版本前用docs:version冻结一个版本快照保证历史版本随时可回溯第三重要文档页面配上last-updated字段或 Git 上的更新时间读者能直观看到信息新旧程度避免过时文档误导用户。6.3 个人体会写到这里想收个尾但我不喜欢那种“总之、综上所述”的写法。我就说一点自己真实的体会用 Docusaurus 三年多我最大的感觉是它并没有试图用一套模板去框住你的内容而是给了你一套足够顺手的基础设施让你可以把精力释放到内容本身。遇到定制需求官方插件解决不了MDX 和 React 组件也能兜底这种“既有默认路径、又有逃生通道”的设计才是我一直愿意把项目文档往它上面搬的真正原因。如果你正准备做一个项目官网或团队知识库不妨从一条npx create-docusauruslatest命令开始先跑起来再按自己的节奏一步步完善它会值得你投入的时间。
返回列表