close

介绍

Rspress 是一个基于 Rsbuild 的静态站点生成器,使用 React 进行渲染,内置了一套默认的文档主题。你可以通过 Rspress 快速搭建文档站点,也可以自定义主题来满足个性化的静态站需求,如博客站、产品主页等。此外,你还可以接入官方提供的插件来便捷地搭建组件库文档。

为什么选择 Rspress

Rspress 主要围绕以下几个核心特性进行设计:

  • 构建性能。保证足够快的启动速度,带来良好的开发体验。
  • AI-native。技术文档不仅服务于人类读者,也可以通过 SSG-MD 被 AI 更好地理解和使用。
  • 主题与定制能力。提供全新默认主题,并支持 CSS 变量、BEM 类名、重导出和 eject 等多种定制方式。
  • MDX 支持。通过 MDX,我们可以方便地复用文档片段,以及在文档中渲染自定义的 React 组件。
  • 文档开发体验。围绕导航配置、代码块、死链检查等能力持续优化日常写作文档的体验。
  • 文档站基础能力。包括国际化、多版本支持、全文搜索、组件库文档等。
  • 可扩展性。内置插件系统,支持通过插件 API 来扩展功能。

这些也代表了静态站点开发的一些核心需求。接下来将会根据这几个方面分别进行介绍。

构建性能

随着项目规模不断扩大,团队成员常常受困于冗长的项目启动时间,开发体验因此受到影响,而且项目开发时间越长,这种体验的劣化就越明显。

我们不禁开始思考,是否能跳出目前社区工具链的限制,突破现有 SSG 框架的性能瓶颈,实现绝大多数场景的项目秒启效果?

接着,我们在这个方向上持续地探索,最终在 Rspress 上实现了这样的效果。

Rspress 通过多种优化手段实现了显著的性能提升:

  • LazyCompilation。lazyCompilation 会在 dev 模式下按需编译。只有当你访问某个页面时,该页面才会被编译,大幅提升了开发启动速度,甚至实现毫秒级的冷启动。
  • 路由预加载。当鼠标悬停在链接上时,Rspress 会预先加载目标路由页面,搭配按需编译实现近乎无损的开发体验。
  • 持久化缓存。对于 build 生产构建中,默认开启了持久化缓存,在热启动中复用上次编译的结果,提升 30%-60% 的构建速度。
  • Rspack Bundler。Rspress 使用了团队内部自研的 Rspack,Rspack 是一个基于 Rust 的 Bundler,内置多种性能优化手段,比如多线程并行编译、增量编译等等,相比社区传统的打包工具,有 5 ~ 10 倍的性能提升。

与此同时,Rspress 内部也应用了其它诸多构建优化手段。这些优化手段,配合强大的 Rust 工具链,将 SSG 框架的编译性能推向了一个崭新的高度。

AI-native

随着大语言模型的普及,技术文档不仅服务于人类读者,也需要被 AI 更好地理解和使用。

Rspress 提供了 SSG-MD 能力,它将页面渲染为 Markdown 文件而非 HTML 文件,并生成符合 llms.txt 规范的索引文件。

rspress.config.ts
import { defineConfig } from '@rspress/core';

export default defineConfig({
  llms: true,
});

启用后,构建产物中会包含 llms.txt(按导航和侧边栏顺序展示各页面标题与描述的索引文件)、llms-full.txt(包含所有页面 Markdown 内容的完整文件)以及各路由对应的 .md 文件。

对于自定义组件,你还可以通过 import.meta.env.SSG_MD 在 SSG-MD 模式下输出更适合 AI 理解的纯文本内容,从而兼顾页面交互体验与静态信息质量。

正如 SSG 可以生成静态 HTML 文件提高 SEO,SSG-MD 也可以相对提升 GEO(Generative Engine Optimization)和给大模型的静态信息质量。

详细用法请参考 SSG-MD 文档

除构建性能与 AI-native 之外,Rspress 还提供默认主题、自动布局、MDX、Shiki 代码高亮、国际化、多版本文档、全文搜索以及插件机制等能力。下面会继续展开这些功能特性。

默认主题与定制

Rspress 提供了一套设计完整的默认主题,在视觉效果和阅读体验上都有良好表现,同时提供了很高的可定制性。

主题定制

/* 轻松覆盖组件样式 */
.rp-nav__title {
  height: 32px;
}
.rp-nav-menu__item--active {
  color: purple;
}

默认主题暴露了更多 CSS 变量,覆盖主题色、代码块、首页等组件样式;所有内置组件均采用 BEM 命名规范,方便通过标准 CSS 选择器覆盖样式;如果 CSS 不足以满足需求,还可以通过 theme/index.tsx 的 ESM 重导出机制覆盖内置组件。

rspress eject 命令

当 CSS 变量无法满足定制需求时,你可以使用 rspress eject 命令将内置组件的源代码复制到项目的主题目录中,实现完全自定义。

# 将 Nav 组件导出到 theme 目录
npx rspress eject Nav

导航栏、侧边栏 tag

Rspress 提供了 Tag 组件,你可以在 frontmatter 中声明 tag,并在标题、导航栏、侧边栏和大纲中展示标记信息。

自动生成布局

对于一个文档站的搭建而言,除了显示正文内容之外,我们一般还需要以下的几个布局模块:

  • 导航栏,用于提供全局性的导航入口;
  • 侧边栏,用于展示当前导航下的文章目录;
  • 文章大纲栏,用于展示当前页面的大纲结构。

对于文档大纲,Rspress 会自动提取文档中的各级标题,生成大纲信息,并默认展示在文章页右侧,你无需其它操作。

而对于导航栏和侧边栏,我们提供了两种配置方式,你可以选择其中一种进行配置:

  • 声明式配置。通过在目录中声明 _meta.json 来配置对应的数据,比如:
_meta.json
["introduction", "install", "start"]

配置详情你可以阅读「自动化导航栏/侧边栏」文档

  • 编程式配置。通过在 Rspress 配置中指定 navsidebar 配置项来实现。

我们推荐在一般情况下使用声明式配置,这样有诸多的好处:

  1. 配置文件更加简洁和清晰。
  2. 文件目录结构侧边栏目录结构的对应关系更加直观。
  3. 增加或者删减侧边栏目录时,直接在当前目录中操作,而不用前往 rspress.config.ts 配置文件中定位到相应的位置然后添加/删减配置,从而减少了开发上下文切换的成本。

编程式配置则在某些需要动态生成配置的场景中非常有用,比如 Rspress 官方的 TypeDoc 插件 会根据 TypeDoc 提供的一份 json 数据自动转换为 navsidebar 的配置。

MDX 支持

MDX 是一种功能强大的内容开发方式。你不仅仅可以像往常一样编写 Markdown 文件,而且可以在 Markdown 的内容中使用 React 组件:

除此之外,Rspress 还支持了一些特定的语法,如:

  • 自定义容器语法。
  • FrontMatter 元数据定义。
  • 代码行高亮语法。

详情可以查看「使用 MDX」 文档

集成 Shiki 用于代码块高亮

Rspress 默认使用 Shiki 进行代码高亮。相比运行时高亮方案,Shiki 在编译时完成高亮处理,基于 TextMate 语法实现与 VS Code 一致的准确语法高亮,不增加运行时开销和包体积。

可以通过 CSS 变量自定义代码块的配色方案,在 CSS 变量 页面可以交互式地切换和预览不同的 Shiki 主题。同时 Shiki 也允许使用自定义的 transformer 进行扩展来丰富写作,如 twoslash

文档开发体验

Rspress 在文档开发体验上也做了系统性优化:

  • 默认开启死链检查,在构建过程中自动检测无效链接。
  • 支持文件代码块语法,通过 file="./path/to/file" 直接引用外部示例代码。
  • preview 插件改为基于 meta 属性配置,能更灵活地与文件代码块配合使用。
  • previewplayground 插件现在可以同时接入,适合组件库和交互示例文档场景。

关于 previewplayground 的实际写法,可以直接查看下文的组件文档章节。

SSG

Rspress 是一个标准的 SSG 框架,在生产环境的构建中,它会自动帮你生成静态站点,即生成各个页面的 HTML 内容,在构建完成之后,HTML 会出现在默认的产物目录中。

随后,你可以将这个产物目录的内容部署到任何静态站点托管服务上,比如 GitHub Pages、Netlify、Vercel 等等。

同时,我们也提供了配置让你能够很方便地自定义 SSG 生成的 HTML 内容,详情可以参考「静态站点生成」文档

国际化(i18n)

国际化是文档站点的常见需求,Rspress 将国际化能力封装得简单易用,我们将其抽象为如下需求:

  • 如何定义 I18n 数据源?
  • 如何进行不同语言下的站点配置?
  • 如何组织不同语言版本的文档目录?
  • 如何自定义组件中使用 I18n 数据源?

Rspress 主题内置了中文、英文、日文、韩文等多种语言的翻译文本,未来会支持更多语言,系统会自动根据语言配置和使用进行 "Tree Shaking",仅打包你需要的文本。你也可以通过 i18nSource 配置项轻松扩展或覆盖翻译内容。

你可以根据 I18n 教程 来一步步为你的站点实现国际化。

多版本文档

在某些场景中,我们需要进行多版本文档管理,而 Rspress 已经内置了多版本文档的支持,一方面你可以通过简单的配置来开启这个能力,另一方面你只需要按照往常的写法来组织目录即可,不引入非必要的目录和概念,将心智负担降到最低:

// 配置文件
import { defineConfig } from '@rspress/core';

export default defineConfig({
  multiVersion: {
    default: 'v1',
    versions: ['v1', 'v2'],
  },
});
// 目录结构
docs
v1
README.md
guide
README.md
v2
README.md
guide
README.md

全文搜索

Rspress 中提供开箱即用的全文搜索能力,你无需任何配置即可接入,底层基于开源的 FlexSearch 引擎实现,效果如下:

