Aller au contenu principal
Version: 2.0.0-beta.4

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.

Pour éviter de mélanger les versions de Joi, utilisez const {Joi} = require("@docusaurus/utils-validation")

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.

Pour éviter de mélanger les versions de Joi, utilisez const {Joi} = require("@docusaurus/utils-validation")

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, content)#

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.

attention

L'API de configureWebpack sera modifiée dans le futur pour accepter un objet (configureWebpack({config, isServer, utils, content}))

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#

configureWebpack reçoit également un objet utilitaire :

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

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'],            },          ],        },      };    },  };};

content#

configureWebpack sera appelé aussi avec le contenu chargé par le plugin.

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('autoprefixer')],};

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>[];};

Exemple :

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

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({content})#

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

injectHtmlTags sera appelé aussi avec le contenu chargé par le plugin.

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',    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> Ceci 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];    },  };};

Cycle de vie i18n#

getTranslationFiles({content})#

Les plugins déclarent les fichiers de traduction JSON qu'ils veulent utiliser.

Retournee les fichiers de traduction {path: string, content: ChromeI18nJSON} :

  • Path : relatif au dossier du plugin localisé i18n/<locale>/pluginName. L'extension .json n'est pas nécessaire.
  • Content : utilisation du format JSON pour Chrome i18n

Ces fichiers seront écrits par le CLI write-translations dans le sous-dossier du plugin i18n, et sera lu dans la locale appropriée avant d'appeler translateContent() et translateThemeConfig()

Exemple :

module.exports = function (context, options) {  return {    name: 'my-plugin',    async getTranslationFiles({content}) {      return [        {          path: 'sidebar-labels',          content: {            someSidebarLabel: {              message: 'Some Sidebar Label',              description: 'A label used in my plugin in the sidebar',            },            someLabelFromContent: content.myLabel,          },        },      ];    },  };};

translateContent({content,translationFiles})#

Traduit le contenu du plugin, en utilisant les fichiers de traduction localisés.

Retourne le contenu du plugin localisé.

Le cycle de vie de contentLoaded() sera appelé avec le contenu du plugin localisé retourné par translateContent().

Exemple :

module.exports = function (context, options) {  return {    name: 'my-plugin',    translateContent({content, translationFiles}) {      const myTranslationFile = translationFiles.find(        (f) => f.path === 'myTranslationFile',      );      return {        ...content,        someContentLabel: myTranslationFile.someContentLabel.message,      };    },  };};

translateThemeConfig({themeConfig,translationFiles})#

Traduit les libellés de themeConfig du site en utilisant les fichiers de traduction localisés.

Renvoie le themeConfig localisé.

Exemple :

module.exports = function (context, options) {  return {    name: 'my-theme',    translateThemeConfig({themeConfig, translationFiles}) {      const myTranslationFile = translationFiles.find(        (f) => f.path === 'myTranslationFile',      );      return {        ...themeConfig,        someThemeConfigLabel: myTranslationFile.someThemeConfigLabel.message,      };    },  };};

async getDefaultCodeTranslationMessages()#

Les thèmes utilisant l'API <Translate> peuvent fournir des messages de traduction de code par défaut.

Il devrait retourner des messages dans Record<string,string>, où les clés sont les identifiants de traduction et les valeurs sont des messages (sans la description) localisés en utilisant la locale courante du site.

Exemple :

module.exports = function (context, options) {  return {    name: 'my-theme',    async getDefaultCodeTranslationMessages() {      return readJsonFile(`${context.i18n.currentLocale}.json`);    },  };};

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, utils, content) {      // Modify internal webpack config. 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({content}) {      // Inject des balises HTML head et/ou body.    },
    async getTranslationFiles({content}) {      // Retourne les fichiers de traduction    },
    translateContent({content, translationFiles}) {      // traduit ici le contenu du plugin    },
    translateThemeConfig({themeConfig, translationFiles}) {      // traduit ici le themeConfig du site    },
    async getDefaultCodeTranslationMessages() {      // retourne ici les traductions du thème par défaut    },  };};