vendredi 25 septembre 2026

À propos

Contact

Blocs Gutenberg

Plusieurs blocs dans une seule extension : structure, build et enregistrement

Organiser un dossier src/ multi-blocs, un build unique avec @wordpress/scripts et un enregistrement PHP propre, sans multiplier les extensions séparées.

Par Clément Hadrot • 19 février 2021 • 4 min de lecture • Aucun commentaire
Plusieurs blocs dans une seule extension : structure, build et enregistrement

Une extension qui gère cinq types de contenu différents, chacun avec son propre bloc d’affichage, ne justifie pas cinq extensions séparées à activer indépendamment. La bonne échelle reste une seule extension, avec une arborescence organisée pour que l’ajout d’un sixième bloc, dans six mois, ne demande pas de réinventer la structure.

Arborescence de référence

mon-extension/
├── mon-extension.php
├── package.json
├── build/
│   ├── fiche-produit/
│   │   ├── index.js
│   │   ├── index.asset.php
│   │   └── style-index.css
│   └── avis-client/
│       ├── index.js
│       ├── index.asset.php
│       └── style-index.css
└── src/
    ├── fiche-produit/
    │   ├── block.json
    │   ├── edit.js
    │   ├── save.js
    │   ├── index.js
    │   ├── style.scss
    │   └── editor.scss
    └── avis-client/
        ├── block.json
        ├── edit.js
        ├── save.js
        ├── index.js
        ├── style.scss
        └── editor.scss

Chaque bloc vit dans son propre sous-dossier de src/, avec sa propre déclaration block.json, ses propres fichiers edit/save, et ses propres feuilles de style. Cette symétrie entre src/ et build/ rend triviale l’identification de l’origine d’un problème de compilation.

Un build unique avec @wordpress/scripts

Depuis les versions récentes de @wordpress/scripts, la commande build détecte automatiquement plusieurs points d’entrée si elle reçoit un motif de chemin, sans configuration Webpack manuelle :

{
	"scripts": {
		"build": "wp-scripts build src/*/index.js",
		"start": "wp-scripts start src/*/index.js"
	}
}

Cette seule ligne suffit à compiler tous les blocs présents dans src/, chacun dans son propre sous-dossier de sortie sous build/, avec son fichier index.asset.php listant les dépendances et la version de hachage — indispensable pour un wp_enqueue_script qui gère correctement le cache navigateur.

Enregistrement PHP : parcourir plutôt que lister

L'essentiel à retenir : Un dossier par bloc, un point d'entrée par bloc, un seul build global ; php_register_blocks parcourt le dossier plutôt que de lister chaque bloc à la main ; Un fichier index.php par bloc simplifie l'ajout du suivant

Plutôt que d’appeler register_block_type une fois par bloc, un parcours du dossier build/ évite d’oublier une déclaration lors de l’ajout d’un nouveau bloc :

<?php
add_action( 'init', function () {
	foreach ( glob( __DIR__ . '/build/*/block.json' ) as $chemin ) {
		register_block_type( dirname( $chemin ) );
	}
} );

register_block_type accepte directement un chemin de dossier contenant un block.json et se charge de lire le fichier, d’enregistrer les scripts et styles associés selon leurs clés (editorScript, script, style) et de les relier au bloc. Il faut s’assurer que le block.json source est bien copié dans build/ — @wordpress/scripts s’en charge automatiquement depuis les versions qui le supportent nativement.

Nommage : éviter les collisions

Chaque bloc doit porter un nom préfixé par l’espace de noms de l’extension, jamais un nom générique :

  • mon-extension/fiche-produit, jamais simplement fiche-produit.
  • Un préfixe identique sur tous les blocs de l’extension facilite le filtrage dans l’inserteur de blocs et dans les journaux de débogage.
  • Le nom du dossier source peut rester court (fiche-produit), seul le nom déclaré dans block.json porte l’espace de noms complet.

Code partagé entre blocs

Quand plusieurs blocs partagent une fonction utilitaire ou un composant d’interface, un dossier src/shared/ (non compilé en point d’entrée direct) évite la duplication, à condition que chaque index.js l’importe explicitement plutôt que de dupliquer le code.

src/
├── shared/
│   └── formater-prix.js
├── fiche-produit/
│   └── edit.js   // import { formaterPrix } from '../shared/formater-prix';
└── avis-client/
    └── edit.js   // import { formaterPrix } from '../shared/formater-prix';

Sur une extension qui dépasse cinq ou six blocs, le temps gagné par cette organisation en amont dépasse largement le temps investi à la mettre en place dès le premier bloc.

Où cette approche montre ses limites

Cette structure convient à une extension unique avec plusieurs blocs liés fonctionnellement. Si le projet grandit au point de justifier plusieurs équipes travaillant sur des blocs totalement indépendants, avec des cycles de publication distincts, une architecture en plusieurs paquets séparés (un monorepo avec des espaces de travail npm, par exemple) devient plus pertinente — un sujet qui dépasse le cadre d’une extension unique.

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