# 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.

- Auteur : Clément Hadrot
- Publié le : 2021-02-19
- Mis à jour le : 2021-02-19
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/plusieurs-blocs-une-extension-structure-build/

## L’essentiel

- 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

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.
