跳到主要内容
版本:2.4.3

插件

插件是 Docusaurus 2 功能特性的基石。 每个插件都有其自己的独立功能。 插件可以通过预设被打包分发。

Creating plugins

A plugin is a function that takes two parameters: context and options. 它会返回一个插件实例对象(或者一个对象的 Promise)。 你所创建的插件可以是函数或者模块。 For more information, refer to the plugin method references section.

Function definition

你可以在 Docusaurus 配置文件中直接以函数形式声明插件:

docusaurus.config.js
module.exports = {
// ...
plugins: [
async function myPlugin(context, options) {
// ...
return {
name: 'my-plugin',
async loadContent() {
// ...
},
async contentLoaded({content, actions}) {
// ...
},
/* other lifecycle API */
};
},
],
};

Module definition

你可以用一个模块路径声明插件,路径应指向一个文件或者一个 npm 包:

docusaurus.config.js
module.exports = {
// ...
plugins: [
// without options:
'./my-plugin',
// or with options:
['./my-plugin', options],
],
};

Then in the folder my-plugin, you can create an index.js such as this:

my-plugin/index.js
module.exports = async function myPlugin(context, options) {
// ...
return {
name: 'my-plugin',
async loadContent() {
/* ... */
},
async contentLoaded({content, actions}) {
/* ... */
},
/* other lifecycle API */
};
};

You can view all plugins installed in your site using the debug plugin's metadata panel.

插件有几种类型:

  • package: an external package you installed
  • project: a plugin you created in your project, given to Docusaurus as a local file path
  • local: a plugin created using the function definition
  • synthetic: a "fake plugin" Docusaurus created internally, so we take advantage of our modular architecture and don't let the core do much special work. 你不会在元数据中看到这些插件,因为这是一个实现细节。

You can access them on the client side with useDocusaurusContext().siteMetadata.pluginVersions.

Plugin design

Docusaurus 所实现的插件系统可以让你轻松地在网站的各个生命周期环节更改开发/构建时的行为,包括但不限于扩展 Webpack 配置、修改所加载的数据,以及创建新组件供页面使用。

Theme design

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...

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. UI 是一个独立于数据的层级,这样使得调换界面设计变得简单。

举个例子,一个 Docusaurus 博客可能由一个博客插件和一个博客主题组成。

备注

This is a contrived example: in practice, @docusaurus/theme-classic provides the theme for docs, blog, and layouts.

docusaurus.config.js
module.exports = {
themes: ['theme-blog'],
plugins: ['plugin-content-blog'],
};

And if you want to use Bootstrap styling, you can swap out the theme with theme-blog-bootstrap (another fictitious non-existing theme):

docusaurus.config.js
module.exports = {
themes: ['theme-blog-bootstrap'],
plugins: ['plugin-content-blog'],
};

Now, although the theme receives the same data from the plugin, how the theme chooses to render the data as UI can be drastically different.

虽然主题与插件有完全相同的生命周期方法,但基于主题的设计目标,主题的实现可能与插件的实现大不相同。

主题旨在完成你的 Docusaurus 网站的构建,并提供你的网站、插件和主题本身所使用的组件。 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.

总地来说:

  • 主题与插件共享相同的生命周期方法
  • 主题在所有现有插件后运行
  • Themes add component aliases by providing getThemePath.