Aller au contenu principal
Version: 2.0.0-alpha.72

Cycle de vie des API

attention

Cette section est en cours de rédaction.

Les API de cycle de vie sont partagées par les thèmes et les plugins.

validateOptions({options, validate})#

Retourne les options validées et normalisées pour le plugin. Cette méthode est appelée avant que le plugin soit initialisé. Vous devez retourner des options car les options retournées seront passées au plugin lors de l'initialisation.

options#

validateOptions est appelé avec les options passées au plugin pour la validation et la normalisation.

validate#

validateOptions est appelée avec la fonction validate qui prend un schéma Joi et les options comme argument, retourne des options validées et normalisées. validate gérera automatiquement la configuration d'erreur et de validation.

astuce

Joi est recommandé pour la validation et la normalisation des options.

Si vous n'utilisez pas Joi pour la validation, vous pouvez lancer une erreur en cas d'options non valides et retourner des options en cas de succès.

my-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
// reste des méthodes
};
};
module.exports.validateOptions = ({options, validate}) => {
const validatedOptions = validate(myValidationSchema, options);
return validationOptions;
};

Vous pouvez également utiliser le style d'exportation des modules ES.

my-plugin/src/index.ts
export default function (context, options) {
return {
name: 'docusaurus-plugin',
// reste des méthodes
};
}
export function validateOptions({options, validate}) {
const validatedOptions = validate(myValidationSchema, options);
return validationOptions;
}

validateThemeConfig({themeConfig, validate})#

Retourne une configuration validée et normalisée pour le thème.

themeConfig#

validateThemeConfig est appelé avec themeConfig fourni dans docusaurus.config.js pour la validation et la normalisation.

validate#

validateThemeConfig est appelé avec la fonction validate qui prend un schéma Joi et themeConfig en argument, retourne les options validées et normalisées. validate gérera automatiquement la configuration d'erreur et de validation.

astuce

Joi est recommandé pour la validation et la normalisation de la configuration du thème.

Si vous n'utilisez pas Joi pour la validation, vous pouvez lancer une erreur en cas d'options non valides.

my-theme/src/index.js
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
// reste des méthodes
};
};
module.exports.validateThemeConfig = ({themeConfig, validate}) => {
const validatedThemeConfig = validate(myValidationSchema, options);
return validatedThemeConfig;
};

Vous pouvez également utiliser le style d'exportation des modules ES.

my-theme/src/index.ts
export default function (context, options) {
return {
name: 'docusaurus-plugin',
// reste des méthodes
};
}
export function validateThemeConfig({themeConfig, validate}) {
const validatedThemeConfig = validate(myValidationSchema, options);
return validatedThemeConfig;
}

getPathsToWatch()#

Spécifie les chemins à surveiller pour les plugins et les thèmes. Les chemins sont surveillés par le serveur de développement de sorte que les cycles de vie du plugin sont rechargés lorsque le contenu des chemins surveillés change. Notez que les modules de plugins et de themes sont initialement appelés avec context et options depuis Node, que vous pouvez utiliser pour trouver les informations de répertoire nécessaires sur le site.

Exemple :

docusaurus-plugin/src/index.js
const path = require('path');
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
getPathsToWatch() {
const contentPath = path.resolve(context.siteDir, options.path);
return [`${contentPath}/**/*.{ts,tsx}`];
},
};
};

async loadContent()#

Les plugins doivent utiliser ce cycle de vie pour récupérer des sources de données (système de fichiers, API distante, CMS sans entête, etc) ou pour effectuer un traitement du serveur.

Par exemple, ce plugin ci-dessous renvoie un entier aléatoire compris entre 1 et 10 comme contenu;

docusaurus-plugin/src/index.js
const path = require('path');
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
async loadContent() {
return 1 + Math.floor(Math.random() * 10);
},
};
};

async contentLoaded({content, actions})#

Les plugins doivent utiliser les données chargées dans loadContent et construire les pages/routes qui consomment les données chargées (facultatif).

content#

contentLoaded sera appelé après que loadContent soit effectué, la valeur de retour de loadContent() sera passée à contentLoaded comme content.

actions#

actions contiennent deux fonctions :

  • addRoute(config: RouteConfig): void

Créez une route pour l'ajouter au site web.

interface RouteConfig {
path: string;
component: string;
modules?: RouteModule;
routes?: RouteConfig[];
exact?: boolean;
priority?: number;
}
interface RouteModule {
[module: string]: Module | RouteModule | RouteModule[];
}
type Module =
| {
path: string;
__import?: boolean;
query?: ParsedUrlQueryInput;
}
| string;
  • createData(name: string, data: any): Promise<string>

Une fonction pour vous aider à créer des données statiques (généralement json ou string), que vous pouvez fournir à vos routes en tant que props.

Par exemple, ce plugin ci-dessous crée une page /friends qui affiche Vos amis sont : Yangshun, Sébastien :

website/src/components/Friends.js
import React from 'react';
export default function FriendsComponent({friends}) {
return <div>Vos amis sont {friends.join(',')}</div>;
}
docusaurus-friends-plugin/src/index.js
export default function friendsPlugin(context, options) {
return {
name: 'docusaurus-friends-plugin',
async contentLoaded({content, actions}) {
const {createData, addRoute} = actions;
// Crée friends.json
const friends = ['Yangshun', 'Sebastien'];
const friendsJsonPath = await createData(
'friends.json',
JSON.stringify(friends),
);
// Ajoute la route '/friends' et assure-vous qu'il reçoit la props friends
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
modules: {
// propName -> chemin fichier JSON
friends: friendsJsonPath,
},
exact: true,
});
},
};
}
  • setGlobalData(data: any): void

Cette fonction permet de créer des données globales de plugin, qui peuvent être lues depuis n'importe quelle page, y compris les pages créées par d'autres plugins et la mise en page de votre thème.

Ces données deviennent accessibles pour votre code client/thème, via les useGlobalData et usePluginData.

Une fois ces données créées, vous pouvez y accéder avec les API de hooks de données globales.

attention

Les données globales sont... globales : leurs tailles affectent le temps de chargement de toutes les pages de votre site, alors essayez de les garder petites.

Préférez createData et des données spécifiques à la page dans la mesure du possible.

Par exemple, ce plugin ci-dessous crée une page /friends qui affiche Vos amis sont : Yangshun, Sébastien :

website/src/components/Friends.js
import React from 'react';
import {usePluginData} from '@docusaurus/useGlobalData';
export default function FriendsComponent() {
const {friends} = usePluginData('my-friends-plugin');
return <div>Vos amis sont {friends.join(',')}</div>;
}
docusaurus-friends-plugin/src/index.js
export default function friendsPlugin(context, options) {
return {
name: 'docusaurus-friends-plugin',
async contentLoaded({content, actions}) {
const {setGlobalData, addRoute} = actions;
// Crée des données globales friends
setGlobalData({friends: ['Yangshun', 'Sebastien']});
// Ajoute la route '/friends'
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
exact: true,
});
},
};
}

configureWebpack(config, isServer, utils)#

Modifie la configuration interne de webpack. Si la valeur retournée est un objet JavaScript, elle sera fusionnée dans la configuration finale en utilisant webpack-merge. Si c'est une fonction, elle sera appelée et recevra config comme premier argument et un drapeau isServer comme argument.

config#

configureWebpack est appelée avec config générée selon la construction du client/serveur. Vous pouvez le considérer comme la configuration de base avec laquelle il faut fusionner.

isServer#

configureWebpack sera appelée à la fois dans la construction du serveur et dans la construction du client. La construction du serveur reçoit true et la construction du client reçoit false pour isServer.

utils#

L'appel initial à configureWebpack reçoit également un objet utilitaire constitué de trois fonctions :

  • getStyleLoaders(isServer: boolean, cssOptions: {[key: string]: any}): Loader[]
  • getCacheLoader(isServer: boolean, cacheOptions?: {}): Loader | null
  • getBabelLoader(isServer: boolean, babelOptions?: {}): Loader

Vous pouvez les utiliser pour retourner vos configurations webpack sous certaines conditions.

Par exemple, ce plugin ci-dessous modifie la configuration de webpack pour transpiler le fichier .foo.

docusaurus-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
const {getCacheLoader} = utils;
return {
module: {
rules: [
{
test: /\.foo$/,
use: [getCacheLoader(isServer), 'my-custom-webpack-loader'],
},
],
},
};
},
};
};

Fusionnez la stratégie#

Nous fusionnons les parties de configuration Webpack des plugins dans la configuration globale de Webpack en utilisant webpack-merge.

