3 points par GN⁺ 2024-07-26 | 1 commentaires | Partager sur WhatsApp
  • La PR Node.js #53725 a été fusionnée, ajoutant un support expérimental pour exécuter des fichiers TypeScript via le flag --experimental-strip-types
  • Cette fonctionnalité supprime la syntaxe de type du code source TypeScript pour le convertir en JavaScript, sans effectuer de vérification de types pendant la conversion
  • L’implémentation initiale ne convertit pas les fonctionnalités propres à TypeScript comme Enum ou namespaces, et se limite donc au code qui devient du JavaScript uniquement par suppression des types
  • @swc/wasm-typescript a été retenu pour l’implémentation, principalement pour sa simplicité, car il n’est pas nécessaire d’ajouter Rust ou Go à la toolchain Node.js
  • Dans les discussions, les principales contraintes évoquées portent sur la règle des extensions de fichier obligatoires en ESM, la pratique courante en TypeScript où un import en .js pointe en réalité vers un fichier .ts, ainsi que le coût des source maps et du positionnement des erreurs dans les traces de pile

Fonctionnement de --experimental-strip-types

  • Avec --experimental-strip-types, Node.js peut exécuter des fichiers TypeScript
  • Node.js transpile le code source TypeScript en code source JavaScript
  • Pendant la transpilation, aucune vérification de types n’est effectuée et les informations de type sont supprimées
  • Exemple :
const foo: string = "foo";
const foo = "foo";

Pourquoi se limiter à la suppression des types, et les restrictions initiales

  • Le cœur de cette PR est la suppression de la syntaxe de type dans TypeScript
  • D’autres runtimes convertissent aussi en JavaScript des fonctionnalités propres à TypeScript qui n’existent pas en JavaScript, comme enum
  • L’implémentation initiale de cette PR ne réalise pas ces conversions
    • Enum non pris en charge
    • namespaces non pris en charge
    • les autres fonctionnalités propres à TypeScript ne sont pas non plus converties
  • Les détails d’implémentation et les limitations sont décrits dans typescript.md parmi les changements de la PR

Choix de @swc/wasm-typescript comme outil d’implémentation

  • @swc/wasm-typescript est un petit package, composé d’un fichier wasm et d’un fichier JavaScript qui l’expose
  • D’autres outils imposaient d’ajouter Rust ou Go à la toolchain Node.js
  • SWC est déjà utilisé par Deno pour le même objectif, et l’auteur de la PR y voit une option éprouvée
  • À terme, cette fonctionnalité pourrait être implémentée dans une couche native
  • Cette PR fait référence à nodejs/loaders#217

Résolution des imports et discussion sur les extensions

  • Les imports sans extension comme import foo from "./foo" ne sont pas pris en charge
  • En ESM dans Node.js, la règle des mandatory file extensions s’applique, donc l’absence de support pour les imports sans extension est considérée comme intentionnelle
  • Il a été souligné que, dans de nombreuses bases de code TypeScript modulaires, il est courant d’écrire l’extension .js dans les imports même si le fichier réel est en .ts
    • Exemple : import foo from './foo.js'
    • alors que le système de fichiers ne contient pas ./foo.js, mais uniquement ./foo.ts
  • L’auteur de la PR estime que ce sujet pourra être traité dans un travail itératif ultérieur, car deviner l’extension demanderait des vérifications supplémentaires du système de fichiers et des heuristiques
    • si ./foo.js n’existe pas, vérifier ./foo.ts
    • si ./foo.ts n’existe pas, vérifier ./foo.js
  • Cette discussion est suivie dans nodejs/loaders#208

Positionnement du code source, source maps et traces de pile d’erreurs

  • Lors de la revue, certains ont estimé qu’un positionnement précis dans le code source pour les traces de pile d’erreurs était nécessaire à court terme
  • Une approche possible consiste à ne pas modifier les positions dans le code lors de la suppression des types, afin d’éviter la génération et le mapping de source maps
  • Il a été noté que les source maps ont un coût en mémoire et en performance, et qu’elles ne sont pas simples à gérer
  • L’auteur de la PR indique que SWC prend déjà en charge les source maps, et qu’un flag pourrait être ajouté pour les activer
  • Il estime aussi qu’il serait possible de demander à SWC une option remplaçant la syntaxe supprimée par des espaces afin de ne pas modifier les traces de pile d’origine

