Loupe

Gagnez du temps en développant avec Snowpack !

Hello !

Aujourd’hui on se retrouve pour parler bundler js, performances et confort de développement.

De nos jours, quand on parle d’applications modernes Javascript et surtout bundling, nous n’avons qu’un seul mot à la bouche: Webpack.

Pour rappel, Webpack est ce qu’on appelle un Bundler, un Bundler est un outil qui va nous permettre d’écrire du code sous forme de modules indépendants qu’il va ensuite transformer et concaténer en un ou plusieurs fichiers nommés bundles, qui contiendront toute notre application js. Les bundlers sont devenus aujourd’hui indispensables tant ils sont performants et nous permettent d’avoir une build impeccable pour la production.

Mais quid lors du développement ? Quel sont les performances des bundlers lors de cette phase ? Est-ce toujours pertinent d’avoir beaucoup de traitement et du bundling quand on veut simplement mettre à jour une couleur ?

La question est certes biaisée mais la réponse est elle objective : les bundler ne sont aujourd’hui pas adaptés pour le développement. Et ce, malgré des configurations spécifiques que l’on peut mettre en place pour un environnement de développement.
Le problème vient simplement de leur complexité et des nombreux traitements qu’ils réalisent et qui in-fine induisent de mauvaises performances de build et de rebuild, qui de plus croissent au fur et à mesure que la taille du projet grossit.

La solution Snowpack

C’est avec ce postulat de départ que l’équipe derrière Snowpack (Pika) décida de lancer une alternative aux bundlers traditionnels lorsque vous êtes dans un environnement de développement.

Leur piste ? Les module ESM et l’unbundled development

L’ESM (pour EcmasScript Module) est une syntaxe qui permet d’écrire des modules Javascript. C’est cette syntaxe que vous utilisez la plupart du temps dans vos projets web lorsque vous utilisez des keywords comme import ou export default.

Et il se trouve que depuis quelques temps déjà (depuis fin 2017), cette syntaxe est supportée de manière native par les navigateurs modernes. Ainsi, si vous écrivez dans un fichier html :

<script type="module">
    import {myLogger} from "./mon_module.js"

	myLogger("Hello World!");
</script>

Ce code sera compris nativement par votre navigateur qui ira chercher un symbole exporté sous le nom de myLogger dans un fichier nommé mon_module.js .

Ainsi, si les navigateurs sont capables de comprendre nativement cette syntaxe et si vous ajoutez à cela du HMR (Hot Module Reload), il ne reste plus qu’à transpiler votre code javascript afin de le rendre compréhensible par votre navigateur, et le tour est joué. Etant donné que chaque fichier sera traité comme un module ESM indépendant, vous pourrez ainsi profiter de l’HMR lors de chaque modification du fichier pour publier la nouvelle version du module automatiquement au navigateur.

Il se trouve que c’est exactement ce que Snowpack propose, à quelques détails près. Son fonctionnement est donc le suivant :

  • Il transpile l’intégralité de vos dépendances (./node_modules/) en générant un module par paquet dans un dossier qu’il nomme ./web_modules. Il faut évidemment que vos dépendances soient en ESM.
  • Il transpile les fichiers de votre projet où chaque fichier va être également un module indépendant et distinct (et non un bundle unique comme ce que peux fournir webpack).
  • Il envoit tout au navigateur qui s’occupe du module mapping et des résolutions d’imports.
  • Chaque mise à jour de fichier et donc de module est automatiquement transféré au navigateur via l’HMR, évitant le refresh lors d’une modification.

La valeur ajoutée de Snowpack est donc la suivante :

  • Les dépendances du projet ne seront pas modifiées par définition, puisque ce sont des paquets externes. Ils sont donc compilés une seule fois, et seulement une seule fois lors du lancement du serveur de développement.
  • Le support natif de l’ESM par les navigateurs permet de profiter du cache de ceux-ci, et donc de refresh extrêmement rapides.
  • Les fichiers étant des modules distincts et non un seul et unique bundle, le changement d’un fichier ne déclenche que la transpilation de celui-ci.

Ainsi, nous en arrivons au point central de Snowpack :

