vendredi 25 septembre 2026

À propos

Contact

Extensions

Diviser un plugin monolithique en extensions indépendantes : la méthode

Un plugin fourre-tout de huit ans devenu ingérable a été découpé en modules chargés à la demande. Retour sur la méthode qui a rendu ce chantier possible.

Par Clément Hadrot • 2 mai 2026 • 5 min de lecture • Aucun commentaire
Diviser un plugin monolithique en extensions indépendantes : la méthode

Un client du secteur associatif utilisait depuis huit ans un plugin unique regroupant la gestion des adhésions, la billetterie d’événements, l’envoi de newsletters et un système de dons en ligne, plus de 40 000 lignes de code accumulées au fil des demandes successives. Chaque nouvelle fonctionnalité ajoutée touchait un fichier de plus en plus difficile à faire évoluer sans effet de bord sur une autre partie du plugin, sans lien fonctionnel apparent avec la modification demandée.

Ce billet raconte le découpage de ce plugin en quatorze modules indépendants, chargés à la demande selon les besoins réels de chaque site utilisant l’un ou l’autre. Il ne s’agit pas ici du refactoring interne d’une extension vieillissante, sujet déjà traité, mais bien de la méthode de découpage en plusieurs extensions distinctes, activables séparément.

Cartographier avant de couper

La première étape, souvent négligée par impatience, a consisté à cartographier précisément les dépendances internes entre les quatre grandes fonctionnalités du plugin, avant d’écrire la moindre ligne de découpage. Une recherche systématique des appels de fonctions croisés entre les dossiers du plugin a révélé des dépendances inattendues : la billetterie appelait directement une fonction de calcul de réduction définie dans le module d’adhésions, sans que cela apparaisse dans la documentation interne du projet.

grep -rn "adhesions_calculer_reduction" wp-content/plugins/plugin-associatif/ \
  --include="*.php" | grep -v "^wp-content/plugins/plugin-associatif/modules/adhesions/"

Cette commande, répétée pour chaque fonction publique du module d’adhésions, a permis de constater que trois autres modules dépendaient directement de son code, sans passer par une interface stable. Sans cette cartographie préalable, l’extraction du module d’adhésions aurait cassé silencieusement la billetterie, les dons et la newsletter, chacun de leur côté.

Définir un noyau commun minimal

Plutôt que de dupliquer les fonctions partagées dans chaque module extrait, ce qui aurait multiplié la dette technique à chaque future correction, un noyau commun a été créé, sous forme d’une extension à part entière dont dépendent les quatorze modules. Ce noyau expose uniquement des interfaces stables et documentées, jamais l’accès direct aux structures internes des modules qui les implémentent.

L'essentiel à retenir : Cartographier les dépendances internes avant de couper quoi que ce soit ; Extraire un module à la fois, en gardant le site fonctionnel entre chaque étape ; Un noyau commun minimal évite la duplication entre les modules extraits
// Dans le module noyau, une interface stable exposée aux autres modules.
function assoc_noyau_calculer_reduction_membre( int $membre_id, float $montant ) : float {
    return apply_filters( 'assoc_noyau_reduction_membre', $montant, $membre_id );
}

// Le module adhésions s'accroche à ce filtre, sans que la billetterie
// ait besoin de connaître son fonctionnement interne.
add_filter( 'assoc_noyau_reduction_membre', function( $montant, $membre_id ) {
    $taux = assoc_adhesions_taux_reduction( $membre_id );
    return $montant * ( 1 - $taux );
}, 10, 2 );

Cette inversion, où le noyau expose un filtre plutôt que d’appeler directement une fonction du module d’adhésions, a permis à la billetterie de continuer à fonctionner même sur les sites où le module d’adhésions n’était pas installé, avec un taux de réduction simplement nul par défaut en son absence.

Extraire un module à la fois, jamais tous en même temps

La tentation initiale du client était de tout redécouper en une seule mise en production, pour ne pas multiplier les livraisons. Cette approche a été écartée au profit d’une extraction séquentielle, module par module, chaque extraction suivie d’une période de stabilisation en production avant de passer à la suivante.

L’ordre d’extraction retenu

  1. Extraire d’abord le module le plus autonome, ici la newsletter, dont les dépendances vers les autres modules étaient minimes et déjà identifiées lors de la cartographie initiale.
  2. Poursuivre par les modules de complexité croissante, en réservant pour la fin le module d’adhésions, celui dont dépendaient le plus grand nombre d’autres fonctionnalités.
  3. Après chaque extraction, conserver temporairement l’ancien code en place, désactivé mais non supprimé, le temps de valider qu’aucune régression silencieuse n’apparaît sur plusieurs semaines de production réelle.

Le chargement à la demande

Une fois les quatorze modules extraits, chaque site client n’active plus que les extensions dont il a réellement besoin. Un site qui ne gère aucun événement peut se passer entièrement du module billetterie, réduisant d’autant la surface de code chargée à chaque page, et surtout la surface de bugs potentiels sur ce site précis.

  • Un module non installé ne doit jamais provoquer d’erreur fatale ailleurs : chaque interaction inter-modules passe par une vérification d’existence, via function_exists() ou un filtre à valeur par défaut sûre.
  • La documentation de chaque interface exposée par le noyau commun devient la seule source de vérité entre les modules, plus jamais une lecture directe du code d’un module voisin.
  • Un module qui grossit à nouveau au point de dépasser ses responsabilités initiales redevient candidat à un nouveau découpage, le processus n’étant jamais définitivement clos.

Une leçon que ce chantier nous a confirmée : le découpage technique compte moins que la discipline à ne jamais laisser un module en emprunter un autre directement. C’est cette règle, plus que l’architecture elle-même, qui a rendu le résultat maintenable sur la durée.

En résumé

Diviser un plugin monolithique en modules indépendants n’est pas d’abord un exercice de découpage de fichiers, mais un travail de cartographie des dépendances réelles, suivi d’une extraction progressive appuyée sur un noyau commun aux interfaces stables. Sur ce projet, l’effort principal n’a pas été de réécrire le code existant, mais de définir où placer les frontières entre modules, de façon à ce qu’aucun d’entre eux ne redevienne, avec le temps, aussi couplé aux autres que ne l’était le plugin d’origine.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi