生命週期 API
在建置期間,外掛程式會並行載入,以擷取自己的內容並將其呈現至路線。外掛程式也可以設定 webpack 或後續處理已建立的檔案。
async loadContent()
外掛程式應使用此生命週期從資料來源(檔案系統、遠端 API、無頭 CMS 等等)擷取或執行一些伺服器處理。傳回值便是其需要的內容。
例如,下列外掛程式會傳回 1 到 10 之間的亂數整數作為內容。
export default function (context, options) {
return {
name: 'docusaurus-plugin',
async loadContent() {
return 1 + Math.floor(Math.random() * 10);
},
};
}
async contentLoaded({content, actions})
於 loadContent
中載入的資料將在 contentLoaded
中使用。它可以呈現至路線、註冊為全域資料等等。
content
contentLoaded
將於 loadContent
之後被呼叫。loadContent()
的傳回值會以 content
傳遞至 contentLoaded
。
動作
動作
包含三個函數
addRoute(config: RouteConfig): void
建立一個加入網站的路徑。
export type RouteConfig = {
/**
* With leading slash. Trailing slash will be normalized by config.
*/
path: string;
/**
* Component used to render this route, a path that the bundler can `require`.
*/
component: string;
/**
* Props. Each entry should be `[propName]: pathToPropModule` (created with
* `createData`)
*/
modules?: RouteModules;
/**
* The route context will wrap the `component`. Use `useRouteContext` to
* retrieve what's declared here. Note that all custom route context declared
* here will be namespaced under {@link RouteContext.data}.
*/
context?: RouteModules;
/**
* Nested routes config, useful for "layout routes" having subroutes.
*/
routes?: RouteConfig[];
/**
* React router config option: `exact` routes would not match subroutes.
*/
exact?: boolean;
/**
* React router config option: `strict` routes are sensitive to the presence
* of a trailing slash.
*/
strict?: boolean;
/**
* Used to sort routes.
* Higher-priority routes will be matched first.
*/
priority?: number;
/**
* Optional route metadata
*/
metadata?: RouteMetadata;
/**
* Extra props; will be available on the client side.
*/
[propName: string]: unknown;
};
/**
* Plugin authors can assign extra metadata to the created routes
* It is only available on the Node.js side, and not sent to the browser
* Optional: plugin authors are encouraged but not required to provide it
*
* Some plugins might use this data to provide additional features.
* This is the case of the sitemap plugin to provide support for "lastmod".
* See also: https://github.com/facebook/docusaurus/pull/9954
*/
export type RouteMetadata = {
/**
* The source code file path that led to the creation of the current route
* In official content plugins, this is usually a Markdown or React file
* This path is expected to be relative to the site directory
*/
sourceFilePath?: string;
/**
* The last updated date of this route
* This is generally read from the Git history of the sourceFilePath
* but can also be provided through other means (usually front matter)
*
* This has notably been introduced for adding "lastmod" support to the
* sitemap plugin, see https://github.com/facebook/docusaurus/pull/9954
*/
lastUpdatedAt?: number;
};
type RouteModules = {
[module: string]: Module | RouteModules | RouteModules[];
};
type Module =
| {
path: string;
__import?: boolean;
query?: ParsedUrlQueryInput;
}
| string;
createData(name: string, data: any): Promise<string>
建立靜態資料(通常是 JSON 或字串)的宣告式回呼,稍後可以將此資料作為道具提供給您的路徑。取得要儲存的檔案名稱和資料,並傳回實際資料檔案路徑。
例如,以下外掛會建立一個顯示 您的朋友是:Yangshun、Sebastien
的 /friends
頁面
import React from 'react';
export default function FriendsComponent({friends}) {
return <div>Your friends are {friends.join(',')}</div>;
}
export default function friendsPlugin(context, options) {
return {
name: 'docusaurus-friends-plugin',
async contentLoaded({content, actions}) {
const {createData, addRoute} = actions;
// Create friends.json
const friends = ['Yangshun', 'Sebastien'];
const friendsJsonPath = await createData(
'friends.json',
JSON.stringify(friends),
);
// Add the '/friends' routes, and ensure it receives the friends props
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
modules: {
// propName -> JSON file path
friends: friendsJsonPath,
},
exact: true,
});
},
};
}
setGlobalData(data: any): void
這個函數允許建立一些可以從任何頁面(包括其他外掛建立的頁面和主題配置)讀取的全球外掛資料。
此資料可透過 useGlobalData
和 usePluginData
鉤子讓您的客戶端/主題程式碼存取。
全球資料具…全球性,它的大小會影響網站上所有頁面的載入時間,因此請儘量保持縮小。在可能的情況下,請優先選擇 createData
和特定頁面的資料。
例如,以下外掛會建立一個顯示 您的朋友是:Yangshun、Sebastien
的 /friends
頁面
import React from 'react';
import {usePluginData} from '@docusaurus/useGlobalData';
export default function FriendsComponent() {
const {friends} = usePluginData('docusaurus-friends-plugin');
return <div>Your friends are {friends.join(',')}</div>;
}
export default function friendsPlugin(context, options) {
return {
name: 'docusaurus-friends-plugin',
async contentLoaded({content, actions}) {
const {setGlobalData, addRoute} = actions;
// Create friends global data
setGlobalData({friends: ['Yangshun', 'Sebastien']});
// Add the '/friends' routes
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
exact: true,
});
},
};
}
configureWebpack(config, isServer, utils, content)
修改內部 webpack 設定。如果傳回值是 JavaScript 物件,它會使用 webpack-merge
與最終設定合併。如果是一個函數,會呼叫它並傳入 config
作為第一個引數和 isServer
標記作為第二個引數。
configureWebpack
的 API 將會在未來修改為接受物件(configureWebpack({config, isServer, utils, content})
)
config
configureWebpack
會使用依據客戶端/伺服器建置所產生的 config
呼叫。您可以將此設定視為要與之合併的基本設定。
isServer
configureWebpack
會在伺服器建置和客戶端建置中同時呼叫。伺服器建置會收到 true
,而客戶端建置會收到 false
作為 isServer
。
utils
configureWebpack
也接收一個 util 物件
getStyleLoaders(isServer: boolean, cssOptions: {[key: string]: any}): Loader[]
getJSLoader(isServer: boolean, cacheOptions?: {}): Loader | null
你可以使用它們來有條件地傳回 webpack 組態。
例如,以下這個外掛會修改 webpack 組態,以轉譯 .foo
檔案。
export default function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
const {getJSLoader} = utils;
return {
module: {
rules: [
{
test: /\.foo$/,
use: [getJSLoader(isServer), 'my-custom-webpack-loader'],
},
],
},
};
},
};
}
content
configureWebpack
將使用這個外掛載入的內容同時呼叫。
合併策略
我們使用 webpack-merge 將外掛的 Webpack 組態部分合併到全域 Webpack 組態中。
可以指定合併策略。例如,如果你想讓 webpack 規則是新增至最前面而非附加在最後面
export default function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
return {
mergeStrategy: {'module.rules': 'prepend'},
module: {rules: [myRuleToPrepend]},
};
},
};
}
請參閱 webpack 合併策略文件 以取得更多詳細資料。
設定開發伺服器
開發伺服器能透過傳回 devServer
欄位設定。
export default function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
return {
devServer: {
open: '/docs', // Opens localhost:3000/docs instead of localhost:3000/
},
};
},
};
}
configurePostCss(options)
修改 postcss-loader
的 postcssOptions
,以用於產生用戶端套件。
應傳回變異過的 postcssOptions
。
預設值 postcssOptions
為下所示
const postcssOptions = {
ident: 'postcss',
plugins: [require('autoprefixer')],
};
範例
export default function (context, options) {
return {
name: 'docusaurus-plugin',
configurePostCss(postcssOptions) {
// Appends new PostCSS plugin.
postcssOptions.plugins.push(require('postcss-import'));
return postcssOptions;
},
};
}
postBuild(props)
當一個(生產環境)建置完成時呼叫。
interface Props {
siteDir: string;
generatedFilesDir: string;
siteConfig: DocusaurusConfig;
outDir: string;
baseUrl: string;
headTags: string;
preBodyTags: string;
postBodyTags: string;
routesPaths: string[];
plugins: Plugin<any>[];
content: Content;
}
範例
export default function (context, options) {
return {
name: 'docusaurus-plugin',
async postBuild({siteConfig = {}, routesPaths = [], outDir}) {
// Print out to console all the rendered routes.
routesPaths.map((route) => {
console.log(route);
});
},
};
}
injectHtmlTags({content})
將 header 和/或 body HTML 標籤插入 Docusaurus 產生的 HTML 中。
injectHtmlTags
將使用這個外掛載入的內容同時呼叫。
function injectHtmlTags(): {
headTags?: HtmlTags;
preBodyTags?: HtmlTags;
postBodyTags?: HtmlTags;
};
type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
type HtmlTagObject = {
/**
* Attributes of the HTML tag
* E.g. `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
*/
attributes?: {
[attributeName: string]: string | boolean;
};
/**
* The tag name e.g. `div`, `script`, `link`, `meta`
*/
tagName: string;
/**
* The inner HTML
*/
innerHTML?: string;
};
範例
export default function (context, options) {
return {
name: 'docusaurus-plugin',
loadContent: async () => {
return {remoteHeadTags: await fetchHeadTagsFromAPI()};
},
injectHtmlTags({content}) {
return {
headTags: [
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://www.github.com',
},
},
...content.remoteHeadTags,
],
preBodyTags: [
{
tagName: 'script',
attributes: {
charset: 'utf-8',
src: '/noflash.js',
},
},
],
postBodyTags: [`<div> This is post body </div>`],
};
},
};
}
標籤將新增如下
headTags
會插入在 config 增加的腳本後的關閉</head>
標籤之前。preBodyTags
將會插入在開啟<body>
標籤後,任何子元素之前。postBodyTags
將會插入在關閉</body>
標籤前,所有子元素之後。
getClientModules()
傳回 用戶端模組 的路徑陣列,此模組應匯入用戶端套件中。
例如,要讓你的佈景主題從使用者傳遞進來的 options
載入 customCss
或 customJs
檔案路徑
export default function (context, options) {
const {customCss, customJs} = options || {};
return {
name: 'name-of-my-theme',
getClientModules() {
return [customCss, customJs];
},
};
}