Avant WordPress 6.5, charger un fichier JavaScript en module ES natif (avec des instructions import/export directement interprétées par le navigateur, sans passer par un bundler qui les transforme) demandait un bricolage manuel : ajouter type="module" à la balise <script> générée par wp_enqueue_script() via un filtre, en espérant que rien d’autre dans l’écosystème ne s’attende à un script classique à cet endroit. WordPress 6.5, sortie en avril 2024, a mis fin à ce bricolage avec une API dédiée aux modules ES.
Ce guide couvre l’essentiel pour un développeur de blocs qui veut comprendre où et pourquoi utiliser cette nouvelle API, sans entrer dans le détail de l’Interactivity API elle-même, qui s’appuie sur ces mêmes fondations mais mérite un traitement à part entière.
Pourquoi des modules plutôt que des scripts classiques
Un script classique enregistré avec wp_enqueue_script() pollue l’espace de nommage global si on n’y prend pas garde, et gère mal le partage de code entre plusieurs fichiers sans convention manuelle. Un module ES natif, lui, encapsule son propre espace de portée, déclare explicitement ses dépendances via import, et permet au navigateur de charger et mettre en cache chaque module séparément, potentiellement partagé entre plusieurs blocs sans dupliquer le code.
Enregistrer un module avec wp_register_script_module
La fonction wp_register_script_module() s’utilise de façon similaire à wp_register_script(), avec une différence de taille : elle attend un fichier écrit en syntaxe de module ES valide, et gère les dépendances via un tableau qui peut référencer d’autres modules déjà enregistrés.
wp_register_script_module(
'agence/utilitaires-carte',
plugins_url( 'build/utilitaires-carte.js', __FILE__ ),
array(),
'1.0.0'
);
wp_register_script_module(
'agence/carte-points-vente-view',
plugins_url( 'build/carte-view.js', __FILE__ ),
array( 'agence/utilitaires-carte' ),
'1.0.0'
);
Le fichier carte-view.js peut alors importer directement le module utilitaire, sans configuration de bundler supplémentaire :
import { formaterDistance } from 'agence/utilitaires-carte';
formaterDistance( 12.4 );

viewScriptModule dans block.json
Pour un bloc, la clé viewScriptModule de block.json associe un module ES au rendu front du bloc, chargé uniquement sur les pages qui affichent réellement ce bloc — comme le faisait déjà viewScript pour les scripts classiques, mais avec les avantages des modules ES pour le partage de dépendances.
{
"apiVersion": 3,
"name": "agence/carte-points-vente",
"viewScriptModule": "file:./view.js"
}
La notation file:./view.js indique à WordPress de résoudre automatiquement le module relatif au dossier du bloc et de l’enregistrer via wp_register_script_module() sous le capot, sans appel PHP manuel supplémentaire — un confort similaire à celui qu’offrait déjà viewScript avec la même syntaxe file:.
Les import maps pour les dépendances partagées
Quand plusieurs modules de blocs différents dépendent d’une même bibliothèque tierce, une import map permet de déclarer un alias unique résolu par le navigateur, plutôt que de dupliquer l’import du fichier physique dans chaque module :
add_filter( 'wp_script_modules_import_map', function ( $map ) {
$map['imports']['leaflet'] = plugins_url( 'vendor/leaflet.js', __FILE__ );
return $map;
} );
Chaque module qui écrit ensuite import * as L from 'leaflet'; se voit résolu vers ce même fichier physique, chargé une seule fois par le navigateur même si plusieurs blocs différents en dépendent indépendamment.
Ce qui ne change pas
- Un bloc qui n’a besoin d’aucune interactivité côté front (un bloc purement statique de mise en page) n’a aucune raison d’adopter
viewScriptModule:viewScriptclassique reste parfaitement valide et plus simple pour ce cas. - Le support des navigateurs anciens sans modules ES natifs (une part désormais marginale du trafic web) doit être vérifié si le site cible un public avec des navigateurs très datés ; les modules ES sont largement supportés depuis plusieurs années sur les navigateurs à jour.
- Le processus de build avec
@wordpress/scriptscontinue de fonctionner normalement ; les modules ES sont transpilés correctement pourvu que la configuration webpack sous-jacente les traite comme telle, ce que gèrewp-scriptspar défaut pour les fichiers déclarés viaviewScriptModule.
Un point de vigilance en développement
Les erreurs de résolution de module (un chemin d’import incorrect, une dépendance non enregistrée dans l’import map) ne remontent pas toujours clairement en PHP : elles apparaissent dans la console du navigateur sous forme d’erreur de chargement de module. On garde systématiquement la console ouverte pendant les tests d’un nouveau module ES pour repérer ce type d’erreur silencieuse côté serveur.
Un réflexe qu’on a adopté en équipe : nommer les modules avec le préfixe de l’extension (
agence/nom-du-module) plutôt qu’un nom générique, pour éviter toute collision avec un module du même nom enregistré par une autre extension sur le même site.
En résumé
WordPress 6.5 a normalisé ce qui relevait auparavant du bricolage : charger un vrai module ES natif, avec ses propres imports et exports, sans détourner l’API de scripts classiques. Pour un bloc qui a besoin d’interactivité front, viewScriptModule et wp_register_script_module() forment désormais la base recommandée, sur laquelle s’appuie également l’Interactivity API pour ses propres fondations techniques.