Chaque développeur a ce dossier. Celui appelé utils ou helpers que vous copiez d'un dépôt à l'autre. Vous le collez, passez vingt minutes à supprimer les références aux anciens schémas de base de données, à arracher les vérifications d'authentification qui ne s'appliquent pas, et à renommer les variables pour que votre nouveau linter arrête de hurler. J'avais l'habitude de faire cela avec un système de thémisation que j'avais construit, le Dynamic Theme Kit. Au départ, c'était une fonctionnalité au sein d'une application, et pendant des mois, je l'ai traité comme un outil portable. Je me trompais. Copier du code n'est pas de la réutilisation. C'est de la duplication avec des étapes supplémentaires.
Le piège de la mentalité centrée sur un projet unique
Lorsque vous développez une fonctionnalité au sein d'un projet, vous faites des centaines d'hypothèses invisibles. La palette de couleurs peut supposer une configuration CSS-in-JS spécifique. L'échelle d'espacement peut faire référence à un token de design issu de la charte graphique de votre entreprise. Le basculement entre le mode clair et le mode sombre peut appeler un endpoint de préférences utilisateur propre au backend de cette application. Ces dépendances semblent inoffensives car, à l'intérieur du projet, elles le sont. Elles y ont leur place.
Le problème commence lorsque vous essayez d'extraire ce code. Vous découvrez que le composant « réutilisable » est en réalité un réseau de liens cachés le connectant à cette base de code précise. Je l'ai appris avec DTK. Il générait des variables de thème, certes. Mais il exigeait aussi une structure de dossiers spécifique. Il importait une définition de type provenant de quelque part dans le répertoire types de l'application d'origine. Il supposait la présence d'un objet de configuration global qui n'existait que dans ce dépôt. Je ne l'avais jamais remarqué car, au sein de ce projet, tout était toujours présent.
Transformer DTK en un package autonome a nécessité une opération chirurgicale, pas une expansion. Je n'avais pas besoin de plus de fonctionnalités. J'avais besoin de moins de connexions.
Extraction du Dynamic Theme Kit
Le travail le plus difficile a consisté à s'asseoir devant la base de code et à se demander, pour chaque fonction et chaque export : cela sert-il la logique de thémisation, ou cela sert-il le projet ? J'ai supprimé les préréglages de style. J'ai supprimé l'hypothèse que le consommateur serait une application React. J'ai entièrement supprimé les palettes de couleurs par défaut. Le projet original avait une esthétique d'entreprise bleu marine et ardoise intégrée par défaut. Cela devait disparaître. Un package ne peut pas livrer vos couleurs de marque.
Le nouveau kit ne ferait qu'une seule chose. Il prend un objet de configuration — quelques valeurs de couleur, quelques nombres pour l'espacement, quelques échelles de typographie — et il génère des propriétés CSS personnalisées. C'est tout. Il ne les applique pas. Il ne décide pas de leur emplacement dans votre DOM. Il se moque de savoir si vous utilisez Tailwind, Styled Components ou du HTML pur. Il fournit les variables à votre application, et votre projet choisit comment les utiliser.
Cette contrainte semblait limitante au début. Elle s'est avérée libératrice.
Ce qui casse lorsque vous essayez réellement de le réutiliser
Avant de publier quoi que ce soit, j'avais besoin de la preuve que l'abstraction tenait la route. J'ai sorti trois petits projets personnels de mes archives : un outil de prévisualisation markdown, un suivi d'habitudes et une landing page pour un événement. Aucun d'entre eux ne partageait le même framework ou la même structure de dossiers. J'ai installé DTK localement dans chacun d'eux et j'ai essayé de les thématiser.
La première tentative a échoué immédiatement. Les noms de variables générés par DTK étaient trop spécifiques. Il produisait des tokens tels que --primary-action et --background-overlay qui impliquaient une certaine mise en page d'interface utilisateur. Dans le prévisualiseur markdown, ces noms n'avaient aucun sens. Il n'y avait pas de bouton d'action. Il n'y avait pas d'overlay. J'ai renommé la logique de génération pour produire des noms structurels neutres qui décrivaient la valeur plutôt que le widget.
J'ai également constaté que mes valeurs par défaut étaient trop agressives. Lorsqu'un utilisateur passait une configuration incomplète, DTK comblait les lacunes avec des valeurs qui semblaient correctes dans un tableau de bord dense, mais qui brisaient une landing page épurée. Je suis passé à des valeurs par défaut transparentes où les tokens manquants ne s'affichaient tout simplement pas, laissant le projet consommateur définir ses propres solutions de repli.
Ensuite, il y avait la documentation. Ce qui me semblait évident — « passez simplement un objet de configuration » — était vague pour quelqu'un lisant le README à minuit. Je l'ai réécrit avec de vrais objets, de vrais chemins de fichiers et des explications claires sur ce qui se passe lors de l'appel de la fonction par rapport à ce que votre application doit faire ensuite.
Ces petits projets personnels ont servi de bancs d'essai. Les enjeux étaient faibles, mais ils ont exposé de réelles failles que je n'aurais pas détectées en examinant le code source de manière isolée.
Le vrai test : la mise en production chez Web Weavers World
Les projets personnels sont des bacs à sable. Ils n'ont ni échéances, ni parties prenantes, ni CSS hérité antérieur à votre package. Le véritable test a eu lieu lorsque j'ai intégré DTK à Web Weavers World, mon site professionnel. Il s'agissait d'un site en production avec des styles existants, des attentes clients et des données analytiques à prendre en compte. Si le package cassait quelque chose, je ne pouvais pas simplement supprimer le dépôt et recommencer à zéro.
J'ai ajouté DTK au pipeline de build, je l'ai orienté vers une nouvelle configuration de couleurs et je l'ai laissé générer un nouvel ensemble de variables CSS. L'intégration a pris un après-midi, pas une semaine. C'était le signal. Auparavant, ajouter un nouveau thème signifiait écrire du nouveau CSS, traquer des valeurs hexadécimales codées en dur dans vingt fichiers et espérer ne pas avoir oublié un cas particulier. Désormais, j'ajoute une palette au fichier de configuration, DTK génère les variables, et le reste du site les consomme. La logique de thème est passée d'un processus manuel fragile à quelque chose en quoi j'ai assez confiance pour le confier à des collaborateurs.
Trois questions qui ont changé ma façon de construire
Ce processus m'a obligé à formaliser une liste de contrôle mentale que j'utilise désormais avant d'abstraire quoi que ce soit :
- Cette variable est-elle vraiment générique ? Si le nom ou la logique fait référence à un concept métier du projet d'origine, il doit rester en arrière.
- Cela appartient-il au package ou à l'application ? Les règles métier, l'identité de marque et les hypothèses de mise en page résident dans l'application. La tuyauterie qui génère une sortie standardisée réside dans le package.
- Est-ce que je résous un problème réutilisable ou un problème spécifique à un projet ? C'est la question la plus difficile à trancher honnêtement. Nous aimons penser que nos solutions sont universelles. En général, elles sont locales.
Répondre à ces questions m'a forcé à simplifier ma conception, souvent en supprimant du code plutôt qu'en en ajoutant. DTK m'a appris que la réutilisation n'est pas un cadeau que l'on se fait à soi-même. C'est une discipline que l'on pratique en disant non à la facilité.
Une autre façon de penser le refactoring
J'avais l'habitude de mesurer le refactoring à la réduction de la taille du code. Moins de lignes semblait être un progrès. Maintenant, je le mesure au nombre de portes qu'il ouvre. Le Dynamic Theme Kit n'est pas élégant parce qu'il est concis. Il est utile parce qu'il a survécu à trois projets personnels sans lien entre eux et à un site professionnel en production sans avoir besoin de modifier son fonctionnement interne.
C'est la métrique qui compte. Un code qui fonctionne une fois est une dépense. Un code qui fonctionne de manière répétée est un actif. Avant de commencer toute nouvelle fonctionnalité, je m'arrête. Je me demande si je construis quelque chose dont j'aurai encore besoin. Si la réponse est oui, je le construis différemment dès la première ligne. J'isole les entrées. Je définis les sorties. Je supprime les hypothèses.
Le meilleur refactoring ne rend pas votre code plus court. Il permet à votre code de fonctionner dans des endroits que vous n'avez pas encore imaginés.