Cette image tirée de la documentation officielle nous montre que la transpilation étant unitaire par fichier, une modification de fichier déclenche seulement la transpilation de celui-ci. Ceci est à l’opposé du fonctionnement de Webpack où chaque modification de fichier va déclencher une recompilation globale du bundle. C’est cette différence fondamentale qui nous permet ainsi d’avoir d’excellentes performances lors du développement.

Installation

Pour installer Snowpack, c’est très simple :

> mkdir my_snowpack_project && cd ./my_snowpack_project
> npm init -y
> npm install --save-dev snowpack

Cela vous installera Snowpack localement en dépendance de développement. Ce paquet vous permettra d’utiliser deux commandes :

  • snowpack dev : Cette commande vous permet de lancer le serveur local de développement Snowpack.
  • snowpack build : Cette commande vous permet d’effectuer une build de production.

Une fois ceci installé, vous n’avez plus qu’à générer un projet Snowpack. Et là encore Snowpack a tout prévu pour vous : via une commande nommée CSA (pour “Create Snowpack App”), il vous permet de générer un projet via plusieurs templates où tout est déjà câblé pour vous ! C’est une des très grandes forces de Snowpack puisque l’outil supporte un très grand nombre de librairie / framework.

Voici la liste des templates officiels fournis par Snowpack :

Vous pouvez aussi voir la liste des templates créés par la communauté ici.

Voici donc la commande pour générer un projet Snowpack :

> npx create-snowpack-app folder_location --template [template] [--use-yarn]

Ainsi, si je veux générer un projet react-typescript dans mon dossier courant (my_snowpack_project) :

> npx create-snowpack-app ./ --template @snowpack/app-template-react-typescript --force

Et en production ?

Très bien, nous avons donc présenté Snowpack en ce qui concerne l’environnement de développement qui est son terrain de jeu principal. Mais qu'en est-il de la build de production ?

En ce qui concerne la build de production, Snowpack fournit une commande que nous avons cité précédemment qui est snowpack build. Cette commande par defaut va builder exactement de la même manière que la commande de dev, à l’exception que l’intégralité des fichiers se retrouveront dans un dossier build.

Comme le précise la documentation officielle de Snowpack, cette approche devrait suffire pour la plupart des petits projets. Cependant, on est très loin de ce que l’on peut appeler une build de production. A ce stade, nous n’avons pas de minification, pas de code-splitting, pas de support pour anciens navigateurs, etc… La documentation conseille donc d’utiliser dans ce genre de cas un véritable bundler qui est beaucoup plus adapté à ce genre de besoins. Snowpack a donc déjà sorti des plugins officiels pour supporter Webpack ainsi que Parcel.

Prenons donc l’exemple de Webpack. Pour cela rien de plus simple, il vous suffit d’installer le plugin suivant :

> npm install --save-dev @snowpack/plugin-webpack

Une fois installé, il vous suffit d’ajouter le plugin à la liste des plugins de Snowpack.

// snowpack.config.json
{
  "plugins": ["@snowpack/plugin-webpack"]
}

Cela dira à Snowpack d’envoyer tous les fichiers transpilés à Webpack afin qu’il s’occupe du bundling. Attention, par default, une configuration de base de Webpack sera utilisée. Pour surcharger cette configuration, vous devrez passer par les options du plugin (Ce changement nécessite également que vous passiez votre fichier de configuration en “Javascript config file”, le JSON ne pouvant pas représenter des fonctions).

Ainsi, si vous souhaitez par exemple changer le nom par défaut du bundle généré :

// snowpack.config.js
module.exports  =  {
	"extends":  "@snowpack/app-scripts-react",
	"scripts":  {},
	plugins: [
		[
			"@snowpack/plugin-webpack",
			{
				extendConfig:  (config)  =>  {
					config.output.filename =  "index_bundle.js";
					return config;
				},
			},
		],
	],
};

Et voilà le travail, ça n'est pas plus compliqué que ça ! Vous avez désormais une build de production classique et optimisée, et tout cela directement intégré à Snowpack !

Attention, l’essayer c’est l’adopter :P

Happy Coding !

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus