Rspress 1-0 正式發佈,基於 Rspack 的高性能靜態站點生成器

今天,我們很高興地跟大家宣佈 Rspress 1.0 正式發佈了!

GitHub 倉庫地址:https://github.com/web-infra-dev/rspress

官網地址:https://rspress.dev

框架定位

Rspress 是由 ByteDance Web Infra 團隊孵化的一款靜態站點生成器,使用 Rspack 進行構建,基於 React 框架進行渲染,支持 MDX 內容開發,主打高性能、簡單易用和定製性強。

Rspress 中內置了一套默認的文檔主題,你可以通過 Rspress 來快速搭建一個文檔站點,同時也可以自定義主題,來滿足你的個性化靜態站需求,比如博客站、產品主頁等。

當然,你也可以接入官方提供的相應插件來方便地搭建組件庫文檔。

項目背景

Rspress 最初的形態是給 Web Infra 團隊內部提供文檔工具,在過去在維護一些稍複雜的文檔項目的過程中,我們圍繞着以下的幾個方向來建設 Rspress 本身的能力:

同時我們意識到這些也代表了 SSG 站點開發的一些核心需求。接下來將會根據這幾個方面分別進行介紹。

構建性能

當項目越來越龐大,團隊成員時常苦惱於冗長的項目啓動時間,開發體驗因此受到了一些負面影響,並且項目開發的時間越長,這種體驗的劣化就越爲明顯。

我們不禁開始思考,是否能跳出目前社區工具鏈的限制,突破現有 SSG 框架的性能瓶頸,實現絕大多數場景的項目秒啓效果?

接着,我們在這個方向上持續地探索,最終在 Rspress 上實現了這樣的效果。以 Rspress 官網文檔的內容爲例,Rspress、Docusaurus 和 Nextra 三者的性能對比情況如下:

如果只說一種最核心的優化手段,那無疑是 Rust 前端工具鏈。我們主要在兩個性能敏感部分使用了 Rust 工具鏈:

與此同時,Rspress 內部也應用了其它的諸多構建優化手段,比如主題包預打包樣式預生成 等等。這些額外的優化手段,配合強有力的 Rust 工具鏈,將 SSG 框架的編譯性能推向了一個嶄新的高度。

MDX 支持

爲了保證內容開發的靈活性,Rspress 選擇支持 MDX 這種內容格式。

因爲 MDX 的背後實際代表了一種組件化的內容組織方式,一方面文檔即組件,那麼我們可以在不同文檔間複用文檔片段,另一方面在文檔中可以引入任何自定義 React 組件,大大釋放了文檔開發的想象力。

文檔站基礎能力

當然,Rspress 在文檔站基礎能力的打磨上也做了相當多的工作,支持瞭如下的功能特性:

擴展機制

在團隊內部我們需要在框架中嵌入一些飛書文檔、點擊關鍵詞展示詞條卡片、MDX 代碼塊自動轉換爲 Playground 組件等等各種能力,這些能力都需要依託於框架本身足夠完善的擴展機制。而 Rspress 的插件機制就是爲了滿足這一系列的擴展能力。

爲了讓更多的人可以參與到這樣有趣的事情中,我們開放了 Rspress 的源碼,歡迎大家一起參與建設。

快速開始

你可以通過如下的命令很方便地開始一個 Rspress 項目:

# npm
npm create rspress@latest
# yarn
yarn create rspress@latest
# pnpm
pnpm create rspress@latest
# bun
bun create rspress@latest

然後執行npm run dev 即可啓動項目。

具體可以參考官網的「快速開始」文檔:https://rspress.dev/zh/guide/start/getting-started.html。

功能特性

接下來我們來介紹 Rspress 的主要功能特性。

自動生成佈局

對於一個文檔站的搭建而言,除了顯示正文內容之外,我們一般還需要以下的幾個佈局模塊:

對於文檔大綱,Rspress 會自動提取文檔中的各級標題,生成大綱信息,並默認展示在文章頁右側,你無需其它操作。

