vendredi 25 septembre 2026

À propos

Contact

Headless & API

Architecture d’un monorepo Next.js et WordPress headless avec Turborepo

Organiser un thème WordPress minimal, des types générés et un front Next.js dans un même monorepo, avec mise en cache intelligente des builds via Turborepo.

Par Clément Hadrot • 24 mai 2022 • 5 min de lecture • Aucun commentaire
Architecture d'un monorepo Next.js et WordPress headless avec Turborepo

À mesure qu’un projet headless grandit, la question de l’organisation des dépôts finit toujours par se poser : faut-il un dépôt pour le thème WordPress minimal, un autre pour le front Next.js, un troisième pour les types partagés ? Sur un projet e-commerce récent, cette dispersion avait fini par ralentir l’équipe, chaque modification de type obligeant à publier un paquet npm intermédiaire avant de pouvoir l’utiliser côté front. Ce billet décrit l’architecture en monorepo Turborepo mise en place pour régler ce problème, sans revenir sur la génération de types elle-même, déjà détaillée dans un autre article de ce blog.

La structure retenue

mon-projet/
├── apps/
│   ├── front/                 # Application Next.js
│   │   ├── app/
│   │   ├── package.json
│   │   └── next.config.js
│   └── wp-theme/              # Thème WordPress minimal (pas de rendu)
│       ├── functions.php
│       └── style.css
├── packages/
│   ├── types-wp/              # Types TypeScript générés depuis le schéma WPGraphQL
│   │   ├── src/index.ts
│   │   └── package.json
│   └── ui/                    # Composants React partagés (boutons, cartes produit)
│       ├── src/
│       └── package.json
├── turbo.json
└── package.json

Le thème WordPress, volontairement minimal, ne sert qu’à déclarer les types de contenu personnalisés et les réglages GraphQL, sans jamais générer de rendu HTML destiné à un visiteur. Il vit néanmoins dans le même dépôt, ce qui permet de versionner ensemble une modification de type de contenu PHP et le type TypeScript correspondant, dans un seul et même commit.

Le fichier turbo.json, cœur de l’organisation des tâches

{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "generate-types": {
      "cache": false
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {
      "outputs": []
    }
  }
}

La clé dependsOn: ["^build"] indique à Turborepo que la tâche build d’un paquet dépend d’abord du build de ses dépendances internes : avant de compiler apps/front, Turborepo s’assure que packages/types-wp et packages/ui sont déjà construits à jour. La tâche generate-types, elle, reste explicitement non mise en cache, car elle dépend de l’état courant du schéma WPGraphQL exposé par WordPress, une donnée externe que Turborepo ne peut pas suivre par empreinte de fichiers.

L'essentiel à retenir : Un seul dépôt pour trois briques qui évoluent ensemble ; Turborepo évite de reconstruire ce qui n'a pas changé ; Les types partagés circulent sans publication npm

La mise en cache des builds, le vrai gain au quotidien

Sur ce projet, une modification isolée dans packages/ui ne déclenche la reconstruction que de ce paquet et de tout ce qui en dépend, jamais du thème WordPress qui n’a pas changé. Turborepo calcule une empreinte à partir du contenu réel des fichiers concernés, et restaure le résultat depuis le cache local, ou depuis un cache distant partagé par l’équipe, si l’empreinte correspond à un build déjà réalisé ailleurs :

$ turbo run build

• Packages in scope: front, types-wp, ui, wp-theme
• Running build in 4 packages
types-wp:build: cache hit, replaying output
ui:build: cache miss, executing
front:build: cache miss, executing
wp-theme:build: cache hit, replaying output

Tasks:    4 successful, 4 total
Cached:   2 cached, 4 total
Time:     18.4s (saved 41.2s)

Sur un projet où seule une petite partie change à chaque commit, ce gain se traduit directement par des temps d’intégration continue plus courts, sans rien sacrifier sur la fiabilité des builds.

Faire circuler les types sans publication npm

Le paquet packages/types-wp est référencé directement dans le package.json de apps/front via le protocole de dépendance locale des gestionnaires de paquets modernes :

{
  "dependencies": {
    "@mon-projet/types-wp": "workspace:*"
  }
}

Aucune publication sur un registre npm, même privé, n’est nécessaire : le gestionnaire de paquets crée un lien symbolique local vers le paquet du monorepo, ce qui permet de modifier un type et de voir immédiatement l’effet côté front, sans étape de publication intermédiaire à attendre.

Les limites rencontrées

  • Le thème WordPress lui-même reste déployé séparément sur l’hébergement WordPress, le monorepo n’unifie que le code source, pas le déploiement final.
  • L’équipe a dû s’habituer à la discipline des espaces de travail (workspaces), en particulier pour éviter d’installer une dépendance au mauvais niveau du monorepo.
  • Le cache distant de Turborepo demande une configuration d’accès à un compte Vercel ou un serveur de cache auto-hébergé, une étape supplémentaire à ne pas négliger dans la mise en place initiale.

Un monorepo n’apporte de valeur que si les briques qu’il regroupe évoluent réellement ensemble : forcer un thème WordPress et un front dans le même dépôt sans lien de dépendance réel n’apporterait aucun bénéfice, seulement de la complexité.

En résumé

Sur ce projet, Turborepo a permis de faire cohabiter le thème WordPress minimal, les types générés et le front Next.js dans une seule base de code cohérente, avec des builds nettement plus rapides grâce à la mise en cache par empreinte de fichiers. Ce n’est pas une architecture universelle : elle prend tout son sens à partir du moment où plusieurs paquets internes dépendent réellement les uns des autres, ce qui était précisément le cas sur ce projet e-commerce en pleine croissance.

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