Sur une mise à jour Drupal 10 vers 11, le cœur passe rarement en premier dans la liste des problèmes. Ce qui bloque, ce sont les modules : un contrib qui n'annonce pas la compatibilité Drupal 11, un module sur mesure qui appelle une API supprimée, une dépendance Composer figée. Avec la fin de vie de Drupal 10 le 9 décembre 2026, il reste peu de temps pour traiter ces cas un par un. Voici la méthode que j'applique pour les traiter, outil par outil.
Les prérequis avant de regarder les modules
La documentation officielle de mise à jour pose deux conditions de départ :
- le site doit tourner sur Drupal 10.3.0 ou plus avant de passer en 11 (dans les faits, visez la dernière 10.6.x) ;
- l'environnement doit fournir PHP 8.3 minimum, exigé par Drupal 11. Si votre hébergement est encore en 8.1 ou 8.2, c'est un chantier en soi, détaillé dans l'article sur la fin de support de PHP 8.2.
Côté outillage, Drush 12 ne gère que Drupal 10 : il faut Drush 13 (compatible Drupal 10.2+ et 11) pour faire la transition.
Mesurer : le module Upgrade Status
Upgrade Status analyse le site courant pour dire ce qui empêche le passage à la version majeure suivante. Il s'installe sur le site Drupal 10 (il faut toujours l'exécuter sur la version de départ), de préférence sur une copie de préproduction. La page du projet décrit une installation via Composer ; en dépendance de développement, cela donne :
composer require --dev drupal/upgrade_status
drush en upgrade_status -y
Si Composer refuse l'installation pour un conflit de dépendances (souvent avec Drush), la page du projet sur drupal.org décrit une procédure qui passe par drupal/core-dev. Le rapport est ensuite disponible dans Rapports > Upgrade Status, ou en ligne de commande :
drush upgrade_status:analyze --all
# ou pour un seul module
drush us-a mon_module
Installé en dépendance de développement, le module doit être désinstallé avant tout déploiement fait avec composer install --no-dev, sinon le site cherchera un module absent.
Lire le rapport
Le rapport range chaque projet dans une catégorie qui correspond à une action :
| Catégorie | Ce qu'elle signifie | Action |
|---|---|---|
| Remove | Projet présent dans le code mais non installé | Le retirer de composer.json |
| Update | Une version plus récente, compatible, existe | Mettre à jour sous Drupal 10 |
| Scan | Code sur mesure (modules, thème) à analyser | Lancer l'analyse, corriger |
| Collaborate with maintainers | Aucune version compatible publiée | Chercher un patch, remplacer ou retirer |
| Compatible | Prêt pour Drupal 11 | Rien |
Le rapport affiche aussi un bloc sur l'environnement (PHP, base de données, version de Drush). Les exigences de Drupal 11.0 sont notamment MySQL 8.0, MariaDB 10.6 ou PostgreSQL 16 au minimum : un vieux serveur MariaDB peut bloquer autant qu'un module.
Deux précautions de lecture. D'abord, l'analyse de code repose sur PHPStan et ne voit pas tout : un appel à un service retiré construit dynamiquement, ou un template Twig qui utilise une fonction supprimée, peut passer entre les mailles. Ensuite, un module marqué « Update » peut avoir une version compatible qui change de branche majeure (par exemple de 1.x à 2.x) : lisez les notes de version avant de la prendre.
Comprendre pourquoi un module est refusé
Un module contrib est refusé à deux niveaux distincts.
Côté Drupal, c'est la clé core_version_requirement de son fichier .info.yml. Tant qu'elle n'inclut pas Drupal 11, le module ne pourra pas être activé :
name: Mon module
type: module
core_version_requirement: ^10.3 || ^11
Côté Composer, c'est la contrainte drupal/core déclarée par le paquet. Pour savoir précisément qui empêche l'installation de Drupal 11, la commande why-not (alias de prohibits) liste les paquets bloquants :
composer why-not drupal/core "^11"
composer why-not drupal/core-recommended "^11" --tree
La sortie donne la liste des modules, bibliothèques ou contraintes du projet qui s'y opposent. C'est plus fiable que de lancer directement la mise à jour et de déchiffrer l'erreur du solveur. Pensez aussi au simulateur : une fois les contraintes modifiées, composer update --dry-run montre ce qui se passerait sans rien écrire.
Quatre stratégies, module par module
Pour chaque module bloquant, il n'y a que quatre issues. L'ordre ci-dessous est celui que je suis : de la moins coûteuse à maintenir à la plus lourde.
1. Mettre à jour
Le cas le plus fréquent : une version compatible Drupal 11 existe déjà, le site n'est simplement pas à jour. Faites ces mises à jour sous Drupal 10, une par une ou par petits lots, avec drush updb et un export de configuration après chacune. Mélanger ces mises à jour avec le changement de version majeure rend le diagnostic très difficile en cas de régression.
composer update drupal/pathauto --with-dependencies
drush updb -y && drush cex -y
2. Appliquer un patch publié sur drupal.org
Si le mainteneur n'a pas encore publié de version compatible, cherchez dans la file d'issues du module un ticket du type « Drupal 11 compatibility ». Il contient souvent une merge request qui corrige les dépréciations et ajoute ^11 au core_version_requirement. On l'applique avec le plugin cweagans/composer-patches :
{
"extra": {
"patches": {
"drupal/mon_module": {
"Drupal 11 compatibility (#0000000)": "patches/mon_module-d11.patch"
}
}
}
}
Piège fréquent : les URL de diff des merge requests drupal.org évoluent à chaque nouveau commit sur la branche. Téléchargez le patch, versionnez-le dans le dépôt et pointez vers le fichier local. Sinon, un composer install en production peut appliquer un contenu différent de celui que vous avez testé.
Compléter le patch côté Composer : le plugin lenient
Un patch qui modifie core_version_requirement règle le problème côté Drupal, pas côté Composer : si le paquet déclare drupal/core: ^9 || ^10, Composer refusera toujours de l'installer avec Drupal 11. C'est là qu'intervient le plugin mglaman/composer-drupal-lenient, qui assouplit cette contrainte pour une liste de projets que vous choisissez :
composer require mglaman/composer-drupal-lenient
composer config --merge --json extra.drupal-lenient.allowed-list '["drupal/mon_module"]'
L'ancien dépôt https://packages.drupal.org/lenient n'existe plus ; s'il figure encore dans votre composer.json, retirez-le. La documentation drupal.org est explicite : ce plugin ne devrait pas être utilisé en production. Il fait taire la vérification de compatibilité, rien de plus. Si vous l'utilisez malgré tout pour tenir une échéance, limitez l'allowed-list au strict nécessaire (jamais allow-all), documentez chaque entrée avec son issue drupal.org, et planifiez son retrait dès qu'une version officielle sort. C'est une dette technique assumée, pas une solution.
3. Remplacer
Un module abandonné depuis des années, sans patch viable, doit être remplacé par un équivalent maintenu. Le coût dépend de ce qu'il stocke : un module d'interface se remplace sans grande difficulté ; un module qui définit des champs ou des entités exige une migration de données, avec un script de mise à jour ou l'API Migrate. Pour évaluer la santé d'un module candidat, regardez la date de la dernière version, la couverture de sécurité (le bouclier sur la page du projet) et l'activité de la file d'issues.
4. Retirer
Beaucoup de sites embarquent des modules installés pour un besoin qui n'existe plus. Upgrade Status ne repère que ceux dont le code traîne sans être installés ; pour les autres, installés mais inutiles, seule une revue fonctionnelle les révèle. Retirer un module se fait en deux temps : désinstallation sous Drupal 10 (drush pm:uninstall mon_module), export de configuration, déploiement, puis suppression du code au déploiement suivant. Supprimer le code d'un module encore installé laisse le site dans un état incohérent.
Les modules retirés du cœur dans Drupal 11
Drupal 11.0 a sorti six modules du cœur, dépréciés au cours de Drupal 10 : Actions UI, Activity Tracker, Book, Forum, Statistics et Tour. Chacun existe désormais comme projet contrib sur drupal.org (par exemple drupal/book ou drupal/forum). La documentation officielle demande de choisir avant la mise à jour :
- soit désinstaller le module s'il ne sert plus ;
- soit ajouter sa version contrib sous Drupal 10.3 ou plus, avant de passer le code en Drupal 11.
composer require drupal/book
Si le module est installé mais que ni la version contrib ni la désinstallation n'ont été faites, la mise à jour échouera. À noter aussi : le fichier .htaccess fourni avec Drupal 11 ne contient plus la règle propre au module Statistics.
Préparez aussi la suite : plusieurs modules sont dépréciés au fil des versions mineures de Drupal 11 et seront retirés de Drupal 12, dont Ban, Contact, History, Search, Shortcut et Telephone. Drupal 12 est annoncé pour la semaine du 7 décembre 2026 : si votre site utilise l'un de ces modules, prévoyez dès maintenant son remplacement ou sa version contrib, pour ne pas refaire l'exercice au prochain passage.
Le code sur mesure : Drupal Rector
Pour les modules et thèmes écrits spécifiquement pour le site, Upgrade Status liste les dépréciations et Drupal Rector en corrige une partie automatiquement. D'après sa documentation, ses règles couvrent les dépréciations de Drupal 10.0 à 11.4.
composer require --dev palantirnet/drupal-rector
cp vendor/palantirnet/drupal-rector/rector.php .
vendor/bin/rector process web/modules/custom/mon_module --dry-run
vendor/bin/rector process web/modules/custom/mon_module
Le projet signale qu'un site encore en Drupal 10 peut rencontrer des conflits de dépendances avec PHPStan ; sa documentation propose alors une configuration autonome. Relisez chaque diff : Rector remplace mécaniquement un appel par son équivalent, mais ne sait pas si l'injection de dépendances de votre classe est correcte, ni si un comportement a changé. Il reste ensuite à la main les cas que Rector ne couvre pas, les templates Twig et les fichiers .info.yml à passer en ^10.3 || ^11.
L'ordre des opérations
- Sous Drupal 10 : cœur en 10.6, contrib à jour, modules retirés du cœur remplacés ou désinstallés, modules inutiles retirés.
- Upgrade Status à vert, sauf les modules traités par patch.
- Code sur mesure corrigé avec Rector puis à la main.
- Mise à jour des contraintes Composer vers
^11,composer update --dry-run, puis la vraie mise à jour,drush updb,drush cex. - Recette complète sur la préproduction avant la mise en production.
Le déroulé complet et les forfaits sont sur la page mise à jour Drupal 10 vers 11. Si vous préférez savoir d'abord combien de modules posent problème sur votre site, l'audit flash fournit cette liste avec une stratégie par module et un chiffrage ferme.