79 lines
7.2 KiB
Markdown
79 lines
7.2 KiB
Markdown
<!-- file: docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md -->
|
|
<!-- version: 3 -->
|
|
|
|
# Profil écosystème de packages JavaScript
|
|
|
|
## Rôle et applicabilité
|
|
|
|
Ce profil possède le contrat réutilisable d'un package JavaScript/TypeScript utilisant un manifest `package.json` et un package manager compatible avec cet écosystème.
|
|
|
|
Il complète [`500-LANGUAGES.md`](500-LANGUAGES.md) et reste indépendant du choix entre JavaScript et TypeScript, du bundler, du framework frontend, de Sass et du host.
|
|
|
|
## Package manager
|
|
|
|
PGR MUST NOT imposer npm uniquement parce qu'il est utilisé par un corpus source.
|
|
|
|
Le projet MUST sélectionner explicitement le package manager qu'il utilise lorsque plusieurs outils sont possibles. npm, pnpm, yarn, Bun ou une autre solution compatible MAY être retenus si le besoin et la toolchain du projet le justifient.
|
|
|
|
Les commandes opérateur et CI doivent utiliser le package manager réellement sélectionné par le projet ; un exemple PGR ne doit pas transformer sa propre syntaxe en obligation universelle.
|
|
|
|
## Manifest et scripts
|
|
|
|
`package.json` appartient à cet owner lorsqu'il décrit le package frontend ou JavaScript/TypeScript concerné.
|
|
|
|
Pour une application locale/non publiée, `private: true` **SHOULD** être utilisé afin d'exprimer explicitement que le package n'est pas destiné à être publié par erreur. Un package destiné à un registry doit au contraire définir les métadonnées et versions nécessaires à sa publication réelle.
|
|
|
|
Le projet MUST sélectionner explicitement son package manager. Cette sélection peut être rendue machine-readable dans le manifest lorsque la toolchain retenue le permet, ou être possédée par la configuration/CI/documentation locale. PGR ne fixe ni le nom ni la version du package manager dans son template générique.
|
|
|
|
Les scripts du manifest doivent représenter des responsabilités utiles du package. Un script MAY orchestrer plusieurs outils, mais sa présence ne transfère pas l'ownership de TypeScript, Vite, Sass, WASM ou Tauri vers le package manager.
|
|
|
|
Pour un package TypeScript, le nom `typecheck` **SHOULD** désigner la vérification TypeScript indépendante. `dev`, `build` et `preview` restent disponibles pour les owners qui possèdent réellement ces comportements ; leur simple présence dans un exemple ne les rend pas obligatoires.
|
|
|
|
Les champs de version restent classifiés selon la gouvernance PGR et le rôle du package ; un package privé appartenant au même release train et un package publié indépendamment n'ont pas nécessairement la même politique.
|
|
|
|
## Dépendances et sorties téléchargées
|
|
|
|
Les dépendances téléchargées telles que `node_modules/` sont des artefacts reproductibles et SHOULD rester hors du source control.
|
|
|
|
Un package tiers peut exposer des entrypoints JavaScript, CSS, Sass ou d'autres assets. Leur utilisation active les owners correspondants selon le besoin réel du projet ; elle ne fait pas du package manager le propriétaire de leur configuration.
|
|
|
|
## Dépendances de développement et packages de déclarations
|
|
|
|
Le manifest réel doit distinguer les dépendances runtime des outils et déclarations nécessaires uniquement au développement. Pour une application TypeScript privée, le compilateur TypeScript, les outils de build et les packages de déclarations externes nécessaires au type-check **SHOULD** normalement être déclarés dans `devDependencies`.
|
|
|
|
Avant d'ajouter un package `@types/*`, le projet MUST vérifier si la dépendance runtime fournit déjà ses propres types. Si les types sont embarqués, un package `@types/*` redondant SHOULD NOT être ajouté. Si les types sont absents, un package `@types/<nom>` maintenu et compatible **SHOULD** être recherché et ajouté lorsqu'il améliore réellement l'analyse du code consommateur.
|
|
|
|
Des exemples comme `@types/node` et `@types/bootstrap` sont donc conditionnels :
|
|
|
|
- `@types/node` est pertinent lorsque le package analyse du code/config/outillage TypeScript qui utilise l'environnement Node ;
|
|
- `@types/bootstrap` est pertinent lorsque le code TypeScript consomme les API JavaScript Bootstrap et que les déclarations ne sont pas fournies par le package runtime ;
|
|
- aucun des deux ne doit être injecté dans tous les frontends par défaut.
|
|
|
|
Le template PGR générique conserve volontairement un `package.json` sans `devDependencies` préremplies : il ne connaît ni les dépendances runtime du projet, ni la version TypeScript, ni l'environnement Node éventuel. L'instanciation réelle du template doit ajouter TypeScript et les packages de déclarations effectivement requis avec des versions explicitement décidées.
|
|
|
|
Pour une bibliothèque publiée, une dépendance de déclarations exposée par les `.d.ts` publics peut être nécessaire chez le consommateur. Dans ce cas, la classer uniquement en `devDependencies` est insuffisant ; le manifest publié doit rendre cette dépendance disponible selon son contrat réel.
|
|
|
|
## Lockfile
|
|
|
|
La politique du lockfile MUST être explicitement décidée selon le rôle du package, la reproductibilité recherchée, les contraintes de publication et le package manager sélectionné.
|
|
|
|
Pour une application privée, un frontend déployable ou un outil livré comme unité exécutable, le lockfile produit par le package manager sélectionné **SHOULD** être versionné afin de conserver l'arbre effectivement résolu entre développeurs, CI et livraisons.
|
|
|
|
Pour une bibliothèque publiée, un lockfile **MAY** être versionné afin de stabiliser l'environnement de développement et de CI. Il ne remplace toutefois pas les contraintes du manifest qui pilotent la résolution chez les consommateurs.
|
|
|
|
Un exemple, un template ou une fixture qui ne résout aucune dépendance réelle **MAY** ne pas embarquer de lockfile.
|
|
|
|
Un package **SHOULD NOT** conserver simultanément plusieurs lockfiles concurrents (`package-lock.json`, `pnpm-lock.yaml`, `yarn.lock` ou équivalent), sauf migration explicitement temporaire entre package managers.
|
|
|
|
Lorsqu'un lockfile est versionné, la CI **SHOULD** utiliser le mode de résolution gelé, immutable ou clean-install fourni par le package manager sélectionné. Le nom exact de cette commande reste local à l'outil ; PGR MUST NOT transformer `npm ci` en commande universelle.
|
|
|
|
L'absence actuelle de lockfiles dans Games reste historique. Lors de l'adoption `0.1.5`, chaque package concerné devra soit `ADOPT` cette recommandation, soit documenter un `OVERRIDE` si une autre politique reste préférable.
|
|
|
|
## Validation
|
|
|
|
Le parsing du manifest, l'installation/résolution de dépendances, le respect du lockfile et les scripts du package manager sont des preuves distinctes. Leur sélection reste proportionnée au scope conformément à [`400-VALIDATION.md`](400-VALIDATION.md).
|
|
|
|
Une validation statique PGR peut vérifier qu'un `package.json` template est du JSON valide et que les champs génériques attendus sont présents. Elle ne remplace pas l'installation/résolution réalisée par le package manager sélectionné.
|
|
|
|
Le modèle minimal [`../../templates/web-typescript/package.json`](../../templates/web-typescript/package.json) représente une application TypeScript privée sans choisir de package manager ni de versions de dépendances. Son adaptation est documentée par [`../templates/008-WEB_TYPESCRIPT_PACKAGE.md`](../templates/008-WEB_TYPESCRIPT_PACKAGE.md).
|