@nodefony/frontend 10.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +544 -0
- package/README.md +338 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
- package/dist/index.js +63 -0
- package/dist/nodefony/command/frontend-build.js +68 -0
- package/dist/nodefony/command/frontend-dev.js +31 -0
- package/dist/nodefony/command/frontend-status.js +40 -0
- package/dist/nodefony/config/config.js +65 -0
- package/dist/nodefony/config/defineModuleConfig.js +34 -0
- package/dist/nodefony/interfaces/IFrontBuilder.js +1 -0
- package/dist/nodefony/interfaces/IFrontPreset.js +1 -0
- package/dist/nodefony/interfaces/IFrontendService.js +1 -0
- package/dist/nodefony/interfaces/IViteSupervisor.js +1 -0
- package/dist/nodefony/interfaces/index.js +1 -0
- package/dist/nodefony/service/FrontendService.js +708 -0
- package/dist/nodefony/service/ViteConfigGenerator.js +139 -0
- package/dist/nodefony/service/ViteProcessSupervisor.js +589 -0
- package/dist/nodefony/src/FrontendAdminApi.js +113 -0
- package/dist/nodefony/src/builders/ViteBuilder.js +75 -0
- package/dist/nodefony/src/errors/FrontendError.js +50 -0
- package/dist/nodefony/src/isolationGroups.js +116 -0
- package/dist/nodefony/src/presets/angular-vite.js +27 -0
- package/dist/nodefony/src/presets/react19-vite.js +26 -0
- package/dist/nodefony/src/presets/svelte5-vite.js +37 -0
- package/dist/nodefony/src/presets/vanilla-vite.js +17 -0
- package/dist/nodefony/src/presets/vue3-vite.js +23 -0
- package/dist/nodefony/src/remoteDev.js +157 -0
- package/dist/nodefony/src/template/TemplateHelper.js +255 -0
- package/dist/types/index.d.ts +51 -0
- package/dist/types/nodefony/command/frontend-build.d.ts +17 -0
- package/dist/types/nodefony/command/frontend-dev.d.ts +12 -0
- package/dist/types/nodefony/command/frontend-status.d.ts +14 -0
- package/dist/types/nodefony/config/config.d.ts +38 -0
- package/dist/types/nodefony/config/defineModuleConfig.d.ts +29 -0
- package/dist/types/nodefony/interfaces/IFrontBuilder.d.ts +69 -0
- package/dist/types/nodefony/interfaces/IFrontPreset.d.ts +26 -0
- package/dist/types/nodefony/interfaces/IFrontendService.d.ts +77 -0
- package/dist/types/nodefony/interfaces/IViteSupervisor.d.ts +56 -0
- package/dist/types/nodefony/interfaces/index.d.ts +4 -0
- package/dist/types/nodefony/service/FrontendService.d.ts +230 -0
- package/dist/types/nodefony/service/ViteConfigGenerator.d.ts +66 -0
- package/dist/types/nodefony/service/ViteProcessSupervisor.d.ts +214 -0
- package/dist/types/nodefony/src/FrontendAdminApi.d.ts +63 -0
- package/dist/types/nodefony/src/builders/ViteBuilder.d.ts +17 -0
- package/dist/types/nodefony/src/errors/FrontendError.d.ts +34 -0
- package/dist/types/nodefony/src/isolationGroups.d.ts +89 -0
- package/dist/types/nodefony/src/presets/angular-vite.d.ts +15 -0
- package/dist/types/nodefony/src/presets/react19-vite.d.ts +9 -0
- package/dist/types/nodefony/src/presets/svelte5-vite.d.ts +13 -0
- package/dist/types/nodefony/src/presets/vanilla-vite.d.ts +9 -0
- package/dist/types/nodefony/src/presets/vue3-vite.d.ts +11 -0
- package/dist/types/nodefony/src/remoteDev.d.ts +107 -0
- package/dist/types/nodefony/src/template/TemplateHelper.d.ts +99 -0
- package/docs/index.md +925 -0
- package/package.json +80 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Famille d'isolation Vite d'un type de preset frontend.
|
|
3
|
+
*
|
|
4
|
+
* Les presets d'une même famille **cohabitent dans une seule instance Vite** ;
|
|
5
|
+
* les familles distinctes tournent dans des **process Vite séparés** (multi-
|
|
6
|
+
* supervisor).
|
|
7
|
+
*
|
|
8
|
+
* **Le motif est toujours le même : un plugin qui transforme ce qui ne lui
|
|
9
|
+
* appartient pas.** Deux familles le paient aujourd'hui.
|
|
10
|
+
*
|
|
11
|
+
* Angular : son plugin (`@analogjs/vite-plugin-angular`) transforme **tout**
|
|
12
|
+
* fichier `.ts` du serveur de développement — y compris ceux des autres bundles
|
|
13
|
+
* (ex. stores MobX à décorateurs). Mélangé aux autres, il throw sur des fichiers
|
|
14
|
+
* hors de son tsconfig → erreurs de compilation + boucle de rechargement.
|
|
15
|
+
*
|
|
16
|
+
* Vue : le compilateur de composants monofichiers sert le bloc script sous un
|
|
17
|
+
* identifiant qui se TERMINE par `.ts`
|
|
18
|
+
* (`App.vue?vue&type=script&setup=true&lang.ts`). Le filtre de
|
|
19
|
+
* `@vitejs/plugin-react` y mord — il est élargi aux identifiants portant une
|
|
20
|
+
* query — et injecte son `$RefreshSig$()`, que rien ne définit sur une page sans
|
|
21
|
+
* préambule React : la vitrine Vue ne se montait plus du tout
|
|
22
|
+
* (`ReferenceError: $RefreshSig$ is not defined`).
|
|
23
|
+
*
|
|
24
|
+
* ⚠️ Il a longtemps été écrit ici que « React / Vue / vanilla ciblent des
|
|
25
|
+
* extensions disjointes ». C'était faux, et c'est ce qui a fait chercher
|
|
26
|
+
* ailleurs. Passer `exclude: [/\.vue/]` à `@vitejs/plugin-react` **ne suffit
|
|
27
|
+
* pas** : mesuré sur Vite 8.2.2, l'injection persiste jusqu'à `exclude: [/./]`
|
|
28
|
+
* inclus — l'option ne borne pas ce chemin. Seule l'isolation en process
|
|
29
|
+
* distinct l'arrête.
|
|
30
|
+
*
|
|
31
|
+
* Svelte, lui, cohabite sans dommage (constaté) : son bloc script n'est pas
|
|
32
|
+
* servi sous un identifiant qui finit par `.ts`.
|
|
33
|
+
*
|
|
34
|
+
* @param type - type de preset déclaré par le module (`react19`, `vue3`,
|
|
35
|
+
* `angular`, `vanilla`, …).
|
|
36
|
+
* @returns la clé de famille d'isolation (`"default"` pour tout ce qui peut
|
|
37
|
+
* partager une instance, une clé dédiée pour ce qui doit être isolé).
|
|
38
|
+
*/
|
|
39
|
+
export declare function isolationGroup(type: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Famille servie sur le port de base (`devPort`). Les autres familles prennent
|
|
42
|
+
* les blocs de ports suivants. Garder `default` ici garantit que l'instance
|
|
43
|
+
* principale (React/Vue/Studio) reste sur le port habituel (5173).
|
|
44
|
+
*/
|
|
45
|
+
export declare const PRIMARY_FAMILY = "default";
|
|
46
|
+
/**
|
|
47
|
+
* Ordonne les familles de façon déterministe : la famille primaire d'abord
|
|
48
|
+
* (port de base), puis les autres triées alphabétiquement. L'ordre fixe le
|
|
49
|
+
* port attribué à chaque famille — il doit être stable entre deux démarrages.
|
|
50
|
+
*
|
|
51
|
+
* @param families - familles présentes (clés de regroupement des entries).
|
|
52
|
+
* @returns familles ordonnées, `PRIMARY_FAMILY` en tête s'il est présent.
|
|
53
|
+
*/
|
|
54
|
+
export declare function orderFamilies(families: ReadonlyArray<string>): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Plan d'allocation des ports : un **bloc disjoint** par famille. Chaque famille
|
|
57
|
+
* réserve `portRetryAttempts + 1` ports consécutifs → le port-retry d'une
|
|
58
|
+
* instance (sur EADDRINUSE) ne peut jamais empiéter sur le bloc d'une autre
|
|
59
|
+
* famille. La famille primaire (index 0) garde `devPort` (le port habituel).
|
|
60
|
+
*
|
|
61
|
+
* @param devPort - port de base de la première famille (ex. 5173).
|
|
62
|
+
* @param families - familles présentes ; réordonnées en interne via `orderFamilies`.
|
|
63
|
+
* @param portRetryAttempts - tentatives de port-retry par instance (bloc = +1).
|
|
64
|
+
* @returns map ordonnée `famille → port de base de son bloc`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function familyPortPlan(devPort: number, families: ReadonlyArray<string>, portRetryAttempts: number): Map<string, number>;
|
|
67
|
+
/**
|
|
68
|
+
* Bloc de ports de chaque famille : tous les ports que SON instance Vite peut
|
|
69
|
+
* prendre, port-retry compris.
|
|
70
|
+
*
|
|
71
|
+
* Le plan seul ne dit que le port ESPÉRÉ ; sur `EADDRINUSE` le superviseur
|
|
72
|
+
* glisse dans son bloc. Un CSP construit sur le seul port espéré laisse la page
|
|
73
|
+
* sans rechargement à chaud dès que le port de base est pris — et il l'est dès
|
|
74
|
+
* qu'un second projet tourne sur la machine.
|
|
75
|
+
*
|
|
76
|
+
* Rendu par famille, et non à plat : le consommateur remplace le bloc d'une
|
|
77
|
+
* famille par son port RÉEL dès qu'il est connu. Déclarer les douze ports d'un
|
|
78
|
+
* poste à trois familles coûte un en-tête CSP de ~8 Ko sur chaque réponse
|
|
79
|
+
* (mesuré) — la plage est le prix d'une incertitude, elle ne doit pas survivre
|
|
80
|
+
* à sa levée.
|
|
81
|
+
*
|
|
82
|
+
* Dérivé du plan plutôt que recalculé depuis `devPort` : la règle des blocs
|
|
83
|
+
* disjoints n'est écrite qu'à un endroit, `familyPortPlan`.
|
|
84
|
+
*
|
|
85
|
+
* @param plan - `famille → port de base`, tel que rendu par `familyPortPlan`.
|
|
86
|
+
* @param portRetryAttempts - tentatives de port-retry par instance (bloc = +1).
|
|
87
|
+
* @returns `famille → ports du bloc`, croissants.
|
|
88
|
+
*/
|
|
89
|
+
export declare function familyPortBlocks(plan: ReadonlyMap<string, number>, portRetryAttempts: number): Map<string, number[]>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IFrontPreset } from "../../interfaces/IFrontPreset.js";
|
|
2
|
+
/**
|
|
3
|
+
* Preset Angular (17+ standalone) + Vite via `@analogjs/vite-plugin-angular`.
|
|
4
|
+
*
|
|
5
|
+
* Charge le plugin paresseusement : aucune dépendance Angular tant qu'aucune
|
|
6
|
+
* entrée `angular` n'est déclarée. Comme React/Vue, aucun preamble HTML n'est
|
|
7
|
+
* requis — `bootstrapApplication(AppComponent)` dans le point d'entrée suffit.
|
|
8
|
+
*
|
|
9
|
+
* ⚠️ Contrairement à `.vue`/`.tsx`, le plugin Angular transforme les `.ts`
|
|
10
|
+
* (extension non dédiée). Le scoping se fait via le `tsconfig` de l'app Angular
|
|
11
|
+
* (passé par `ViteConfigGenerator`) dont le `include` ne couvre que le frontend
|
|
12
|
+
* Angular — les `main.ts` des autres bundles (Vue) restent hors programme.
|
|
13
|
+
*/
|
|
14
|
+
declare const angularPreset: IFrontPreset;
|
|
15
|
+
export default angularPreset;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IFrontPreset } from "../../interfaces/IFrontPreset.js";
|
|
2
|
+
/**
|
|
3
|
+
* Preset React 19 + Vite.
|
|
4
|
+
*
|
|
5
|
+
* Charge `@vitejs/plugin-react` paresseusement : aucune dépendance
|
|
6
|
+
* sur le module si aucune entrée React n'est déclarée.
|
|
7
|
+
*/
|
|
8
|
+
declare const react19Preset: IFrontPreset;
|
|
9
|
+
export default react19Preset;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IFrontPreset } from "../../interfaces/IFrontPreset.js";
|
|
2
|
+
/**
|
|
3
|
+
* Preset Svelte 5 + Vite.
|
|
4
|
+
*
|
|
5
|
+
* Charge `@sveltejs/vite-plugin-svelte` paresseusement : aucune dépendance sur
|
|
6
|
+
* le module tant qu'aucune entrée Svelte n'est déclarée — c'est l'application
|
|
7
|
+
* qui porte `svelte` et le plugin en devDependencies. Comme Vue, Svelte n'exige
|
|
8
|
+
* aucun preamble HMR injecté côté serveur (`mount(App, { target })` suffit) ;
|
|
9
|
+
* il cohabite donc dans la famille d'isolation `default` (extensions `.svelte`
|
|
10
|
+
* disjointes de `.tsx`/`.vue`).
|
|
11
|
+
*/
|
|
12
|
+
declare const svelte5Preset: IFrontPreset;
|
|
13
|
+
export default svelte5Preset;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IFrontPreset } from "../../interfaces/IFrontPreset.js";
|
|
2
|
+
/**
|
|
3
|
+
* Preset vanilla — TS/JS sans framework.
|
|
4
|
+
*
|
|
5
|
+
* Aucun plugin Vite, utile pour les modules qui n'ont besoin
|
|
6
|
+
* que de bundling ESM + HMR de base.
|
|
7
|
+
*/
|
|
8
|
+
declare const vanillaPreset: IFrontPreset;
|
|
9
|
+
export default vanillaPreset;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IFrontPreset } from "../../interfaces/IFrontPreset.js";
|
|
2
|
+
/**
|
|
3
|
+
* Preset Vue 3 + Vite.
|
|
4
|
+
*
|
|
5
|
+
* Charge `@vitejs/plugin-vue` paresseusement : aucune dépendance
|
|
6
|
+
* sur le module tant qu'aucune entrée Vue n'est déclarée. Contrairement
|
|
7
|
+
* à React, Vue ne nécessite aucun preamble HMR injecté côté serveur —
|
|
8
|
+
* `createApp(App).mount(...)` dans le point d'entrée suffit.
|
|
9
|
+
*/
|
|
10
|
+
declare const vue3Preset: IFrontPreset;
|
|
11
|
+
export default vue3Preset;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev déporté (P14.17) — calculs PURS d'origine publique du dev server Vite.
|
|
3
|
+
*
|
|
4
|
+
* Le problème résolu : `devHost` est une adresse d'ÉCOUTE ; l'origine que le
|
|
5
|
+
* NAVIGATEUR utilise peut être toute autre chose — un forwarder TLS (Codespaces,
|
|
6
|
+
* Gitpod), une passerelle de conteneur (`host.docker.internal`), un port remappé.
|
|
7
|
+
* Ce module dissocie les deux : il produit l'origine publique (assets, `base`
|
|
8
|
+
* Vite, WebSocket HMR) à partir d'un TEMPLATE (`{port}` substitué au port réel
|
|
9
|
+
* du spawn) — explicite (`frontend.publicOrigin`) ou détecté depuis
|
|
10
|
+
* l'environnement de la plateforme.
|
|
11
|
+
*
|
|
12
|
+
* Tout est pur et injectable (env en paramètre) : testable sans process, sans
|
|
13
|
+
* réseau, sur les trois plateformes.
|
|
14
|
+
*
|
|
15
|
+
* Formats VÉRIFIÉS (docs officielles + source Vite 8) :
|
|
16
|
+
* - Codespaces : `https://${CODESPACE_NAME}-${port}.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}`
|
|
17
|
+
* (TLS terminé par le forwarder → WS HMR en `wss` sur 443).
|
|
18
|
+
* - Gitpod classic : `https://${port}-<hôte de GITPOD_WORKSPACE_URL>`.
|
|
19
|
+
* - Vite `server.allowedHosts` : IP et `localhost`/`*.localhost` TOUJOURS
|
|
20
|
+
* acceptés ; un préfixe `.` = le domaine ET tous ses sous-domaines.
|
|
21
|
+
* - VS Code Remote / dev containers / WSL2 : forwarding sur `localhost` →
|
|
22
|
+
* les défauts locaux suffisent, aucune détection requise.
|
|
23
|
+
*/
|
|
24
|
+
/** Placeholder substitué par le port réel du spawn dans un template d'origine. */
|
|
25
|
+
export declare const PORT_PLACEHOLDER = "{port}";
|
|
26
|
+
/** Résultat d'un template résolu contre un port réel. */
|
|
27
|
+
export interface IResolvedPublicOrigin {
|
|
28
|
+
/** Origine que le navigateur utilise — verbatim dans les `<script>` et le `base` Vite. */
|
|
29
|
+
readonly origin: string;
|
|
30
|
+
/**
|
|
31
|
+
* Config `server.hmr` cliente : le WS HMR doit suivre le MÊME chemin que les
|
|
32
|
+
* assets. Port implicite → 443/80 selon le scheme (cas forwarder TLS).
|
|
33
|
+
*/
|
|
34
|
+
readonly hmr: {
|
|
35
|
+
readonly host: string;
|
|
36
|
+
readonly clientPort: number;
|
|
37
|
+
readonly protocol: "ws" | "wss";
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Environnement de dev déporté détecté depuis les variables de la plateforme. */
|
|
41
|
+
export interface IRemoteDevDetection {
|
|
42
|
+
readonly provider: "codespaces" | "gitpod";
|
|
43
|
+
/** Template d'origine publique du dev server Vite (`{port}` à substituer). */
|
|
44
|
+
readonly originTemplate: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Hôte utilisable par un NAVIGATEUR pour une adresse d'écoute donnée.
|
|
48
|
+
* `0.0.0.0`/`::` sont des adresses d'ÉCOUTE (toutes interfaces), pas des
|
|
49
|
+
* destinations : dérivées telles quelles dans une URL, elles donnent des
|
|
50
|
+
* `<script src="http://0.0.0.0:5173/…">` que les navigateurs refusent — et
|
|
51
|
+
* sous Windows, une CONNEXION vers `0.0.0.0` échoue aussi (health check).
|
|
52
|
+
*/
|
|
53
|
+
export declare function browserReachableHost(listenHost: string): string;
|
|
54
|
+
/** Un template d'origine est-il syntaxiquement valide ? (autorité unique) */
|
|
55
|
+
export declare function isValidOriginTemplate(template: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Rejoue une origine résolue sur un AUTRE nom d'hôte, en conservant le scheme
|
|
58
|
+
* et le port. Pure.
|
|
59
|
+
*
|
|
60
|
+
* C'est le cœur de la dérivation par requête : le scheme et le port sont ceux
|
|
61
|
+
* du serveur Vite (il écoute où il écoute), seul le NOM change — celui par
|
|
62
|
+
* lequel le client est arrivé. Une page servie sur `http://poste:5151` charge
|
|
63
|
+
* donc `https://poste:5173` si Vite est en TLS : le scheme ne se déduit JAMAIS
|
|
64
|
+
* de la page.
|
|
65
|
+
*
|
|
66
|
+
* `new URL()` est volontairement évité (une allocation par page rendue, pour
|
|
67
|
+
* une chaîne dont nous produisons nous-mêmes la grammaire).
|
|
68
|
+
*
|
|
69
|
+
* @param origin - origine résolue (`scheme://hôte[:port]`).
|
|
70
|
+
* @param hostname - nom d'hôte de remplacement, SANS port (`Context.domain`) ;
|
|
71
|
+
* une IPv6 est acceptée sous sa forme canonique entre crochets (`[::1]`).
|
|
72
|
+
* @returns l'origine réécrite, ou `null` si l'un des deux est inexploitable
|
|
73
|
+
* (l'appelant garde alors l'origine d'origine — jamais d'URL bancale émise).
|
|
74
|
+
*/
|
|
75
|
+
export declare function originWithHostname(origin: string, hostname: string): string | null;
|
|
76
|
+
/**
|
|
77
|
+
* Résout un template d'origine contre le port RÉEL du spawn. Pure.
|
|
78
|
+
*
|
|
79
|
+
* @returns origine + config HMR cliente, ou `null` si le template est invalide
|
|
80
|
+
* (l'appelant retombe sur la dérivation locale en l'ANNONÇANT — jamais en
|
|
81
|
+
* silence).
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveOriginTemplate(template: string, port: number): IResolvedPublicOrigin | null;
|
|
84
|
+
/**
|
|
85
|
+
* Motif `server.allowedHosts` couvrant TOUTES les origines qu'un template peut
|
|
86
|
+
* produire. `{port}` dans l'hôte → le sous-domaine varie avec le port : motif
|
|
87
|
+
* `.suffixe` (wildcard Vite = domaine + sous-domaines). Hôte fixe → verbatim.
|
|
88
|
+
*
|
|
89
|
+
* @returns le motif, ou `null` si template invalide ou hôte non exprimable
|
|
90
|
+
* (un `{port}` dans le DERNIER label n'a pas de suffixe à wildcarder).
|
|
91
|
+
*/
|
|
92
|
+
export declare function allowedHostPatternForTemplate(template: string): string | null;
|
|
93
|
+
/**
|
|
94
|
+
* Motif Vite `allowedHosts` équivalent d'un pattern `trustedHosts` http.
|
|
95
|
+
* `*.suffixe` (wildcard un-label de la barrière Host) → `.suffixe` (wildcard
|
|
96
|
+
* Vite). Un `*` ailleurs n'est pas exprimable chez Vite → `null` (l'hôte reste
|
|
97
|
+
* couvert par la barrière Nodefony ; Vite le refusera — motif à écrire en
|
|
98
|
+
* clair dans `trustedHosts` si le cas se présente).
|
|
99
|
+
*/
|
|
100
|
+
export declare function viteAllowedHostFromPattern(pattern: string): string | null;
|
|
101
|
+
/**
|
|
102
|
+
* Détecte un environnement de dev déporté depuis les variables de plateforme
|
|
103
|
+
* (variables qu'on ne possède pas — elles se lisent, ne se renomment pas).
|
|
104
|
+
* Ordre : Codespaces puis Gitpod (jamais les deux posées en pratique).
|
|
105
|
+
* Env local/VS Code Remote/WSL2 → `null` (les défauts locaux suffisent).
|
|
106
|
+
*/
|
|
107
|
+
export declare function detectRemoteDev(env: Readonly<Record<string, string | undefined>>): IRemoteDevDetection | null;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { IViteSupervisor } from "../../interfaces/IViteSupervisor.js";
|
|
2
|
+
import type { IResolvedFrontendEntry } from "../../interfaces/IFrontBuilder.js";
|
|
3
|
+
/**
|
|
4
|
+
* Génère les balises HTML à injecter dans la page rendue côté serveur
|
|
5
|
+
* pour brancher le frontend Vite.
|
|
6
|
+
*
|
|
7
|
+
* Dev : `<script type="module" src="http://host:port/@vite/client">` + entry.
|
|
8
|
+
* Prod : lira `manifest.json` du build pour les chemins fingerprintés (TODO).
|
|
9
|
+
*/
|
|
10
|
+
export declare class TemplateHelper {
|
|
11
|
+
private readonly supervisor;
|
|
12
|
+
private readonly mode;
|
|
13
|
+
private readonly entries;
|
|
14
|
+
private readonly assetBaseUrl;
|
|
15
|
+
/**
|
|
16
|
+
* Manifests Vite parsés, cachés par `outDir` (lecture disque 1× par bundle).
|
|
17
|
+
* `null` = lecture tentée mais manifest absent/illisible (build manquant).
|
|
18
|
+
*/
|
|
19
|
+
private readonly manifestCache;
|
|
20
|
+
/** `index.html` des modules, caché par `root` (prod only — dev re-lit). */
|
|
21
|
+
private readonly indexCache;
|
|
22
|
+
/**
|
|
23
|
+
* @param supervisor superviseur Vite (dev) — `null` en prod (Vite ne tourne pas).
|
|
24
|
+
* @param mode bascule dev (URLs vers le dev server) / prod (manifest).
|
|
25
|
+
* @param entries entrées résolues — requises en prod pour `outDir`/`publicPath`.
|
|
26
|
+
* @param assetBaseUrl base CDN normalisée (sans slash final) préfixant les URLs
|
|
27
|
+
* prod émises ; `""` = origine Nodefony (chemins relatifs).
|
|
28
|
+
*/
|
|
29
|
+
constructor(supervisor: IViteSupervisor | null, mode: "development" | "production", entries?: ReadonlyArray<IResolvedFrontendEntry>, assetBaseUrl?: string);
|
|
30
|
+
/**
|
|
31
|
+
* Tags à injecter dans `<head>` (ou avant `</body>`) pour une entrée donnée.
|
|
32
|
+
* @param entryName nom logique de l'entrée (matche `entryName` dans IResolvedFrontendEntry)
|
|
33
|
+
* @param nonce nonce CSP de la requête (`Context.cspNonce`) — posé sur les `<script>`
|
|
34
|
+
* pour satisfaire `script-src 'nonce-…'` (preamble inline dev + entrée prod).
|
|
35
|
+
* @param requestHost nom d'hôte par lequel le client a demandé la PAGE
|
|
36
|
+
* (`Context.domain`, sans port). Dev : l'origine des assets est réécrite
|
|
37
|
+
* sur ce nom (scheme et port restent ceux de Vite) → poste et conteneur
|
|
38
|
+
* servis par la même instance. Prod : **ignoré** — les URLs du manifest
|
|
39
|
+
* sont relatives au document, elles suivent déjà l'hôte de la page.
|
|
40
|
+
*/
|
|
41
|
+
renderTags(entryName: string, nonce?: string, requestHost?: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Document HTML complet pour une entrée : lit l'`index.html` du module (le dev
|
|
44
|
+
* y met SES meta/polices/scripts externes), retire le `<script type=module>`
|
|
45
|
+
* de l'entrée source (Vite-native, non résolvable quand Nodefony sert la page)
|
|
46
|
+
* et injecte les tags Nodefony — au marqueur `<!--nodefony:frontend-->` sinon
|
|
47
|
+
* avant `</head>`. Pas d'`index.html` → coquille minimale générée.
|
|
48
|
+
*
|
|
49
|
+
* @param entryName nom logique de l'entrée
|
|
50
|
+
*/
|
|
51
|
+
renderDocument(entryName: string, nonce?: string, requestHost?: string): string;
|
|
52
|
+
/** Injecte `tags` dans `html` (marqueur > `</head>` > `</body>` > append). */
|
|
53
|
+
private injectIntoHtml;
|
|
54
|
+
/**
|
|
55
|
+
* Lit `${root}/index.html`. Caché par root en **prod** (hot path) ; en dev,
|
|
56
|
+
* re-lu à chaque appel pour refléter les éditions du shell. `null` si absent.
|
|
57
|
+
*/
|
|
58
|
+
private loadIndexHtml;
|
|
59
|
+
private renderDevTags;
|
|
60
|
+
/**
|
|
61
|
+
* Pont HMR sans socket : relaie les événements globaux de Vite
|
|
62
|
+
* (`vite:afterUpdate`, etc.) vers un `CustomEvent` `nodefony:hmr` sur `window`,
|
|
63
|
+
* que la debug bar écoute. `createHotContext` réutilise le client HMR déjà
|
|
64
|
+
* ouvert par `@vite/client` — zéro connexion ajoutée. Tolérant aux versions
|
|
65
|
+
* (try/catch) : si l'export change, le compteur HMR reste à 0 sans casser la page.
|
|
66
|
+
*/
|
|
67
|
+
private hmrBridgeTag;
|
|
68
|
+
/**
|
|
69
|
+
* Tag d'injection de la debug bar (subpath `nodefony/debugbar`). Résout le
|
|
70
|
+
* fichier dist navigateur côté serveur (1×, caché) et le sert via `/@fs`.
|
|
71
|
+
* Renvoie un commentaire HTML (jamais d'erreur) si le subpath est irrésoluble.
|
|
72
|
+
*/
|
|
73
|
+
private debugBarTag;
|
|
74
|
+
/**
|
|
75
|
+
* Prod : lit le `manifest.json` du build Vite (caché par `outDir`) et injecte
|
|
76
|
+
* les assets fingerprintés du chunk d'entrée — JS + CSS + preload des imports
|
|
77
|
+
* partagés — préfixés par le `publicPath` de l'entrée (servi par `Statics`).
|
|
78
|
+
*/
|
|
79
|
+
private renderProdTags;
|
|
80
|
+
/**
|
|
81
|
+
* Lit + parse `${outDir}/.vite/manifest.json` (Vite ≥5) une seule fois par
|
|
82
|
+
* `outDir`. Retombe sur `${outDir}/manifest.json` (layout legacy).
|
|
83
|
+
*
|
|
84
|
+
* Un manifest TROUVÉ est caché (hot path : zéro disque par requête). Un
|
|
85
|
+
* manifest ABSENT n'est JAMAIS caché : figer l'absence condamnait le serveur
|
|
86
|
+
* à la page blanche jusqu'au restart, même après un `frontend:build` réussi
|
|
87
|
+
* (vécu). Le coût — 2 lectures ratées par rendu — n'existe que dans l'état
|
|
88
|
+
* dégradé « pas de build », qui n'est pas un hot path à défendre ; dès que
|
|
89
|
+
* le build apparaît, la lecture réussit et le cache reprend.
|
|
90
|
+
*/
|
|
91
|
+
private loadManifest;
|
|
92
|
+
/**
|
|
93
|
+
* Collecte récursivement les fichiers CSS d'un chunk + de ses imports
|
|
94
|
+
* (le CSS d'un chunk partagé doit être chargé par toutes les entrées).
|
|
95
|
+
* Dédup via un `Set`, anti-cycle via l'ensemble des clés visitées.
|
|
96
|
+
*/
|
|
97
|
+
private collectCss;
|
|
98
|
+
}
|
|
99
|
+
export default TemplateHelper;
|