插件
插件是 Docusaurus 网站功能的基石。每个插件实现自己独立的功能。插件可以通过预设(presets)成为安装包的一部分来运行和分发。
创建插件
插件是一个函数,接受两个参数:context
和 options
;返回一个插件实例对象(或一个 promise)。您可以将插件创建为函数或模块。更多信息,请参阅 插件方法参考手册章节。
函数式定义
您可以直接在 Docusaurus 配置文件中使用函数形式的插件:
export default {
// ...
plugins: [
async function myPlugin(context, options) {
// ...
return {
name: 'my-plugin',
async loadContent() {
// ...
},
async contentLoaded({content, actions}) {
// ...
},
/* other lifecycle API */
};
},
],
};
模块式定义
You can use a plugin as a module path referencing a separate file or npm package: 您可以使用插件作为模块路径,引用单独的文件或 npm 包:
export default {
// ...
plugins: [
// without options:
'./my-plugin',
// or with options:
['./my-plugin', options],
],
};
然后,在 my-plugin
文件夹中创建一个名为 index.js
的文件,内容如下:
export default async function myPlugin(context, options) {
// ...
return {
name: 'my-plugin',
async loadContent() {
/* ... */
},
async contentLoaded({content, actions}) {
/* ... */
},
/* other lifecycle API */
};
}
您可以通过 插件信息调试面板 查看网站中安装的所有插件。
插件有多种类型:
package
: 您所安装的外部软件包project
: a plugin you created in your project, given to Docusaurus as a local file pathlocal
: 使用函数形式所创建的插件synthetic
: Docusaurus 内部创建的 "虚拟插件",我们利用这种模块化架构,不让核心做太多特殊工作。在插件信息调试面板中看不到这这些,因为这是一个实现细节。
您可以通过 useDocusaurusContext().siteMetadata.pluginVersions
在客户端访问它们。
插件的设计
Docusaurus' implementation of the plugins system provides us with a convenient way to hook into the website's lifecycle to modify what goes on during development/build, which involves (but is not limited to) extending the webpack config, modifying the data loaded, and creating new components to be used in a page. Docusaurus 的插件系统为我们提供了一种便捷的方式,让我们可以挂钩网站的生命周期,以修改开发/构建过程中的内容,其中包括(但不限于)扩展 webpack 配置、修改加载的数据以及创建页面中使用的新组件。
主题的设计
When plugins have loaded their content, the data is made available to the client side through actions like createData
+ addRoute
or setGlobalData
. This data has to be serialized to plain strings, because plugins and themes run in different environments. Once the data arrives on the client side, the rest becomes familiar to React developers: data is passed along components, components are bundled with Webpack, and rendered to the window through ReactDOM.render
...
插件加载内容后,数据将通过 createData + addRoute 或 setGlobalData 等操作提供给客户端。这些数据必须序列化为纯字符串,因为插件和主题在不同的环境中运行。数据到达客户端后,剩下的事情对于 React 开发人员来说就很熟悉了:数据沿着组件传递,组件与 Webpack 绑定,并通过 ReactDOM.render 呈现到窗口......
Themes provide the set of UI components to render the content. Most content plugins need to be paired with a theme in order to be actually useful. The UI is a separate layer from the data schema, which makes swapping designs easy. 主题提供了用于呈现内容的 UI 组件集。大多数内容插件都需要与主题搭配才能真正发挥作用。用户界面是一个独立于数据模式的层,因此可以轻松更换设计。
例如,一个 Docusaurus 博客网站可能仅由博客插件和博客主题组成。
这是一个臆造的例子:实际上,@docusaurus/theme-classic
作为主题同时提供了文档、博客和布局功能。
export default {
themes: ['theme-blog'],
plugins: ['plugin-content-blog'],
};
如果你想使用 Bootstrap 风格,可以将主题换成 theme-blog-bootstrap
(也是一个虚构的、不存在的主题):
export default {
themes: ['theme-blog-bootstrap'],
plugins: ['plugin-content-blog'],
};
现在,虽然主题从插件接收到的数据是一样的,但主题选择如何将数据 呈现 为用户界面的方式却可能大相径庭。
虽然主题与插件具有完全相同的生命周期方法,但根据主题的设计目标,主题的实现方式可能与插件截然不同。
Themes are designed to complete the build of your Docusaurus site and supply the components used by your site, plugins, and the themes themselves. A theme still acts like a plugin and exposes some lifecycle methods, but most likely they would not use loadContent
, since they only receive data from plugins, but don't generate data themselves; themes are typically also accompanied by an src/theme
directory full of components, which are made known to the core through the getThemePath
lifecycle.
主题旨在完成 Docusaurus 网站的构建,并提供网站、插件和主题本身所使用的组件。主题仍然像插件一样运行,并暴露一些生命周期方法,但它们很可能不会使用 loadContent,因为它们只会接收来自插件的数据,而不会自己生成数据;主题通常还会附带一个装满组件的 src/theme 目录,通过 getThemePath 生命周期让核心知道这些组件。
总结一下:
- 主题与插件拥有相同的生命周期方法
- 主题在所有插件之后运行
- 主题通过暴露
getThemePath
函数来添加组件别名。