Il est possible de spécifier la stratégie de fusion. Par exemple, si vous voulez qu'une règle de webpack soit placée au début au lieu d'être ajoutée à la fin :

docusaurus-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
return {
mergeStrategy: {'module.rules': 'prepend'},
module: {rules: [myRuleToPrepend]},
};
},
};
};

Lisez la documentation de la stratégie de fusion de webpack-merge pour plus de détails.

configurePostCss(options)#

Modifie postcssOptions de postcss-loader pendant la génération du bundle client.

Devrait retourner le postcssOptions muté.

Par défaut, postcssOptions ressemble à ceci :

const postcssOptions = {
ident: 'postcss',
plugins: [
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 4,
}),
],
};

Exemple :

docusaurus-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
configurePostCss(postcssOptions) {
// Ajoute un nouveau plugin PostCSS.
postcssOptions.plugins.push(require('postcss-import'));
return postcssOptions;
},
};
};

postBuild(props)#

Appelée quand une version (production) se termine.

type Props = {
siteDir: string;
generatedFilesDir: string;
siteConfig: DocusaurusConfig;
outDir: string;
baseUrl: string;
headTags: string;
preBodyTags: string;
postBodyTags: string;
routesPaths: string[];
plugins: Plugin<any>[];
stats: Stats.ToJsonOutput;
};

Exemple :

docusaurus-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
async postBuild({siteConfig = {}, routesPaths = [], outDir, stats}) {
// Affiche dans la console toutes les routes rendues.
routesPaths.map((route) => {
console.log(route);
});
// Affiche dans la console toutes les statistiques de webpack.
console.log(stats);
},
};
};

extendCli(cli)#

Enregistre une commande supplémentaire pour améliorer la CLI de docusaurus. cli est un objet commander.

Exemple :

docusaurus-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
extendCli(cli) {
cli
.command('roll')
.description('Lance un nombre aléatoire entre 1 et 1000')
.action(() => {
console.log(Math.floor(Math.random() * 1000 + 1));
});
},
};
};

injectHtmlTags()#

Injecte les balises HTML head et/ou body vers le HTML générées de Docusaurus.

function injectHtmlTags(): {
headTags?: HtmlTags;
preBodyTags?: HtmlTags;
postBodyTags?: HtmlTags;
};
type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
interface HtmlTagObject {
/**
* Attributs de la balise HTML
* Par exemple `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
*/
attributes?: {
[attributeName: string]: string | boolean;
};
/**
* Le nom de la balise, par exemple `div`, `script`, `link`, `meta`
*/
tagName: string;
/**
* Le contenu HTML
*/
innerHTML?: string;
}

Exemple :

docusaurus-plugin/src/index.js
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin',
injectHtmlTags() {
return {
headTags: [
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://www.github.com',
},
},
],
preBodyTags: [
{
tagName: 'script',
attributes: {
charset: 'utf-8',
src: '/noflash.js',
},
},
],
postBodyTags: [`<div> C'est le corps de l'article </div>`],
};
},
};
};

getThemePath()#

Retourne le chemin vers le répertoire où les composants du thème peuvent être trouvés. Lorsque vos utilisateurs appellent swizzle, getThemePath est appelé et son chemin retourné est utilisé pour trouver les composants de votre thème.

Si vous utilisez le dossier ci-dessus, votre getThemePath peut être :

my-theme/src/index.js
const path = require('path');
module.exports = function (context, options) {
return {
name: 'name-of-my-theme',
getThemePath() {
return path.resolve(__dirname, './theme');
},
};
};

getTypeScriptThemePath()#

Similaire à getThemePath(), il devrait retourner le chemin vers le répertoire où le code source des composants du thème TypeScript peut être trouvé. Les composants de thème sous ce chemin ne seront pas résolus par Webpack. Par conséquent, ce n'est pas un remplacement de getThemePath(). Au lieu de cela, ce chemin est purement destiné au swizzle de composants de thème TypeScript.

Si vous souhaitez prendre en charge le swizzle des composants TypeScript pour votre thème, vous pouvez faire en sorte que le chemin renvoyé par getTypeScriptThemePath() soit votre répertoire source, et que le chemin renvoyé par getThemePath() soit celui de la sortie JavaScript compilée.

Exemple :

