# Un plugin désactivé casse silencieusement douze blocs liés

> Une dépendance cachée entre blocs de plugins différents, découverte seulement après la désactivation d'une extension en production.

- Auteur : Clément Hadrot
- Publié le : 2026-05-19
- Mis à jour le : 2026-05-19
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/plugin-desactive-casse-douze-blocs-lies/

## L’essentiel

- Un bloc peut consommer discrètement le store d'un autre plugin
- Le champ requires de la clé Plugin Dependencies ne couvre pas toute dépendance
- Documenter les dépendances inter-plugins avant toute désactivation

Le Cabinet Ferrand a désactivé, en production et sans préavis particulier, une extension de gestion de rendez-vous jugée obsolète après le passage à un nouvel outil de prise de rendez-vous en ligne. L'opération semblait sans risque : plus aucune page n'utilisait le bloc de prise de rendez-vous fourni par cette extension depuis des mois. Dans l'heure qui a suivi, douze blocs répartis sur plusieurs pages du site ont cessé de s'afficher correctement, sans lien apparent avec la fonctionnalité de rendez-vous elle-même.

## Symptôme : une panne qui ne pointe pas vers sa cause

Les blocs affectés appartenaient à trois extensions différentes, aucune n'étant celle qui venait d'être désactivée. Leur point commun, invisible à première vue : tous consommaient, via `useSelect`, un store de données personnalisé (`createReduxStore`) enregistré par l'extension de rendez-vous, pour vérifier une disponibilité générique avant d'afficher certains éléments d'interface (un badge « sur rendez-vous » affiché sur des fiches services, des articles, et une page d'équipe).

## Diagnostic : une dépendance de fait, jamais déclarée

Aucun des `block.json` des blocs affectés ne mentionnait l'extension de rendez-vous dans un champ de dépendance quelconque, pour une raison simple : ce lien avait été ajouté après coup, par un développeur différent, sur un projet différent, sans jamais documenter cette dépendance croisée. Le store `cabinet-ferrand/rendez-vous` était simplement supposé toujours présent, car il l'avait toujours été jusque-là.

```
// Dans un bloc totalement différent, sans lien apparent :
const disponibilite = useSelect(
  (select) => select('cabinet-ferrand/rendez-vous')?.getDisponibiliteGenerale(),
  []
);
```

> L'essentiel à retenir : Un bloc peut consommer discrètement le store d'un autre plugin ; Le champ requires de la clé Plugin Dependencies ne couvre pas toute dépendance ; Documenter les dépendances inter-plugins avant toute désactivation

Une fois l'extension désactivée, `select('cabinet-ferrand/rendez-vous')` retournait `undefined`, provoquant une erreur JavaScript non interceptée (« Cannot read properties of undefined ») au moment d'appeler `.getDisponibiliteGenerale()`, qui faisait planter le rendu de tout le composant React englobant, pas seulement le badge concerné.

## Ce que la clé Plugin Dependencies ne couvre pas

La fonctionnalité « Plugin Dependencies », introduite avec le champ `Requires Plugins` dans l'en-tête d'un plugin, permet de déclarer qu'une extension a besoin d'une autre pour s'activer, avec un message d'avertissement dans l'administration si la dépendance est manquante. Ce mécanisme couvre les dépendances déclarées au niveau du plugin entier, mais ne protège en rien contre une dépendance de fait entre un bloc précis et un store de données précis, ajoutée après coup sans mise à jour de cet en-tête.

## Correctifs mis en place

1. **Vérification défensive systématique** avant tout appel à un sélecteur d'un store externe, avec un repli explicite plutôt qu'un plantage silencieux :

```
const store = select('cabinet-ferrand/rendez-vous');
const disponibilite = store?.getDisponibiliteGenerale?.() ?? null;

if (disponibilite === null) {
  return null; // Le badge ne s'affiche simplement pas, sans erreur.
}
```

1. **Mise à jour de l'en-tête `Requires Plugins`** de chaque extension concernée, pour au moins avertir dans l'administration en cas de désactivation future de l'extension dont dépendent ces blocs.
2. **Un document de dépendances inter-plugins**, tenu à jour manuellement, recensant tout store ou fonction PHP partagé entre extensions distinctes du même site, un filet qu'aucun mécanisme natif de WordPress ne fournit à ce niveau de granularité.

- Ne jamais supposer qu'un store de données externe est toujours présent, même si c'est vrai depuis des mois.
- Toujours prévoir un repli silencieux plutôt qu'un plantage quand un store ou une fonction externe peut être absente.
- Tester la désactivation de chaque extension en environnement de recette avant toute désactivation en production, même pour une extension jugée obsolète.

> Une dépendance qui n'est écrite nulle part existe quand même : elle attend simplement le jour où quelqu'un désactivera l'extension qui la porte.

## Ce que ce cas ne couvre pas

Les conflits d'extensions au sens large (collision de scripts, de styles, de hooks concurrents) relèvent d'une problématique plus générale déjà traitée ailleurs. Ce retour d'expérience se concentre spécifiquement sur la dépendance cachée entre blocs de plugins différents via un store de données partagé.

## Notre verdict

Douze blocs affectés par la désactivation d'une seule extension jugée sans lien : l'incident a coûté au Cabinet Ferrand une soirée de correctif d'urgence, et surtout a révélé que documenter les dépendances entre plugins d'un même site n'est pas un luxe réservé aux gros projets.