而對於導航欄和側邊欄,我們提供了兩種配置方式,你可以選擇其中一種進行配置:

配置設計遵循奧卡姆剃刀法則,儘可能避免不必要的配置結構,用最簡單的結構描述意圖。關於 _meta.json 的配置詳情你可以閱讀「自動化導航欄 / 側邊欄」文檔 [1]。

我們推薦在一般情況下使用聲明式配置,這樣有諸多的好處:

  1. 配置文件更加簡潔和清晰。

  2. 文件目錄結構側邊欄目錄結構的對應關係更加直觀。

  3. 增加或者刪減側邊欄目錄時,直接在當前目錄中操作,而不用前往 rspress.config.ts 配置文件中定位到相應的位置然後添加 / 刪減配置,從而減少了開發上下文切換的成本。

編程式配置則在某些需要動態生成配置的場景中非常有用,比如 Rspress 官方的 TypeDoc 插件 [3] 會根據 TypeDoc 提供的一份 json 數據自動轉換爲 navsidebar 的配置。

MDX 支持

MDX 是一種功能強大的內容開發方式。你不僅僅可以像往常一樣編寫 Markdown 文件,而且可以在 Markdown 的內容中使用 React 組件:

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

詳情可以查看「使用 MDX」 文檔 [4]。

SSG

Rspress 是一個標準的 SSG 框架,在生產環境的構建中,它會自動幫你生成靜態站點,即生成各個頁面的 HTML 內容,在構建完成之後,HTML 會出現在默認的產物目錄中。

隨後,你可以將這個產物目錄的內容部署到任何靜態站點託管服務上,比如 Github Pages、Netlify、Vercel 等等。

同時,我們也提供了配置讓你能夠很方便地自定義 SSG 生成的 HTML 內容,詳情可以參考「靜態站點生成」文檔 [5]。

國際化(i18n)

國際化在一個文檔類型的站點中是一個很常見的需求,而 Rspress 將國際化的能力封裝得足夠簡單易用,在框架中我們將國際化抽象爲如下的需求:

框架已經爲你支持了這些需求場景,你可以根據官方教程 [6] 來一步步爲你的站點實現國際化。

多版本文檔

在某些場景中,我們需要進行多版本文檔管理,而 Rspress 已經內置了多版本文檔的支持,一方面你可以通過簡單的配置來開啓這個能力,另一方面你只需要按照往常的寫法來組織目錄即可,不引入非必要的目錄和概念,將心智負擔降到最低:

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

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. 基於默認主題擴展。在默認主題的各個組件中,提供了許多插槽讓你能添加自定義的佈局內容,比如接入 documate 提供的 AI 問答組件:
// theme/index.tsx
import Theme from 'rspress/theme'
import { NoSSR } from 'rspress/runtime'
import { Documate } from '@documate/react'
import '@documate/react/dist/style.css'

const Layout = () =(
  <Theme.Layout
    afterNavTitle={
      <NoSSR>
        <Documate endpoint="" />
      </NoSSR>
    }
  />
)

export default {
  ...Theme,
  Layout,
}

export * from 'rspress/theme'

效果如下:

Rspress 中接入 Documate: https://documate.site/integration/rspress

  1. 完全自定義主題。如果你想從頭開發一套自定義主題,可以重新自定義 Layout 的內容,並藉助 Rspress 提供的各個 Runtime API (如 usePageData)來獲取編譯時數據、路由等信息。

關於自定義主題的詳情,你可以參考「自定義主題」文檔 [7]。

插件機制

插件機制是 Rspress 至關重要的部分,它可以讓你在搭建站點的過程中,方便地擴展框架的功能。Rspress 的整體架構如下:

框架整體分爲 Node 端和瀏覽器運行時兩部分,而通過插件機制,你可以輕鬆地擴展這兩部分的功能,比如添加 Markdown/MDX 編譯插件、添加自定義路由、添加自定義全局組件、添加 Rspack 插件等等。

值得注意的是,由於底層的 Rspack 對 webpack 提供了良好的兼容,所以你可以在 Rspress 裏使用社區中大部分的 webpack 插件。

插件機制詳情可以查看介紹文檔 [8]。

目前已有的官方插件包括:

組件文檔

Demo 預覽

Rspress 提供了 preview 插件 [17],可以自動爲你生成組件預覽。當你註冊 preview 插件後,在 mdx 文件中聲明如下的代碼塊:

```jsx
import React from "react";
import { Tag, Space } from "@arco-design/web-react";
import "@arco-design/web-react/dist/css/arco.css";
const COLORS = ["red""orangered""orange""gold""lime""green""cyan""blue""arcoblue""purple""pinkpurple""magenta""gray"];

export default () =(
  <Space wrap>
    {COLORS.map((color, i) =(
      <Tag key={i} color={color}>
        {color}
      </Tag>
    ))}
  </Space>
);

那麼你可以看到如下的預覽效果:

![](https://mmbiz.qpic.cn/mmbiz_png/FuxFc4JogFxaVkwS2RzgciagYtnMYcbL5yjpicErxy93y4wt8F9gOyYV6kBYTCtKKUY3l7EfBdyrPNzyrNpxgicQA/640?wx_fmt=png)

當然,插件同時也支持移動端預覽模式,你可以通過插件配置開啓:

![](https://mmbiz.qpic.cn/mmbiz_png/FuxFc4JogFxaVkwS2RzgciagYtnMYcbL5WN9pJm6UTcs7ob5Qj9a5XibS0ptBnCiaQlYQYZRzcj49oP4CJZHRN8PQ/640?wx_fmt=png)

#### Demo 實時 Playground

對於組件文檔,如果能提供組件的實時編輯的能力,將能大大提高文檔的交互體驗。

爲了實現這個功能,你只需要註冊官方的 playground 插件 [18],然後在 .mdx 文件中聲明你的代碼塊。(這裏以上面的代碼塊爲例)

接着,你將會在文檔中看到下面的 playground 效果:

![](https://mmbiz.qpic.cn/mmbiz_gif/FuxFc4JogFxaVkwS2RzgciagYtnMYcbL5AuMHwccw3SxiaMUGOHOutLs5MdzppI55R4vaVhMzA7vBicMu1CWqw0qw/640?wx_fmt=gif)

### 內置流暢的轉場動畫

View Transition API[19] 是現代瀏覽器原生提供的一組 API,用於實現頁面跳轉過程中的過渡效果。在 Rspress 中我們也跟進了這個特性,基於 View Transition 實現了文檔的過渡動畫,而未使用任何第三方 SPA 的動畫方案。在未來,我們也會探索出更多的動畫效果,進一步提升體驗。

export default defineConfig({   themeConfig: {     // 開啓 View Transition 過渡     enableContentAnimation: true,   }, });


未來規劃
----

### 完善基礎能力

Rspress 目前提供的功能已經能夠滿足大多數的 SSG 項目使用,同時我們也在未來會根據社區反饋,豐富 Rspress 的基礎能力,滿足更多場景的需求。

### 補齊 mdx-rs 功能

雖然 mdx-rs 的編譯能力已經能勝任大部分場景的純文檔類開發場景,但目前仍然存在一些不能滿足需求的場景,如 preview 插件和 playground 插件,我們將進一步完善這些常用能力。

### 自定義主題

除了默認的文檔主題,我們也會在未來給 Rspress 添加更豐富的主題,歡迎社區的小夥伴們來貢獻 👏🏻

### 更加豐富的插件能力

未來我們也會提供更多的官方插件能力,比如:

*   BackTop 插件,在頁面中增加回到頂部效果。
    
*   Google Analytics 插件,給站點集成谷歌分析,收集網站訪問數據。
    
*   Sitemap 插件,在構建階段生成 sitemap 文件。
    
*   PWA 插件,提供 PWA 集成。
    
*   Client Redirect 插件,提供路由重定向能力。
    
*   ......
    

### 持續優化性能和質量

性能是 Rspress 的關鍵優勢,隨着項目的不斷迭代,我們會逐步建立起完善的性能觀測機制,防止性能劣化,尋找潛在的性能提升點,給社區用戶持續提供良好的開發體驗。

同時,我們也會不斷地完善功能測試用例,提升測試覆蓋率,保障項目長期的健康發展。

致謝
--

Rspress 的設計受到了社區中諸多項目的啓發和支持,在這裏對這些前輩表示致敬和感謝:

*   VitePress[20] 項目(由 @尤雨溪 創建),其中 SSG 的實現架構爲 Rspress 提供了參考。
    
*   Vuepress[21] 項目(由 @尤雨溪 和 @ulivz 創建),其中的插件機制設計啓發了 Rspress 的插件 API 設計。
    
*   Nextra[22] 項目(由 @shuding 創建),Rspress 的 `_meta.json` 設計靈感來自於此,並在 Nextra 的基礎上進行了簡化。
    
*   mdxjs-rs[23] 項目(由 @wooorm 創建),給 @rspress/mdx-rs 節省了諸多的開發成本。
    
*   NAPI-RS[24] 項目(由 @Brooooooklyn 創建),爲 mdx-rs 的 node-binding 實現提供了支持。
    
*   Dumi[25](由 @PeachScript 創建),給 Rspress 的移動端組件 Demo 預覽功能提供了設計上的參考。
    

### 參考資料

[1]

「自動化導航欄 / 側邊欄」文檔: _https://rspress.dev/zh/guide/basic/auto-nav-sidebar.html_

[2]

「API 文檔」: _https://rspress.dev/zh/api/config/config-theme.html#nav_

[3]

TypeDoc 插件: _https://rspress.dev/plugin/official-plugins/typedoc.html_

[4]

「使用 MDX」 文檔: _https://rspress.dev/zh/guide/basic/use-mdx.html_

[5]

「靜態站點生成」文檔: _https://rspress.dev/zh/guide/basic/ssg.html_

[6]

官方教程: _https://rspress.dev/zh/guide/default-theme/i18n.html_

[7]

「自定義主題」文檔: _https://rspress.dev/zh/guide/advanced/custom-theme.html_

[8]

介紹文檔: _https://rspress.dev/zh/plugin/system/introduction.html_

[9]

@rspress/plugin-medium-zoom: _https://rspress.dev/zh/plugin/official-plugins/medium-zoom.html_

[10]

medium-zoom: _https://github.com/francoischalifour/medium-zoom_

[11]

@rspress/plugin-last-updated: _https://rspress.dev/zh/plugin/official-plugins/last-updated.html_

[12]

@rspress/plugin-container-syntax: _https://rspress.dev/zh/plugin/official-plugins/container-syntax.html_

[13]

@rspress/plugin-typedoc: _https://rspress.dev/zh/plugin/official-plugins/typedoc.html_

[14]

TypeDoc: _https://github.com/TypeStrong/typedoc_

[15]

@rspress/plugin-preview: _https://rspress.dev/zh/plugin/official-plugins/preview.html_

[16]

@rspress/plugin-playground: _https://rspress.dev/zh/plugin/official-plugins/playground.html_

[17]

preview 插件: _https://rspress.dev/zh/plugin/official-plugins/preview_

[18]

playground 插件: _https://rspress.dev/zh/plugin/official-plugins/playground.html_

[19]

View Transition API: _https://developer.mozilla.org/zh-CN/docs/Web/API/View_Transitions_API_

[20]

VitePress: _https://vitepress.vuejs.org/_

[21]

Vuepress: _https://vuepress.vuejs.org/_

[22]

Nextra: _https://nextra.site/_

[23]

mdxjs-rs: _https://github.com/wooorm/mdxjs-rs_

[24]

NAPI-RS: _https://github.com/napi-rs/napi-rs_

[25]

Dumi: _https://github.com/umijs/dumi_
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/VOei4yfwBkRRDOGRhBXbJA