換碼
在這部分中,我們將介紹如何在 Docusaurus 中自訂佈局。
似曾相似?
這部分與 造型與佈局 類似,但這次我們將自訂 React 元件本身,而非它們的樣式。我們將探討 Docusaurus 中一個重要的概念:換碼,它能讓您進行更深入的網站自訂。
實際上,換碼允許您將主題元件與您自己的實作交換,而且它有 2 種模式
為什麼稱為換碼?
名稱源自 Objective-C 和 Swift-UI:方法調換是更改現有選擇器(方法)執行的過程。
對於 Docusaurus,組件調換意指提供替代組件,此組件優先於主題提供的組件。
你可以將其視為 React 組件的 猴子修補程式,使你能夠覆寫預設執行方式。Gatsby 有個類似的概念,稱為 主題陰影。
要更深入地了解這個概念,你必須明白 主題組件是如何解析的。
調換程序
概述
Docusaurus 提供了一個方便的互動式 CLI,用於調換組件。你通常只需要記住下列指令
- npm
- Yarn
- pnpm
npm run swizzle
yarn swizzle
pnpm run swizzle
它會在你的 src/theme
目錄中產生一個新的組件,其長相應如下所示
- 退出
- 包裝
import React from 'react';
export default function SomeComponent(props) {
// You can fully customize this implementation
// including changing the JSX, CSS and React hooks
return (
<div className="some-class">
<h1>Some Component</h1>
<p>Some component implementation details</p>
</div>
);
}
import React from 'react';
import SomeComponent from '@theme-original/SomeComponent';
export default function SomeComponentWrapper(props) {
// You can enhance the original component,
// including adding extra props or JSX elements around it
return (
<>
<SomeComponent {...props} />
</>
);
}
要取得可以調換的所有主題和組件的概述,請執行
- npm
- Yarn
- pnpm
npm run swizzle -- --list
yarn swizzle --list
pnpm run swizzle --list
使用 --help
來查看所有可用的 CLI 選項,或參考 swizzle CLI 文件。
在調換組件後,重新啟動 dev 伺服器,讓 Docusaurus 得知新組件。
務必了解 哪些組件可以安全地調換。有些組件是主題的內部實作細節。
docusaurus swizzle
僅是一種自動化方法,有助於您調整組件。您也可以手動建立 src/theme/SomeComponent.js
檔案,Docusaurus 會解析它。此命令背後沒有內部的魔術!
退出
退出主題組件是建立原始主題組件副本的程序,您可以對其進行完全自訂和覆寫。
要退出主題組件,請互動使用 swizzle CLI 或與 --eject
選項一起使用
- npm
- Yarn
- pnpm
npm run swizzle [theme name] [component name] -- --eject
yarn swizzle [theme name] [component name] --eject
pnpm run swizzle [theme name] [component name] --eject
範例
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic Footer -- --eject
yarn swizzle @docusaurus/theme-classic Footer --eject
pnpm run swizzle @docusaurus/theme-classic Footer --eject
這將會複製目前 <Footer />
組件的實作至您網站的 src/theme
目錄。Docusaurus 現將使用此 <Footer>
組件副本而非原件。您現在可以自由重新實作 <Footer>
組件。
import React from 'react';
export default function Footer(props) {
return (
<footer>
<h1>This is my custom site footer</h1>
<p>And it is very different from the original</p>
</footer>
);
}
要在 Docusaurus 升級後,讓已退出的組件保持最新狀態,請重新執行退出命令,並使用 git diff
比較變更。建議您在檔案開頭寫一段簡短的註解,說明您所做的變更,這樣您就能在重新退出後更容易地重新套用您的變更。
包裝
包裝主題組件是建立一個外殼的程序,這個外殼會包圍原始的主題組件,而您可以強化它。
要包裝一個主題組件,互動使用 swizzle CLI 或與 --wrap
選項一起使用
- npm
- Yarn
- pnpm
npm run swizzle [theme name] [component name] -- --wrap
yarn swizzle [theme name] [component name] --wrap
pnpm run swizzle [theme name] [component name] --wrap
範例
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic Footer -- --wrap
yarn swizzle @docusaurus/theme-classic Footer --wrap
pnpm run swizzle @docusaurus/theme-classic Footer --wrap
這會在您網站的 src/theme
目錄中建立外層包裝。Docusaurus 現在會使用 <FooterWrapper>
元件,而不是原本的元件。您現在可以在原本的元件周圍加入自訂內容。
import React from 'react';
import Footer from '@theme-original/Footer';
export default function FooterWrapper(props) {
return (
<>
<section>
<h2>Extra section</h2>
<p>This is an extra section that appears above the original footer</p>
</section>
<Footer {...props} />
</>
);
}
這個 @theme-original
是什麼東西?
Docusaurus 使用 主題別名 來解析要使用的主題元件。新建立的外層包裝會使用 @theme/SomeComponent
別名。@theme-original/SomeComponent
允許匯入外層包裝覆寫的原始元件,而不會建立外層包裝會自己匯入自己的無限匯入迴圈。
對一個主題進行外層包裝是很棒的方法,可以在現有元件周圍加入額外元件,而不必移除它。例如,您可以在每個部落格文章下方輕鬆加入自訂留言系統
import React from 'react';
import BlogPostItem from '@theme-original/BlogPostItem';
import MyCustomCommentSystem from '@site/src/MyCustomCommentSystem';
export default function BlogPostItemWrapper(props) {
return (
<>
<BlogPostItem {...props} />
<MyCustomCommentSystem />
</>
);
}
什麼是可以安全替換的?
能力越大,責任越大
某些主題元件是一個主題的實作內部細節。Docusaurus 允許您替換這些元件,但這可能有風險。
為什麼會有風險?
主題作者(包括我們團隊)未來可能需要更新他們的主题:變更元件屬性、名稱、檔案系統位置、類型等。例如,考慮一個接收兩個屬性 name
和 age
的元件,但重新整理後,此元件現在接收一個包含兩個上面屬性的 person
屬性。您的元件仍然預期這兩個屬性,將會呈現 undefined
而不是這些屬性。
此外,內部元件可能會完全消失。如果一個元件稱為 Sidebar
,後續改名為 DocSidebar
,您替換過的元件將會完全被忽略。
標示為不安全的主题元件,在主版本之間可能以不向後相容的方式變更。在更新一個主题(或 Docusaurus)時,您的自訂內容可能會出現異常行為,甚至造成您的網站故障。
對於每個主题元件,替換 CLI 將會指出三個不同的安全等級,由主题作者宣告
- 安全:此元件可以安全地替換,其公開的 API 被視為穩定,而且在一個主题主要版本中不會發生重大變更
- 不安全:此元件是主题實作內部細節,不適合替換,而且在一個主题次要版本中可能會發生重大變更
- 禁止:swizzle CLI 會禁止你 swizzle 這個元件,因為它完全不是設計成可以進行 swizzle 的
有些元件可能可以安全地包覆,但不能安全地彈出。
不要太害怕 swizzle 不安全的元件:只要記住可能發生重大變更,且你可能需要在次要版本升級時手動升級你的自訂。
如果你有需要 swizzle 不安全元件的強烈使用案例,請在此報告,讓我們共同努力找出解決方案來讓它安全。
我應該 swizzle 哪個元件?
並不總是清楚你應該 swizzle 哪個元件才能達成預期的結果。提供大部分主題元件的 @docusaurus/theme-classic
有大約100 個元件!
若要列印所有 @docusaurus/theme-classic
元件的概觀
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic -- --list
yarn swizzle @docusaurus/theme-classic --list
pnpm run swizzle @docusaurus/theme-classic --list
你可以按照下列步驟找到適當的元件來 swizzle
- 元件說明。有些元件提供了簡短的說明,這是找出正確元件的好方法。
- 元件名稱。正式的主題元件有語意化的命名,因此你應該可以從名稱中推論其功能。swizzle CLI 允許你輸入元件名稱的一部分,以縮小可用選項。例如,如果你執行
yarn swizzle @docusaurus/theme-classic
,並輸入Doc
,將只會列出與文件相關的元件。 - 從較高層級的元件開始。元件會形成一個樹狀結構,有些元件會匯入其他元件。每個路由會與一個由該路由要渲染的頂層元件關聯(大部分都列在內容外掛程式的路由中)。例如,所有部落格文章頁面都會將
@theme/BlogPostPage
設定為最上層的元件。你可以從 swizzle 這個元件開始,然後向下探索元件樹狀結構,以找到僅渲染你要目標的元件。記得在你找到正確的元件之後,刪除檔案並解除其他元件的 swizzle,這樣你就不會有太多元件要維護了。 - 閱讀 主題原始碼 並明智地使用搜尋功能。
我必須調用嗎?
調用最終表示您必須維護一些額外的 React 程式碼,這些程式碼會與 Docusaurus 內部 API 互動。您可以思考下列替代方案,自訂您的網站
- 使用 CSS。 CSS 規則和選擇器常常能協助您達成相當程度的自訂。請參閱 造型和版面,深入了解詳細資訊。
- 使用翻譯。這或許聽起來令人驚訝,但翻譯最終只不過是用於自訂文字標籤的方法。舉例來說,如果您的網站預設語言為
en
,您仍然可以執行yarn write-translations -l en
,並編輯所產生的code.json
。請參閱 i18n 教學課程,深入了解詳細資訊。
使用 <Root>
包裝您的網站
<Root>
元件會呈現在 React 樹狀結構的 最上方,高於主題 <Layout>
,而且絕不會取消掛載。這是新增狀態邏輯的絕佳處,這個邏輯不應在導覽期間重新初始化(使用者驗證狀態、購物車狀態等)。
在 src/theme/Root.js
創建一個檔案,手動調用它
import React from 'react';
// Default implementation, that you can customize
export default function Root({children}) {
return <>{children}</>;
}
使用這個元件來呈現在 React 的 Context 供應商。