Questions de conception restantes avant la stabilisation

  • Le support de TypeScript se divise en deux axes
    • suppression de la syntaxe de type
    • ajustement des règles de résolution pour accepter les fichiers .ts
  • Des inquiétudes ont été exprimées quant au fait qu’un changement des règles de résolution puisse entrer en conflit avec les loaders TypeScript existants
  • L’auteur de la PR répond que cette PR ne contient aucun override des règles de résolution et que l’extension du fichier reste requise
  • Via allowImportingTsExtensions, il serait possible de prendre en charge la forme import './file.ts', une approche jugée cohérente avec Deno
  • Pour exécuter directement un même fichier source tout en produisant aussi une sortie JavaScript avec un outil de build, la responsabilité de transformer file.ts en file.js pourrait incomber à l’outil de build

Fusion et travaux de suivi

  • La PR a été fusionnée dans nodejs:main le 24 juillet 2024
  • L’ampleur du changement est de 8 commits, 89 fichiers, 2 190 lignes ajoutées et 25 lignes supprimées
  • Elle porte les labels semver-minor, experimental, module, esm, notable-change
  • Il y a aussi eu une discussion sur l’opportunité de mentionner cette fonctionnalité sur la page d’information TypeScript du site web, avec une PR de mise à jour associée
  • Une autre piste de suivi concerne l’ajout, dans les métadonnées de distribution, de la version de TypeScript utilisée par le binaire Node pour la suppression des types

