Accélérer les builds qui dépendent de nodejs

Quel que soit le procédé utilisé pour compiler ces projets JavaScript ou TypeScript, il y a une étape qui est trop souvent négligée. Il s’agit de l’opération de récupération des modules. Le fameux : npm install.

Même si npm a beaucoup évolué ces dernières années, il est toujours à la traine par rapport aux alternatives que sont yarn et pnpm.

Pourquoi ?

Yarn a la bonne idée de ne télécharger qu’une fois un module, quel que soit le nombre de projets qui l’utilisent. Il télécharge aussi plus rapidement les fichiers.

Pnpm va un peu plus loin. Il a les mêmes avantages que yanr sur npm. Mais, il ne réalise pas de copie des modules. Il crée des liens symboliques vers les dossiers des modules téléchargés (il adapte la technologie à employer en fonction de l’OS : Linux, Mac, Windows). La durée de création de ces liens est bien plus courte qu’une copie. Il a en plus l’avantage de structurer différemment les modules dans le répertoire node_modules. Cela n’a pas d’impact sur la durée de la build, je ne vais donc pas détailler ce point.

Quels intérêts et limites pour un agent de build ?

Même si yarn et pnpm ont prouvé tout leur intérêt sur un PC de développement, leur emploi dans une build automatisée n’est pas toujours aussi efficace.

Ne vous méprenez pas, yarn et pnpm peuvent être utilisés dans une build Azure DevOps, GitHub, Jenkins ou autres sans problèmes. Il y a cependant des cas où ils sont inutiles :

  • Agent autohébergé par GitHub ou Azure DevOps
  • Agent utilisé dans un conteneur instancié à chaque nouvelle build.
  • Agent hébergé derrière un bon proxy.

Dans les deux premiers cas, yarn et pnpm ne peuvent pas profiter des modules téléchargés lors d’une précédente build. Les modules sont donc téléchargés à chaque build. La différence par rapport à npm est donc mimine (à chaque version de npm, cette différence s’amenuise). Il est même possible que ce gain s’annule par le temps perdu à installer yarn ou pnpmn à chaque build (hormis si votre agent contient déjà ces outils). Pour la même raison, la présence du proxy peut donner l’avantage à npm.

Vous l’aurez compris, yarn et pnpm révèlent leur plein potentiel quand ils sont utilisés avec un agent selft-hosted. Ce peut être une VM dans le cloud ou héberger sur son propre réseau. Dans tous les cas, le serveur de build doit permettre à yarn ou pnpm da’voir un cache local. Ce cache pourra profiter à plusieurs projets (à la manière du package référence de nuget).

Concrètement

Exemple : Sur l’un de mes projets, une première installation de module via npm, yarn ou pnpm qui prend entre 5 et 6 minutes :

  • npm consommera toujours 5 à 6 minutes.
  • yarn ne consommera plus que 24 secondes après la première build.
  • pnpm ne consommera plus que 6 secondes après la première build.

L’Hyper-V qui héberge mes agents de builds Azure DevOps utilise des disques mécaniques. L’usage de SSD pour la build pourrait réduire l’écart entre yarn et pnpm. Mais ce n’est pas garanti. Dans mon cas, l’usage de pools, ReFS et de disque VHDX me permet de faire passer de vieux disques pour de véritables petites bombes.

Jérémy Jeanson

Comments

You have to be logged in to comment this post.