Loupe

Babel et Typescript - Et si c'était simple ?

Il est désormais temps de rentrer dans le vif du sujet ! Si vous n’avez pas vu la première partie de cet article qui présente Babel ainsi que @babel/preset-env, c’est ici.

Aujourd’hui, Typescript est quasiment un incontournable de l’écosystème javascript. Ce langage inventé par Microsoft et notamment par le créateur de C# a fait un sacré bout de chemin en très peu de temps, à tel point qu’il fait partie des 15 langages de programmation les plus utilisés en 2019 !

Le but de cet article est de montrer comment il est possible d’intégrer Typescript et Babel dans un même projet. Sauf qu’il se trouve que ces deux outils ont sensiblement le même but : transpiler du javascript. En effet, Typescript permet de transpiler du code javascript Typescript (.ts) en du Javascript Vanilla, et Babel du Javascript avec de la syntaxe ES2015+ en du Javascript Vanilla.

La solution Webpack avec un loader typescript

Si nous reprenons l’exemple de notre dernier article, nous avions défini dans notre configuration Webpack que les fichiers js seraient traités par Babel. Si nous voulions intégrer Typescript dans ce workflow en suivant la même logique, on obtiendrait ceci :

  1. On a du code Typescript (.ts)
  2. Le compilateur Typescript convertit le code typescript en du javascript (.js)
  3. On a désormais du code javascript avec possiblement de la syntaxe ES2015+
  4. Babel convertit le javascript en du javascript vanilla compréhensible par les navigateurs que l’on target.

En pratique cela fonctionne mais :

  • On se retrouve à avoir 2 compilateurs et ce n'est en général pas quelque chose que l’on souhaite.
  • Le compilateur Typescript fait énormément de traitement et donc les performances au global sont assez moyennes.
  • Il existe 2 loaders majeurs typescript pour Webpack mais chacun demande sa propre configuration pour fonctionner correctement. En fonction de ce que vous souhaitez avoir comme comportement, la complexité peut varier du tout au tout.

A savoir que tout cela est d’autant plus contraignant si l’on souhaite mettre en place Typescript et Babel dans une build déjà existante.

La question est donc, pourquoi ne pas avoir un seul compilateur qui s’occupe de tout ? Vous vous en doutez, la réponse est dans la question : c’est possible !

Pour les plus érudit d’entre-vous, vous savez qu’il est déjà possible d'obtenir des résultats en utilisant uniquement le compilateur Typescript. En effet, le champ target du fichier de configuration du compilateur Typescript tsconfig.json permet de spécifier la version d’ECMAScript que l’on souhaite supporter.

“C’est exactement ce que l’on veut” me direz-vous ! Pas tout à fait, l’énorme désavantage de cette solution est que l’on perd toute l’optimisation rendue possible par @babel/preset-env, et notamment son attribut target, en effet, impossible ici de cibler les browsers que l’on souhaite supporter, le compilateur Typescript transpilera par défaut toutes les fonctions ECMAScript qu’il trouvera.

Si le compilateur de typescript n’a pas ce que l’on veut, l’autre solution est de voir ce que Babel peut nous proposer. Et il se trouve qu’il y a de quoi être satisfait :)

La solution Babel : Pourquoi compiler du Typescript ?

Babel fonctionne par plugin afin d’étendre ses fonctionnalités, chaque plugin que l’on installe est responsable d’effectuer un traitement spécifique sur le code. Et heureusement pour nous, les équipes de Microsoft et celles de Babel se sont associées pour mettre au point un plugin Typescript pour Babel.

Pour l’installer :

> npm install --save-dev @babel/preset-typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread

Modifions ensuite notre configuration Babel .babelrc existante afin d’utiliser Typescript:

{
	"presets":  [
		["@babel/preset-env",
			{
				"targets":  {
					"browsers":  [">0.25%",  "ie >= 11"]
				},
				"corejs":  3,
				"useBuiltIns":  "entry"
			}
		],
		"@babel/preset-typescript"
	],
	"plugins":  [
		"@babel/proposal-class-properties",
		"@babel/proposal-object-rest-spread"
	]
}

En modifiant cette configuration, nous venons d’ajouter le preset @babel/preset-typescript afin de permettre le traitement des fichier Typescript. On a également ajouté deux paquets (@babel/proposal-class-properties et @babel/proposal-object-rest-spread) afin de permettre à Babel de reconnaître certaines syntaxes.

N’oubliez pas également d’ajouter à tout ça votre configuration du compilateur typescript dans un fichier tsconfig.json à la racine de votre projet.

Ainsi, lors de la compilation, le plugin Typescript va être responsable de reconnaître le code Typescript et de le supprimer, ne laissant à Babel que du javascript pur qu’il sait parfaitement traiter.

Eh oui, vous avez bien lu, le code Typescript est supprimé par le plugin Typescript, nous n’avons donc plus de compilation Typescript. L’avantage évident de ce traitement est que cela rend la compilation incroyablement plus rapide. Le désavantage est qu’il n’y a plus de type-checking pendant la compilation, votre code Typescript peut ne pas être correct, vous n’aurez aucune erreur à la compilation. Heureusement pour nous il est très simple de palier à ce problème, de plusieurs façons :

  • En mettant en place un script qui watch nos fichiers .ts et exécute le compilateur Typescript qui va pouvoir nous dire en temps réel si nous avons des erreurs ou pas.
  • En mettant en place un linter comme ESLint configuré pour reconnaître Typescript (attention, tslint n’est plus maintenu et son équipe recommande désormais de passer par eslint).

Et voilà le travail ! On a réussi à mettre en place Babel et Typescript en profitant du meilleur de ce que les deux ont à nous offrir, tout cela en n'ayant qu’un seul compilateur et une build beaucoup plus rapide ! Elle est Babel la vie ?

Dans le prochain article qui conclura cette petite série sur Babel, nous parlerons des macros Babel et l’avenir de cet outil au sein de écosystème Javascript.

Happy coding !

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus