Una sola importación dinámica de un icono hizo colapsar el servidor de desarrollo en una máquina con Windows Subsystem for Linux 2 (WSL2) de 16 GB, obligando al proceso vmmemWSL a devorar toda la memoria disponible y congelar toda la ventana de Linux. El fallo ocurrió mientras se ejecutaba un proyecto Next.js 16 que utiliza Turbopack, y sucedió a pesar de tener un archivo .wslconfig que limita el uso de RAM de la VM.

Por qué una importación diminuta puede convertirse en un monstruo

El desarrollador intentó resolver los iconos en tiempo de ejecución con un punto de entrada dinámico. La importación llamó a un paquete de iconos que contiene aproximadamente 9,000 módulos. Turbopack, el bundler basado en Rust que impulsa el servidor de desarrollo de Next.js 16, construye un mapa de módulos completo para cada paquete que toca. En modo de desarrollo, el mapa reside en la memoria y se actualiza con cada cambio de archivo. Cargar todo el paquete de iconos obligó a Turbopack a asignar una gran cantidad de RAM, alcanzando rápidamente el límite estricto establecido por el archivo .wslconfig. Una vez alcanzado el límite, la VM de WSL dejó de responder; Ctrl + C no hizo nada y la única salida fue un apagado forzado del host de Windows.

Una build de producción del mismo código tuvo éxito porque el bundler compila el grafo una sola vez, genera los assets y finaliza. El servidor de desarrollo, sin embargo, mantiene el grafo residente para permitir el hot-reloading. Por lo tanto, una build exitosa no garantiza que el entorno de desarrollo pueda sobrevivir al mismo patrón de importación.

El riesgo más amplio

Los desarrolladores que trabajan con cadenas de herramientas basadas en Linux dentro de Windows dependen de WSL2 para aislar el uso de recursos. Cuando una sola importación agota la memoria de la VM, todo el host puede volverse lento o dejar de responder, afectando a cualquier otro contenedor o aplicación en la misma máquina. El incidente también resalta una falta de coincidencia entre los flags típicos de ajuste de memoria de Node.js y la arquitectura de Turbopack: Turbopack se ejecuta en Rust, no en V8, por lo que aumentar el flag de Node --max-old-space-size no sirve para frenar su consumo de RAM.

Qué salió mal realmente

  • Punto de entrada dinámico: La sentencia de importación pidió al bundler que tratara todo el paquete de iconos como un único módulo de carga diferida (lazy-loaded). Turbopack respondió analizando de forma inmediata cada archivo para construir el mapa de módulos.
  • Grafo del servidor de desarrollo: A diferencia de una compilación de producción única, el servidor de desarrollo retiene el grafo de dependencias completo en la RAM para proporcionar una respuesta instantánea ante los cambios de archivos.
  • Límite de memoria: El archivo .wslconfig limitaba la VM a una fracción de la RAM del host. Cuando la demanda de Turbopack superó ese límite, la VM se congeló.

Soluciones que reducen la memoria a la mitad

El desarrollador aplicó tres cambios prácticos que redujeron el uso de RAM de 3.6 GB a 1.87 GB y restauraron la estabilidad:

  1. Dejar de usar puntos de entrada dinámicos para assets pequeños – Importa solo los iconos que necesites, por ejemplo: import { SearchIcon } from 'icon-pack/search'. Si solo necesitas unos pocos, los SVGs en línea son incluso más ligeros.
  2. Habilitar optimizePackageImports en next.config.ts – Esta opción le indica a Turbopack que resuelva las importaciones a sus rutas de archivos concretas en lugar de a la raíz del paquete, evitando que cargue todo el árbol del paquete.
  3. No confiar en los flags del heap de Node – Dado que el uso de memoria de Turbopack está gobernado por su entorno de ejecución de Rust, --max-old-space-size no tiene efecto sobre el problema.

Aún se recomienda mantener los límites de .wslconfig. Un límite estricto puede hacer que la VM se pause en lugar de hacer colapsar el host de Windows, dándote la oportunidad de intervenir antes de que todo se detenga.

Qué vigilar en tu propio flujo de trabajo

  • Tableros de memoria: Herramientas como htop dentro de WSL o el Administrador de tareas de Windows pueden revelar cuándo vmmemWSL tiene picos de consumo. Configura alertas si el uso se acerca a tu límite configurado.
  • Auditorías de tamaño de paquetes: Antes de añadir una librería, comprueba cuántos módulos incluye. Los paquetes de iconos grandes, las colecciones de utilidades o las librerías de componentes pueden inflar silenciosamente el grafo de desarrollo.
  • Importaciones selectivas: Favorece las importaciones con nombre o las rutas de archivos directas sobre las importaciones con comodines o dinámicas, especialmente en un entorno de desarrollo donde el bundler mantiene todo residente.
  • Paridad entre producción y desarrollo: Trata una build de producción exitosa como un paso de validación separado. Ejecuta el servidor de desarrollo con un monitor de memoria para detectar problemas que solo aparecen durante el hot-reloading.

Conclusión

Un solo paquete de iconos importado dinámicamente puede consumir suficiente RAM como para paralizar un servidor de desarrollo Next.js basado en WSL2, incluso cuando los recursos del host están limitados deliberadamente. Al evitar las importaciones dinámicas amplias, habilitar la optimización de importaciones a nivel de paquete y monitorear el uso de la memoria, los desarrolladores pueden mantener sus entornos de Linux dentro de Windows con capacidad de respuesta y evitar apagados forzados.