my-theme/src/index.js
const path = require('path');
module.exports = function (context, options) {
return {
name: 'name-of-my-theme',
getThemePath() {
// Où se trouve le JavaScript compilé
return path.join(__dirname, '..', 'lib', 'theme');
},
getTypeScriptThemePath() {
// Où se trouve le code source TypeScript
return path.resolve(__dirname, './theme');
},
};
};

getSwizzleComponentList()#

Retourne une liste de composants stables considérés comme sûrs pour le swizzle. Ces composants seront listés depuis le swizzle de composant sans --danger. Tous les composants sont considérés comme instables par défaut. Si un tableau vide est retourné, tous les composants sont considérés comme instables, si undefined est retourné, alors tous les composants sont considérés stables.

my-theme/src/index.js
const swizzleAllowedComponents = [
'CodeBlock',
'DocSidebar',
'Footer',
'NotFound',
'SearchBar',
'hooks/useTheme',
'prism-include-languages',
];
module.exports.getSwizzleComponentList = () => swizzleAllowedComponents;

getClientModules()#

Retourne un tableau de chemins vers les modules qui doivent être importés dans le bundle client. Ces modules sont importés globalement avant même que React ne rende l'interface utilisateur initiale.

À titre d'exemple, pour que votre thème puisse charger un fichier customCss ou customJs à partir des options passées par l'utilisateur :

my-theme/src/index.js
const path = require('path');
module.exports = function (context, options) {
const {customCss, customJs} = options || {};
return {
name: 'name-of-my-theme',
getClientModules() {
return [customCss, customJs];
},
};
};

Exemple#

Voici un modèle de pensée pour une implémentation présumée d'un plugin.

const DEFAULT_OPTIONS = {
// Quelques valeurs par défaut.
};
// Une fonction JavaScript qui renvoie un objet.
// `context` est fourni par Docusaurus. Exemple : siteConfig est accessible depuis le contexte.
// `opts` sont les options définies par l'utilisateur.
module.exports = function (context opts) {
// Fusionne les valeurs par défaut avec les options définies par l'utilisateur.
const options = {...DEFAULT_OPTIONS, ...options};
return {
// Un champ obligatoire utilisé comme espace nommé pour les répertoires à mettre en cache
// les données intermédiaires pour chaque plugin.
// Si vous écrivez votre propre plugin local, vous voudrez qu'il
// soit unique afin de ne pas entrer en conflit avec des plugins importés.
// Une bonne façon sera d'ajouter votre propre nom de projet à l'intérieur.
name: 'docusaurus-my-project-cool-plugin',
async loadContent() {
// Le hook loadContent est exécuté après le chargement de siteConfig et env .
// Vous pouvez retourner un objet JavaScript qui sera passé au hook contentLoaded .
},
contentLoaded({content, actions}) {
// Le hook contentLoaded est traité après que loadContent hook est terminé.
// `actions` est un ensemble d'API fonctionnelle fournie par Docusaurus (par exemple addRoute)
},
postBuild(props) {
// Après que le <build> de docusaurus soit terminé.
},
// À FAIRE
async postStart(props) {
// docusaurus <start> finish
},
// À FAIRE
afterDevServer(app, server) {
// https://webpack.js.org/configuration/dev-server/#devserverbefore
},
// À FAIRE
beforeDevServer(app, server) {
// https://webpack.js.org/configuration/dev-server/#devserverafter
},
configureWebpack(config, isServer) {
// Modife la configuration interne de webpack. Si la valeur retournée est un objet, elle
// sera fusionnée dans la configuration finale en utilisant webpack-merge;
// Si la valeur retournée est une fonction, il recevra la configuration en tant que 1er argument et un drapeau isServer en tant que deuxième argument.
},
getPathsToWatch() {
// Chemins à surveiller.
},
getThemePath() {
// Retourne le chemin vers le répertoire où les composants du thème peuvent
// être trouvés.
},
getClientModules() {
// Retourne un tableau de chemins vers les modules qui doivent être importés
// dans le bundle client. Ces modules sont importés globalement avant même que
// React ne rende l'interface utilisateur initiale.
},
extendCli(cli) {
// Enregistre une commande supplémentaire pour améliorer le CLI de Docusaurus
},
injectHtmlTags() {
// Injecte des balises HTML head et/ou body.
},
};
};