Un seul import d'icône dynamique a fait planter le serveur de développement sur une machine Windows Subsystem for Linux 2 (WSL2) de 16 Go, forçant le processus vmmemWSL à engloutir toute la mémoire disponible et à figer toute la fenêtre Linux. Le crash est survenu lors de l'exécution d'un projet Next.js 16 utilisant Turbopack, et ce, malgré un fichier .wslconfig qui limite l'utilisation de la RAM de la VM.
Pourquoi un minuscule import peut devenir un monstre
Le développeur a tenté de résoudre les icônes au moment de l'exécution avec un point d'entrée dynamique. L'import a appelé un package d'icônes contenant environ 9 000 modules. Turbopack, le bundler basé sur Rust qui alimente le serveur de développement de Next.js 16, construit une carte complète des modules pour chaque package qu'il touche. En mode développement, cette carte réside en mémoire et se met à jour à chaque modification de fichier. Le chargement de l'intégralité du package d'icônes a forcé Turbopack à allouer une quantité massive de RAM, atteignant rapidement le plafond strict défini par le fichier .wslconfig. Une fois la limite atteinte, la VM WSL a cessé de répondre ; Ctrl + C ne faisait rien et la seule issue était un arrêt forcé de l'hôte Windows.
Un build de production du même code a réussi car le bundler compile le graphe une seule fois, génère les assets et s'arrête. Le serveur de développement, en revanche, maintient le graphe en mémoire pour permettre le rechargement à chaud (hot-reloading). Un build réussi ne garantit donc pas que l'environnement de développement puisse survivre au même modèle d'import.
Les enjeux plus larges
Les développeurs travaillant sur des chaînes d'outils basées sur Linux à l'intérieur de Windows s'appuient sur WSL2 pour isoler l'utilisation des ressources. Lorsqu'un seul import épuise la mémoire de la VM, l'hôte entier peut devenir lent ou peu réactif, affectant tout autre conteneur ou application sur la même machine. L'incident souligne également un décalage entre les flags typiques d'optimisation de la mémoire de Node.js et l'architecture de Turbopack : Turbopack s'exécute en Rust, et non en V8, donc augmenter le flag Node --max-old-space-size ne sert à rien pour freiner sa consommation de RAM.
Ce qui s'est réellement passé
- Point d'entrée dynamique : L'instruction d'import demandait au bundler de traiter l'intégralité du package d'icônes comme un seul module chargé à la demande (lazy-loaded). Turbopack a réagi en analysant systématiquement chaque fichier pour construire la carte des modules.
- Graphe du serveur de développement : Contrairement à une compilation de production ponctuelle, le serveur de développement conserve l'intégralité du graphe de dépendances en RAM pour fournir un retour instantané lors des modifications de fichiers.
- Limite de mémoire : Le fichier .wslconfig limitait la VM à une fraction de la RAM de l'hôte. Lorsque la demande de Turbopack a dépassé cette limite, la VM a gelé.
Des correctifs qui divisent la mémoire par deux
Le développeur a appliqué trois changements pratiques qui ont réduit l'utilisation de la RAM de 3,6 Go à 1,87 Go et ont rétabli la stabilité :
- Arrêter d'utiliser des points d'entrée dynamiques pour de petits assets – Importez uniquement les icônes dont vous avez besoin, par exemple
import { SearchIcon } from 'icon-pack/search'. Si vous n'en avez besoin que de quelques-unes, les SVG en ligne (inline) sont encore plus légers. - Activer
optimizePackageImportsdansnext.config.ts– Cette option indique à Turbopack de résoudre les imports vers leurs chemins de fichiers concrets plutôt que vers la racine du package, l'empêchant ainsi de charger tout l'arbre du package. - Ne pas se fier aux flags de tas (heap) de Node – Puisque l'utilisation de la mémoire de Turbopack est régie par son runtime Rust,
--max-old-space-sizen'a aucun effet sur le problème.
Il est toujours conseillé de maintenir les limites du fichier .wslconfig. Un plafond strict peut amener la VM à se mettre en pause plutôt qu'à faire planter l'hôte Windows, vous donnant ainsi une chance d'intervenir avant que tout ne s'arrête.
Ce qu'il faut surveiller dans votre propre flux de travail
- Tableaux de bord de la mémoire : Des outils comme
htopà l'intérieur de WSL ou le Gestionnaire des tâches Windows peuvent révéler quandvmmemWSLprésente des pics. Configurez des alertes si l'utilisation approche de votre limite configurée. - Audits de la taille des packages : Avant d'ajouter une bibliothèque, vérifiez combien de modules elle contient. Les grands packs d'icônes, les collections d'utilitaires ou les bibliothèques de composants peuvent gonfler silencieusement le graphe de développement.
- Imports sélectifs : Privilégiez les imports nommés ou les chemins de fichiers directs plutôt que les imports avec wildcard ou dynamiques, surtout dans un environnement de développement où le bundler maintient tout en mémoire.
- Parité production vs développement : Considérez un build de production réussi comme une étape de validation distincte. Lancez le serveur de développement avec un moniteur de mémoire pour détecter les problèmes qui n'apparaissent que lors du rechargement à chaud.
À retenir
Un seul package d'icônes importé dynamiquement peut consommer suffisamment de RAM pour paralyser un serveur de développement Next.js basé sur WSL2, même lorsque les ressources de l'hôte sont délibérément limitées. En évitant les imports dynamiques trop larges, en activant l'optimisation des imports au niveau du package et en surveillant l'utilisation de la mémoire, les développeurs peuvent maintenir la réactivité de leurs environnements Linux sous Windows et éviter les arrêts forcés.