1 commentaires

 
GN⁺ 2024-07-26
Avis sur Hacker News
  • La suppression des types TypeScript est impossible sans la syntaxe TypeScript. La suppression des types n’est pas une opération au niveau des tokens, et la syntaxe TypeScript continue d’évoluer.
    Par exemple, foo < bar & baz > ( x ) était analysé comme (foo (x)) dans TypeScript 1.5, car bar&baz n’était pas une expression de type valide, mais après l’ajout de l’opérateur de types d’intersection, c’est analysé comme foo<(bar & baz)>(x), et désambiguïsé en foo(x).
    Pour continuer à utiliser les fonctionnalités TypeScript récentes, il faut compiler en JS ou maintenir sa version de Node constamment à jour ; pour les équipes qui préfèrent rester sur Node LTS, cela peut être un compromis difficile à accepter.

    • L’équipe Node semble avoir déjà pris ce problème en compte. Comme Node intègre npm mais permet de le mettre à niveau séparément, il existe un précédent, et certains discutent de faire de même avec le transformateur TypeScript.
      L’idée serait de garder une version stable dans le cœur, mais de permettre une mise à niveau séparée depuis NPM lorsque TypeScript ajoute de nouvelles fonctionnalités, introduit des changements cassants, ou lorsque l’utilisateur veut utiliser de nouvelles fonctionnalités expérimentales.
      Cela permettrait de prendre en charge une version donnée de TypeScript pendant les trois ans de durée de vie d’une version de Node.js, sans bloquer les utilisateurs : https://github.com/nodejs/loaders/issues/217
    • Du point de vue de la syntaxe pour la suppression des types, il y a eu bien plus de versions de TypeScript où elle était stable que de périodes où elle était instable. Si l’on remonte jusqu’à la 1.5, c’est justement parce qu’elle est restée assez stable depuis la 2.x.
      Le dernier gros changement syntaxique était probablement les types conditionnels de la 2.8, quand une syntaxe ressemblant à un opérateur ternaire if a été introduite dans les positions de type. Si l’on veut aussi faire de la vérification de types, le modèle de types a beaucoup changé depuis la 2.x, mais la syntaxe est restée globalement stable, et l’innovation de TypeScript s’est surtout faite du côté du modèle de types et de l’inférence de types.
      C’est encore à un stade précoce, Stage 1, mais il existe aussi une tentative de standardiser une bonne partie de la syntaxe de types TypeScript, non pas pour la vérification de types, mais pour la suppression des types : https://github.com/tc39/proposal-type-annotations
    • Il faudra aussi mettre à jour le compilateur. Au final, on peut formuler cela comme « impossible de faire évoluer la version de TypeScript indépendamment de la version de Node.js », mais ce ne sera probablement pas un gros problème.
    • Utiliser les signes inférieur/supérieur comme des chevrons était vraiment une erreur, à mon avis.
    • Les équipes qui suivent toujours le dernier TypeScript et utilisent les nouvelles fonctionnalités du langage semblent aussi susceptibles de suivre les dernières versions de Node. D’après mon expérience, les mises à niveau de TypeScript ont nécessité plus souvent des migrations ou corrections à cause de nouvelles erreurs que les mises à niveau de Node.
      Les équipes qui ne s’intéressent pas vraiment aux dernières fonctionnalités de V8 ou de Node et restent sur LTS ont de fortes chances d’être également moins intéressées par les toutes dernières fonctionnalités TypeScript.
  • Si Node.js peut exécuter directement des fichiers TypeScript, le compilateur TypeScript pourrait servir uniquement de vérificateur de types, plutôt que de faire la suppression des types et la transformation en JavaScript. C’est similaire à Python, où le vérificateur de types vérifie les types et les laisse en place, tandis que l’interpréteur ignore les annotations de type.
    Fait intéressant, en Python, plusieurs vérificateurs de types populaires sont apparus avec la même syntaxe d’annotations de type, mais des sémantiques différentes. En JavaScript, en revanche, TypeScript semble être devenu de fait le seul vérificateur de types populaire.
    J’ai aussi entendu dire qu’en Python, certains ajoutent des types dans le source sans les vérifier, simplement comme une syntaxe de commentaires plus pratique. Si Node.js prend en charge l’ignorance des types, ce genre d’usage deviendra possible aussi en JavaScript.

    • Flow de Facebook était assez important côté JavaScript il y a quelques années, mais TypeScript semble désormais avoir gagné assez nettement.
    • Même sans vérification de types, les IDE peuvent utiliser les annotations de type pour améliorer l’autocomplétion, etc. Ajouter des types à certains endroits garde donc un intérêt.
    • Aujourd’hui déjà, on peut ajouter des types avec JSDoc et les vérifier avec TypeScript, sans compilation. Les builds sont plus rapides, et l’on obtient du code qui fonctionne partout sans traitement magique ni étape de suppression autre que les commentaires.
      Personnellement, le plus gros inconvénient de JSDoc était la syntaxe d’import, mais cela a changé depuis TypeScript 5.5 et ce n’est désormais plus un problème.
    • Node.js n’est pas le seul runtime JavaScript. Tant que tous les navigateurs ne pourront pas exécuter TypeScript directement, il faudra compiler TS en JS pour le navigateur.
      Cela dit, certains bundlers utilisent déjà des compilateurs non officiels comme SWC pour le faire, et Node expérimente aussi SWC pour cette fonctionnalité.
      Les annotations de type ne sont pas de simples commentaires : ce sont aussi des indices, comme les noms, qui permettent aux IDE d’offrir une meilleure autocomplétion.
    • Il existe une proposition EcmaScript dans ce sens : https://github.com/tc39/proposal-type-annotations
      À mon avis, cela devrait faire partie de la spécification du langage.
  • Je me demande comment l’écosystème NPM réagira si cette fonctionnalité devient le comportement par défaut, et non plus quelque chose caché derrière un flag. Je ne sais pas si les contributeurs continueront à produire des versions CJS et ESM lorsqu’ils publieront des modules NPM, ou s’ils se contenteront d’ajouter engine: nodejs >= 25 dans package.json en supprimant l’étape de build.
    Personnellement, si les modules NPM qui ont des sources TS arrêtent de publier des dist/.cjs, je trouverais ça mieux : il deviendrait plus clair où mettre le débogueur et les console.log. Du point de vue des contributeurs NPM, la tentation de supprimer l’étape de build sera aussi forte.
    Mais si une seule dépendance publie des fichiers TS, l’idée que « tout le monde reçoit des fichiers TS » pourrait se répandre rapidement. Dès que Node.js sortira cela du flag expérimental opt-in, toute la communauté risque d’attendre implicitement des consommateurs qu’ils acceptent les fichiers TS.
    Dans ce cas, d’ici quelques mois, Firefox et Safari subiront aussi une pression pour les accepter, et tous les compilateurs JS seront forcés d’ignorer les annotations de types TS.
    Personnellement, ça ne me dérange pas non plus. Côté utilisateurs de TS, on ajoute déjà aux modules NPM une étape de transformation qui convertit le code TS en JS et en .d.ts pour prendre en charge d’hypothétiques utilisateurs JS. Mais si Node accepte les fichiers .ts, on pourra supprimer cette étape de transformation sans s’en rendre compte ; je me demande donc quel mécanisme empêchera les éditeurs NPM d’arrêter de publier des fichiers js/d.ts sans s’apercevoir que c’est cassé.

    • Ryan Dahl est en train de créer un nouveau registre de paquets appelé JSR pour résoudre ce problème.
      Il permet de publier du code TypeScript sans étape de build, et fait en sorte que, lorsqu’un autre développeur l’installe, il voie le source TypeScript d’origine plutôt que du JavaScript transformé.
    • L’exécution de fichiers .ts dans node_modules n’est pas prise en charge. C’est l’une des principales restrictions destinées à éviter de casser l’écosystème.
    • Les anciennes bibliothèques TypeScript maintenues sont transformées en .cjs et .mjs pour npm ; elles finiront probablement par publier les trois versions.
      Pour un projet écrit from scratch aujourd’hui, il est possible de ne publier que du TypeScript et de ne pas effectuer de transformation.
      Modification : d’après un commentaire frère de satanacchio, qui semble être l’auteur de la PR et membre du comité de pilotage technique de Node.js, la prise en charge de TS concerne les éléments de premier niveau et ne s’applique pas aux bibliothèques dans node_modules.
    • J’aimerais publier mon code source .ts sur npm, mais l’équipe TypeScript y était très opposée à cause des problèmes liés à tsconfig et aux performances. J’ai quand même bon espoir.
  • Peut-être qu’un jour Node permettra la réflexion à l’exécution de ces types depuis JS.
    Ce serait un gain énorme. En Python, comme les types peuvent être introspectés, d’excellents outils comme pydantic peuvent générer des validations à partir des types.
    Avec une seule notation standard, on peut obtenir la vérification de types, la validation des données à l’exécution, la génération d’API et la génération de documentation d’API.
    Aujourd’hui en JS, des outils comme Zod doivent en pratique réinventer ce que TypeScript fait déjà, avec des choses comme const mySchema = z.string();.

    • Le z.string() de Zod ne fournit pas seulement une sécurité de types à la TypeScript. TypeScript fournit une vérification de types à la compilation, tandis que Zod ajoute la validation et le parsing à l’exécution.
      z.string() transforme mySchema en schéma fonctionnel capable de parser et de valider. mySchema.parse("some data") réussit, tandis que mySchema.parse(321) lève une exception.
      Je l’ai utilisé là où il fallait de la validation à l’exécution et des vérifications dans le processus ; ça fonctionnait assez bien, et on peut aussi en extraire le type, comme dans const A = z.string(); type A = z.infer; // string.
      Autrement dit, si l’on définit d’abord le type dans Zod puis qu’on en infère le type, on obtient à la fois une vérification de types à la compilation et à l’exécution. Cela peut être excessif pour une petite base de code qui évolue vite, mais c’est très utile dans les situations où il faut valider dans le processus, et la charge de travail n’est pas énorme.
    • Ces derniers temps, l’équipe TypeScript se concentre beaucoup sur l’alignement avec le langage JavaScript, et les nouvelles fonctionnalités comme les types à l’exécution ont quasiment été écartées, ou au moins repoussées derrière la proposition TC39 sur les types JavaScript. Le problème de l’utilisation des décorateurs sur des variables hors des structures de classe était similaire.
      Cela dit, TypeScript autorise les plugins. Ils ne sont pas très utilisés, mais ils permettent d’ajouter au langage d’autres fonctionnalités qui sont transformées en JavaScript de sortie.
      Pour les types à l’exécution, il existe un plugin appelé Typia, qui permet d’utiliser les signatures de types TypeScript à l’exécution dans des gardes comme assert(myValue). Il intercepte cet appel de fonction et génère, dans le JavaScript transformé, des if exhaustifs qui vérifient la nature de la variable transmise.
      Je ne pense pas que cela fera partie du langage dans les 4 à 6 prochaines années, mais il existe déjà des bibliothèques qui permettent de faire ce genre de choses aujourd’hui.
    • Si JS ajoute un jour une vérification de types, j’espère qu’il ne choisira pas TypeScript.
      Il faut en réalité un système de types sound, mais TS est intentionnellement non sound. Il faut un système de types qui n’autorise pas les mauvaises pratiques de codage comme TS, et qui impose une conception permettant d’obtenir des programmes rapides. Il faut un système de types Hindley-Milner.
      Si l’on veut transformer un module en code typé, il suffirait d’ajouter "use type". Ce mode devrait interdire les mauvaises parties comme les coercitions de types, et bloquer les éléments qui nuisent aux performances, comme changer la forme des objets ou le type des valeurs, ou créer des tableaux mélangeant n’importe quelles valeurs.
      Les données provenant de modules non typés seraient converties, ou déclencheraient une erreur si elles ne peuvent pas l’être ; le compilateur pourrait alors optimiser en profondeur le code typé avec des garanties de types plus fortes et sans risque de bail-out.
    • Je me demande si cela signifie que Node pourrait savoir si une exception est une sous-classe de ValueError, ou si un objet est une instance de SomeClass. Je débute avec TS, donc je pensais qu’en dehors des tableaux, objets, nombres et chaînes, il n’y avait pas de types en JS, et que Zod ou les fonctions de garde de types renvoyaient simplement des objets ordinaires qu’il faut croire sur parole.
  • L’expérience développeur de Bun est assez inédite dans ce domaine, et désormais la plupart des cas d’usage sont couverts, ou bien Bun ne plante pas lorsqu’on écrit des scripts d’exécution avec bun run
    À l’inverse, avec Node, on ne peut ni le configurer pour ne pas exiger les extensions dans les imports, ni faire en sorte que tsc ajoute automatiquement l’extension .js au résultat compilé, ce qui oblige à ajouter un bundler
    La prise en charge native de TypeScript corrigera sans doute assez bien ce petit désagrément, mais même une fois stabilisée, il est difficile d’imaginer que l’expérience utilisateur ou les performances rivalisent avec Bun

    • Les extensions doivent être exigées. On ne peut pas rechercher des chemins sur le réseau comme sur un disque local, et les runtimes connectés au réseau comme les navigateurs sont très importants en JavaScript
    • J’aime beaucoup Bun, mais Deno reste plus mature, plus stable et plus riche en fonctionnalités. Il a aussi des workers stables, HTTP/2, etc., et selon les cas d’usage V8 peut être plus rapide que JSC
      L’expérience développeur et les outils sont également de tout premier ordre. Deno peut aussi faire de la vérification de types et, si je me souviens bien, embarque TSC
      Bun fait beaucoup parler de lui, mais pour du travail sérieux, Deno est aujourd’hui clairement une meilleure option. Cela dit, la vision et l’exécution de Bun sont impressionnantes, et c’est une bonne chose pour les développeurs
    • J’ai essayé Bun deux fois à quelques mois d’intervalle, mais sous Windows bun install échouait, donc je n’ai jamais réussi à le faire fonctionner correctement : https://github.com/search?q=repo%3Aoven-sh%2Fbun+bun+install...
    • « Inédit », oui, si on exclut Deno
    • J’ai l’impression que Bun est encore trop brut. Il est écrit en Zig, qui n’a même pas encore atteint la 1.0
  • Cela fait longtemps que j’attends un runtime TypeScript, et j’aime vraiment TypeScript, mais c’est amusant d’avoir quitté Java il y a longtemps pour finalement chercher quelque chose de beaucoup plus proche de Java
    Au fond, ce qu’on voulait, c’était sans doute Java avec un JIT, un système de types plus riche et du typage progressif. L’écosystème npm a aussi beaucoup de défauts, mais utiliser des bibliothèques dans cet écosystème est bien moins contraignant et plus agréable
    Étonnamment, Rust se trouve à l’autre extrémité du spectre des langages, mais donne parfois une impression similaire
    Modification : le terme JIT n’était pas approprié. Je l’ai écrit par paresse, mais je voulais parler des différences de temps de démarrage et de runtime quand on exécute quelque chose sur la JVM et sur V8. Java donne une impression de lourdeur, tandis que l’écosystème JavaScript paraît beaucoup plus agile

    • Comme Java est littéralement ce qui a popularisé le terme JIT, je ne vois pas ce que « Java avec JIT » veut dire
      Je ne vois pas non plus du tout en quoi TypeScript serait plus proche de Java. Les deux ne partagent guère que le mauvais nom « Javascript » et la prise en charge de la programmation impérative ; pour le reste, ils me semblent très différents
    • D’après mon expérience, TypeScript est bien meilleur que Java. Il est beaucoup moins verbeux et plus flexible
    • Personnellement, je préfère de loin utiliser TypeScript plutôt que Java. Surtout si l’on évite les aspects un peu imparfaits des classes et que l’on se concentre sur les interfaces et les fonctions, l’utilisabilité est bien meilleure
      En revanche, ce que Java a et qui me manque dans TypeScript, c’est la réflexion de types à l’exécution. L’écosystème TypeScript propose d’innombrables contournements, mais je les trouve tous un peu disgracieux
    • Java a un JIT. Et je suis curieux de savoir en quoi le système de types de TypeScript est plus riche en fonctionnalités que celui de Java
    • Je suis dans une situation similaire. Personnellement, ce que je voudrais, c’est la bibliothèque standard et l’écosystème de C#, moins les parties héritées ou de fait abandonnées, avec en plus la simplicité et la puissance des types algébriques structurels
      L’AoT me conviendrait aussi, et une option de binaire unique serait appréciable. Idéalement, il n’y aurait pas de runtime et une élimination intelligente serait possible. Si ça pouvait aussi tourner avec un JIT dans le navigateur, ce serait encore mieux
      Je voudrais aussi des facilités côté compilateur et vérificateur de types, comme le pattern matching exhaustif
  • Des fonctionnalités de Deno que j’aime arrivent directement dans Node. Excellent
    Peut-être que je n’aurai plus toujours besoin d’installer esbuild juste pour supprimer les types. J’ai hâte, car écrire et utiliser des scripts en TypeScript devrait devenir beaucoup plus simple
    Ces derniers temps, je préférais Python pour les scripts ponctuels, mais côté types, je trouve personnellement TypeScript meilleur que Python. Les gros scripts qu’on rouvre quelques mois plus tard profitent particulièrement des types

  • Ce mois-ci a vraiment été riche en événements pour Node. D’abord node:sqlite a été ajouté dans la v22.5.0, et maintenant la prise en charge de TypeScript arrive aussi. J’aime la direction que prend Node

    • J’imagine que c’est dû à l’influence de Bun, ou à la concurrence avec lui. C’est une bonne chose pour tout le monde
    • Le test runner ajouté récemment est aussi très sympa
  • Je suis l’auteur de la PR. Vous pouvez me poser n’importe quelle question

    • Je me demande quelles sont les prochaines étapes, et quel avenir tu imagines pour TypeScript dans Node et dans l’écosystème JS au sens large
  • J’ai commencé il y a longtemps à utiliser Node.js pour du backend, et il me semblait qu’il offrait beaucoup d’avantages par rapport à l’écriture de code en PHP, sans reprendre beaucoup des problèmes de Java
    Mais Node était assez rudimentaire, et donnait l’impression d’être un langage auquel il fallait greffer diverses choses pour obtenir le langage que l’on voulait. J’ai fini par commencer à utiliser Go, qui était beaucoup plus facile à utiliser et, même s’il est parfois bien plus verbeux, la sûreté de typage rendait le codage plus simple
    TypeScript semblait être une bonne option, mais au final c’était encore une couche ajoutée. Je ne vois pas bien quelle valeur on gagne à utiliser TypeScript plutôt que Go. Avoir des types explicites, c’est bien, mais cela ne résout pas les autres problèmes du langage que Go a résolus. Deno en résout aussi une partie
    Le gros avantage de Node par rapport à Go, c’est qu’on peut prototyper rapidement, mais avec TypeScript cet avantage semble nettement réduit. Il est donc difficile de dire si c’est une bonne avancée, ou si cela fait perdre à Node les caractéristiques qui en faisaient une bonne option

    • TypeScript, c’est du JS plus sûr. Même avec TS, on écrit toujours du JS
      À voir l’expression « couche ajoutée », le problème vient peut-être moins du langage lui-même que de l’absence d’un framework opinionated qui gère tout par défaut, comme Django. J’aime utiliser Django, mais il est un peu plus difficile de sortir des sentiers battus
    • La réponse évidente, c’est la familiarité avec le langage. Si le code frontend du projet est en JavaScript ou TypeScript, utiliser Node est un choix facile. On peut utiliser des bibliothèques partagées, des types partagés, etc.
    • C’est peut-être parce que c’est mieux que d’apprendre Go si l’on connaît déjà JavaScript ou si l’entreprise a déjà cette expérience en interne. Nous aussi, nous avions une expérience frontend préalable, et nous l’utilisons avec cdktf ; cela nous a paru un choix plus logique que Go