Skip to content

Outillage ​

Technologies utilisées ​

OutilRôle dans SIA UI
TypeScriptSécurise les API publiques et les composants installés
ReactMoteur de rendu ciblé par @sia-ui/react et le registre
pnpm workspacesLie les packages locaux et partage les dépendances
TurborepoOrchestre build, tests et typecheck entre packages
tsupProduit les bundles ESM, CommonJS et déclarations TypeScript
VitestExécute les tests unitaires rapides
CSS variablesTransporte les tokens et permet les thèmes dynamiques
MermaidDocumente les flux et dépendances dans les fichiers Markdown

Pipeline local ​

Commandes ​

CommandeUtilité
pnpm installSynchroniser le workspace et le lockfile
pnpm typecheckVérifier tous les contrats TypeScript, templates du registre compris
pnpm testExécuter les tests de chaque package
pnpm buildGénérer les packages distribuables
pnpm previewLancer le catalogue visuel Vite
pnpm storybookLancer Storybook pour les composants isolés
pnpm cleanSupprimer les artefacts de build
pnpm check:depsVérifier qu'aucun paquet publié n'a de dépendance tierce
pnpm changesetDécrire un changement à publier
pnpm releaseConstruire et publier sur npm
pnpm sia -- listInspecter le registre local

Portée du typage ​

pnpm typecheck couvre les sources des packages et les templates du registre. Les fichiers copiés chez l'utilisateur sont le produit réellement distribué: ils doivent être vérifiés comme le reste.

json
// packages/registry/tsconfig.json
{
  "include": ["src/**/*.ts", "templates/**/*.ts", "templates/**/*.tsx"]
}

Une entrée ajoutée au registre sans passer tsc ne doit pas être publiée.

Formats produits ​

ESM couvre les bundlers modernes, CommonJS conserve une compatibilité Node et les fichiers .d.ts fournissent l'autocomplétion et la validation aux projets.

Un seul jeu d'options de build ​

tsup.preset.ts, à la racine, porte les options communes aux sept paquets construits par tsup. Chaque tsup.config.ts ne déclare plus que ce qui lui est propre — son entry, ses external :

ts
import { preset } from "../../tsup.preset";

export default preset({ entry: ["src/index.ts"], external: ["react"] });

Une décision de build se prend donc une fois. Pas de sourcemaps en est l'exemple : les cartes pesaient environ soixante pour cent de chaque archive npm — @sia-ui/react-web passait de 2,1 Mo à 759 Ko en les retirant — pour du code que personne ne débogue depuis dist. Un projet qui veut remonter à la source lit les .d.ts ou installe le composant par le registre, où il reçoit le fichier TypeScript lui-même.

La licence voyage avec le paquet ​

npm n'emporte que ce qui vit dans le dossier du paquet : une LICENSE à la racine du dépôt n'arrive jamais dans l'archive. Chaque paquet publié en porte donc une copie, listée dans son champ files — mais aucune n'est écrite à la main. pnpm sync:license les régénère depuis le fichier racine, seule source, et pnpm check:license échoue sur la moindre dérive. La CI le lance juste après le garde-fou des dépendances.

Le journal est visible sur npm ​

Chaque paquet garde son CHANGELOG.md, généré par Changesets, et le publie dans son archive npm. Le même contenu est aussi recopié dans le README.md du paquet sous Journal des changements, parce que npm affiche d'abord le README. pnpm changeset:version lance pnpm sync:changelogs après avoir généré les versions. pnpm release contrôle ensuite la copie et refuse la publication si un README a dérivé de son changelog.

Tests de montage ​

@sia-ui/react-web monte chacun de ses composants exportés et vérifie qu'il tient debout. C'est délibérément grossier : rien n'est asserté sur ce qui s'affiche.

bash
pnpm --filter @sia-ui/react-web test

Ce garde-fou existe parce que typecheck dit qu'un composant compile et Storybook qu'il se bundle — ni l'un ni l'autre ne le rend. Après une migration qui a déplacé 88 fichiers, réécrit leurs imports et découpé leur feuille de style, c'est exactement ce qui manquait.

Deux fichiers portent la mécanique :

  • src/smoke.test.tsx parcourt les exports du barrel et monte tout ce qui commence par une majuscule;
  • src/smoke-props.ts déclare les props minimales de ceux qui en exigent. Une entrée ajoutée là est une information : ce composant a une prop obligatoire, et laquelle.

Les sous-composants d'un ensemble composé — Radio, TabsTrigger — lèvent volontairement hors de leur parent. Ils sont listés comme non montables seuls : c'est un bon comportement, pas un défaut.

src/config.test.tsx couvre ensuite ce que la refonte du fournisseur a changé : une valeur par défaut qui traverse l'arbre, une prop explicite qui gagne sur elle, un libellé traduit, le repli sur le français et la composition de deux fournisseurs imbriqués.

Ajouter un composant ​

Rien à faire : le test le ramasse depuis le barrel. S'il a une prop obligatoire, l'ajouter à MINIMAL_PROPS — le test le dira.

Lint ​

ESLint couvre tout le workspace depuis une configuration unique, eslint.config.mjs. Les règles qui demandent le type checker en sont volontairement absentes : elles doubleraient le temps d'exécution pour signaler ce que tsc voit déjà, et typecheck tourne de toute façon.

Deux assouplissements assumés :

  • no-console est levé pour l'outillage et la CLI — écrire sur la sortie standard est leur rôle, pas une trace de débogage oubliée;
  • react-hooks/rules-of-hooks est levé dans les stories : la fonction render d'une story est un composant, mais la règle ne juge que le nom.

react-hooks/exhaustive-deps ne produit plus aucun avertissement dans react, react-web et headless, et doit le rester : les composants sont copiés dans des projets qui lancent leur propre lint, et chaque avertissement devient le leur. Une valeur lue par un écouteur ou un intervalle sans devoir le relancer passe par une ref mise à jour au rendu (latest.current = …), l'idiome de useLocalForm et SearchInput — useEffectEvent demanderait React 19.2, les paquets acceptent 18.2.

Les règles du React Compiler (react-hooks/refs, purity, set-state-in-effect) ne sont pas activées ici ; elles le sont chez qui utilise la configuration recommended du plugin en version 7 — voir Ce que le projet hôte doit fournir.

Publication ​

Les huit paquets publiés portent toujours le même numéro : ils sont déclarés fixed dans .changeset/config.json. Un changeset sur un seul d'entre eux fait sortir les huit, à la même version. Un utilisateur installe @sia-ui/react-web et @sia-ui/headless côte à côte, et deux numéros différents ne lui apprendraient rien.

Le mode linked, utilisé jusqu'à la 0.7.1, alignait seulement les paquets modifiés : un paquet inchangé restait en arrière, et un changement sur un paquet en retard le faisait sauter au-delà des autres. fixed supprime les deux cas.

bash
pnpm changeset           # décrire le changement
pnpm changeset:version   # versions + CHANGELOG
pnpm release             # build puis publish

Tout est en 0.x tant que les arbitrages restants ne sont pas rendus. Voir Source unique des composants.

Garde-fou des dépendances ​

pnpm check:deps échoue si un paquet publié déclare une dépendance de production autre que @sia-ui/*. C'est la règle du §04 rendue mécanique : SIA UI se branche sur les librairies d'une application, il n'en embarque aucune.

La CI l'exécute avant le lint : c'est la vérification la plus rapide et la plus structurante.

Publié sous licence MIT.