docs(modules): add client manifest generation and update discovery docs
- introduce `OUTPUT_CLIENT` constant and `renderClientManifest` for `'use client'` bundle - rename `renderManifest` to `renderServerManifest` for clarity - update `sync` command to write both server and client manifests - update `findInstalledModuleNames` to support custom package path resolution - rewrite MODULES.md to explain dual-manifest architecture and client hydration rationale
This commit is contained in:
+15
-8
@@ -15,24 +15,31 @@ Aucun fichier de configuration manuelle. La plateforme découvre les modules par
|
||||
|
||||
## Découverte
|
||||
|
||||
Les modules sont activés via un **manifeste statique** généré par la CLI `zen-modules sync` dans le projet consommateur, à `app/.zen/modules.generated.js`. Ce fichier contient des `import * as ...` pour chaque package détecté et appelle `register()` au top level :
|
||||
Les modules sont activés via deux **manifestes statiques** générés par la CLI `zen-modules sync` dans le projet consommateur :
|
||||
|
||||
- `app/.zen/modules.generated.js` — manifeste serveur (importé par `instrumentation.js`).
|
||||
- `app/.zen/modules.client.js` — manifeste client (`'use client'`, importé par `app/layout.js`).
|
||||
|
||||
Les deux fichiers contiennent les mêmes `import * as ... from '@zen/module-X'` mais déclenchent `register()` dans leur bundle respectif. La séparation est nécessaire parce que `app/layout.js` est un Server Component : son graphe d'imports tourne dans le bundle serveur. Pour que les `registerPage()` / `registerWidget()` peuplent aussi le registre côté browser au moment de l'hydratation, il faut un fichier `'use client'` dédié.
|
||||
|
||||
```js
|
||||
// app/.zen/modules.generated.js — AUTO-GÉNÉRÉ
|
||||
// app/.zen/modules.generated.js — AUTO-GÉNÉRÉ (serveur)
|
||||
import * as m0_zen_module_posts from '@zen/module-posts';
|
||||
|
||||
export const modules = [
|
||||
{ name: '@zen/module-posts', exports: m0_zen_module_posts },
|
||||
];
|
||||
|
||||
await Promise.all(modules.map(m => m.exports.register?.()));
|
||||
```
|
||||
|
||||
Le manifeste est importé deux fois :
|
||||
- **Côté serveur** par `instrumentation.js` qui le passe à `initializeZen({ modules })`.
|
||||
- **Côté client** par `app/layout.js` (side-effect import).
|
||||
```js
|
||||
// app/.zen/modules.client.js — AUTO-GÉNÉRÉ (client)
|
||||
'use client';
|
||||
import * as m0_zen_module_posts from '@zen/module-posts';
|
||||
m0_zen_module_posts.register?.();
|
||||
export {};
|
||||
```
|
||||
|
||||
Cette importation statique permet à Turbopack/Webpack d'analyser le graphe complet des modules — JSX, `next/headers`, `next/navigation`, frontières `'use client'` — exactement comme pour le code de l'application elle-même.
|
||||
L'importation statique (le `import * as ...`) permet à Turbopack/Webpack d'analyser le graphe complet du module — JSX, `next/headers`, `next/navigation`, frontières `'use client'` — exactement comme pour le code de l'application elle-même.
|
||||
|
||||
### Critères de détection
|
||||
|
||||
|
||||
Reference in New Issue
Block a user