自定义主题

Rspress 支持两种自定义主题的方式:

  1. 基于默认主题扩展。在默认主题的各个组件中,提供了许多插槽让你能添加自定义的布局内容,比如
// theme/index.tsx
import { Layout as BasicLayout } from '@rspress/core/theme-original';

const Layout = () => <BasicLayout beforeNavTitle={<p>Custom Block</p>} />;

export { Layout };
export * from '@rspress/core/theme-original';
  1. 完全自定义主题。如果你想从头开发一套自定义主题,可以重新自定义 Layout 的内容,并借助 Rspress 提供的各个 Runtime API (如 usePageData)来获取编译时数据、路由等信息。

关于自定义主题的详情,你可以参考「自定义主题」文档

插件机制

插件机制是 Rspress 至关重要的部分,它可以让你在搭建站点的过程中,方便地扩展 Rspress 的功能。详情可以查看插件介绍文档

组件文档

Rspress 通过 @rspress/plugin-preview@rspress/plugin-playground 提供组件预览与实时编辑能力,适合组件库文档和交互式示例。

组件库 Demo 预览

在 mdx 文件中使用 ```tsx preview 的语法:

```tsx playground
import { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  return (
    <div style={{ textAlign: 'center' }}>
      <p>当前计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
}

export default App;
```

它的渲染结果如下:

当前计数: 0

import { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  return (
    <div style={{ textAlign: 'center' }}>
      <p>当前计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
}

export default App;

如果你希望把示例代码拆分到外部文件,也可以配合文件代码块一起使用,详见 @rspress/plugin-preview

组件库 Demo 实时 playground

在 mdx 文件中使用 ```tsx playground 的语法:

```tsx playground
import { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  return (
    <div style={{ textAlign: 'center' }}>
      <p>当前计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
}

export default App;
```

它的渲染结果如下:

当前计数: 0

import { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  return (
    <div style={{ textAlign: 'center' }}>
      <p>当前计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </div>
  );
}

export default App;

关于 iframe 预览模式、布局方向以及与 preview 联用的方式,请参考 @rspress/plugin-playground

与其它 SSG 框架的区别

与 Docusaurus 的区别

Docusaurus 是 Meta 开源的一款 SSG 框架,它和 Rspress 一样使用 React 作为渲染框架,且支持 MDX,但 Rspress 与 Docusaurus 的区别主要在于:

  1. Rspress 通过 lazyCompilation 和持久化缓存提供更好的构建性能,实现毫秒级的冷启动,详见构建性能
  2. Rspress 的配置更简单,上手成本更低。Rspress 的配置更加简单,不引入过多的概念,尽可能降低心智负担,比如提供开箱即用的搜索功能、符合直觉的多版本文档管理方式等等。
  3. Rspress 架构上对 Bundler 提供了更上层的抽象。对于 webpack、Rspack 这类底层的 Bundler,其配置项繁琐且不易上手。Docusaurus 选择直接暴露底层 Bundler 的配置项,而 Rspress 则对 Bundler 进行了更上层的抽象,提供了更加简单易用的配置项,比如你可以通过 builderConfig.html.tags 轻松添加 <head> 中的标签,而不用通过 Bundler 来注册 html-webpack-plugin 相关插件。

与 Nextra 的区别

Nextra 是 Vercel 开源的一款 SSG 框架,它也和 Rspress 一样使用 React 作为渲染框架,且支持 MDX。Rspress 与 Nextra 的区别主要在于:

  1. Rspress 的构建性能更好。这一点可参考「与 Docusaurus 的区别」。
  2. Rspress 整体更加轻量。Nextra 需要依赖 Next.js,其 SSG 流程也是基于 Next.js 的,因此 SSG 产物中并非纯粹的 HTML 文件,而是额外包含了一些 Next.js 的运行时代码,一方面导致了 Nextra 的产物体积更大,另一方面需要在部署时以应用的方式部署(使用 next start 命令),而不能以纯静态站点的方式部署。但 Rspress 没有和任何应用框架绑定,因此产物更加轻量,可以很方便地以纯静态站点的方式部署。

与 VitePress 的区别

VitePress 是一款基于 Vite 静态站点生成器,它的特点是使用 Vue 作为渲染框架,且性能非常优秀。Rspress 与 VitePress 的区别主要在于:

  1. Rspress 使用 React 作为渲染框架,而 VitePress 使用 Vue 作为渲染框架。
  2. Rspress 使用 MDX 作为内容开发方式,而 VitePress 使用 Markdown 作为内容开发方式,并在 Markdown 中支持 Vue 组件,这同时也导致了底层编译工具链实现上的差异。
  3. 构建性能上,在开发阶段,Rspress 和 VitePress 都能很快地启动一个项目,而在生产环境下,VitePress 需要基于 Rollup 打包项目,因此会面临其他基于 JavaScript 的工具链类似的性能问题,此时 Rspress 会有更快的构建速度。

尝试 Rspress

进入快速开始了解如何使用 Rspress 快速搭建一个文档站点。