Saltar al contenido

Rolldown: el bundler en Rust de Vite 8

Rolldown es el bundler escrito en Rust que Vite 8 adopta como motor único, sucesor de Rollup y del esbuild que empaquetaba las dependencias. Por qué el ecosistema unifica dos motores en uno, cómo conserva la compatibilidad con la API de plugins de Rollup apoyándose en Oxc, qué familia de herramientas nativas lo rodea y qué cambia de forma concreta en el build de Astro 7: más velocidad en sitios grandes y menos distancia entre lo que desarrollas y lo que despliegas.

De dos motores a uno

Para entender Rolldown hay que ver el hueco que llena. Rollup es un bundler veterano y muy respetado: produce paquetes limpios, con un tree shaking excelente y una API de plugins que se convirtió en un estándar de facto —el propio Vite la adoptó—. Su debilidad es el rendimiento en grafos enormes: escrito en JavaScript, se ralentiza cuando el proyecto tiene decenas de miles de módulos. esbuild, escrito en Go, es lo contrario: velocísimo, pero con un modelo de salida y un ecosistema de plugins menos ricos, razón por la que Vite lo usaba solo para la fase de pre-empaquetado, no para el artefacto final.

Esa convivencia dejaba una grieta: una dependencia podía comportarse de una manera al pre-empaquetarse con esbuild en desarrollo y de otra al empaquetarse con Rollup en producción. Rara vez rompía, pero cuando lo hacía, el fallo aparecía justo donde más cuesta depurarlo: en el build, ausente en local. Rolldown cierra la grieta sirviendo a las dos fases con el mismo código.

Conviene fijar el reparto histórico de papeles, porque Rolldown hereda lo mejor de cada lado y descarta su punto débil:

  • Rollup aportaba la calidad del artefacto y una API de plugins que se volvió estándar, pero se frenaba en grafos enormes por estar escrito en JavaScript.
  • esbuild aportaba una velocidad deslumbrante en el pre-empaquetado, pero su modelo de salida y su ecosistema no encajaban como bundler de producción.
  • Rolldown persigue las dos virtudes juntas: la salida y los plugins de Rollup con la velocidad de un motor nativo escrito en Rust.

El nombre lo dice todo: Rolldown aspira a ser, respecto a Rollup, lo que una evolución es a su predecesor, no un competidor que parte de cero. Adopta su vocabulario de plugins y su modelo de salida precisamente para que migrar sea, en el caso común, no tener que hacer nada.

Por qué Rust y por qué reescribir

La pregunta obvia es por qué reescribir Rollup en lugar de optimizarlo. La respuesta es que el techo de rendimiento de un bundler en JavaScript es estructural, no un problema de detalle. El trabajo de un bundler es intensivo en CPU y muy paralelizable, y ahí un lenguaje nativo con hilos reales bate a un intérprete de un solo hilo por márgenes que ninguna microoptimización alcanza.

Ese trabajo se descompone en fases que un motor nativo puede repartir entre todos los núcleos de la máquina:

  • Parsear miles de ficheros a su árbol de sintaxis, la fase más pesada y la más paralelizable de todas.
  • Resolver el grafo de dependencias siguiendo cada import hasta su origen en disco.
  • Recorrer ese grafo para el tree shaking, marcando qué exportaciones sobreviven y cuáles mueren.
  • Generar y minificar la salida final, chunk a chunk, hasta el artefacto que se despliega.

La clave estratégica está en la tercera tarjeta. Rolldown no rompe con Rollup: imita deliberadamente su API de plugins para que la enorme biblioteca de plugins existente siga funcionando con cambios mínimos. Reescribir el motor sin reescribir el ecosistema es la única forma de que una transición así sea viable, porque una herramienta sin plugins no es una alternativa real, por rápida que sea. La compatibilidad es, aquí, tan importante como la velocidad.

Una familia de herramientas nativas

Rolldown no llega solo, y ahí reside buena parte de su valor. Pertenece a una familia de herramientas en Rust agrupadas bajo VoidZero, el equipo que sostiene Vite, diseñadas para compartir base en lugar de reimplementar cada una su propio parser y su propio resolver.

  • Oxc es la base común: parser, resolver, transformador y linter en Rust, reutilizados por las capas de arriba.
  • Rolldown empaqueta apoyándose en Oxc, sin reparsear el código con utilidades escritas en JavaScript.
  • Vite orquesta el dev server y el build, y delega en Rolldown el trabajo de empaquetar.
  • Astro monta sobre Vite y añade su compilador, también en Rust, para traducir los ficheros .astro.

La consecuencia es sutil pero decisiva: el análisis del código no cruza la frontera entre lenguajes en ningún punto caliente de la cadena. Un .astro se compila en Rust, su salida se empaqueta en Rust y cada dependencia se parsea en Rust. Antes ese camino saltaba varias veces entre mundos —de un compilador a WebAssembly, de esbuild en Go a Rollup en JavaScript— y cada salto tenía un coste de serialización. Una sola pila nativa de arriba abajo elimina esos peajes, y por eso la mejora se acumula en lugar de diluirse en las costuras.

Dónde se nota más la ganancia se puede anticipar con una regla simple:

  • En sitios pequeños, apenas la percibes: el build ya era casi instantáneo y no había mucho que recortar.
  • En sitios grandes —miles de páginas, muchos módulos— es donde el motor nativo separa los segundos de los minutos.
  • En el desarrollo diario, el arranque en frío y el pre-empaquetado más veloces se suman a cada sesión de trabajo.

Qué cambia en el build de Astro 7

Para ti, autor de un sitio Astro, la mayoría del cambio es invisible por diseño: no reconfiguras nada, no reescribes componentes y la API de astro.config no se mueve. Lo que cambia es el rendimiento y la coherencia, y ambos se notan más cuanto mayor es el proyecto.

  • El build de producción empaqueta miles de módulos sin el cuello de botella del bundler en JavaScript; un sitio de documentación con decenas de miles de páginas baja de minutos a segundos.
  • El pre-empaquetado de dependencias en desarrollo pasa a hacerlo el mismo motor que la producción, así que el arranque en frío es más rápido y más consistente con el build.
  • La coherencia dev-producción mejora: al empaquetar ambas fases con Rolldown, desaparece la clase de fallos que solo asomaban en el build por usar un motor distinto que en local.
Shell
# El build de Astro 7 usa Vite 8 con Rolldown por debajoastro build# el empaquetado de miles de modulos deja de ser el cuello de botella# el mismo motor ya habia pre-empaquetado las dependencias en dev

Para el autor, lo esencial es que Rolldown es un cambio silencioso por diseño. No hay una bandera que activar ni un modo que elegir: al usar Astro 7 ya construyes sobre Vite 8 con Rolldown por debajo, y la ganancia llega por el mero hecho de actualizar. Lo que permanece intacto importa tanto como lo que mejora:

  • Tu sintaxis .astro y tus componentes no se tocan en absoluto.
  • La API de astro.config no cambia: las mismas claves, los mismos valores.
  • El modelo mental —islas, contenido, render estático o bajo demanda— es idéntico.

Conviene una nota de realismo. Una transición de motor de esta magnitud puede rozar algún plugin de Vite o Rollup que dependa de detalles internos no documentados del bundler anterior; esos casos raros se resuelven actualizando el plugin a su versión compatible con Rolldown. El compilador de Astro y las integraciones oficiales ya vienen adaptados, de modo que un proyecto estándar no toca nada.

Si mantienes tus dependencias al día, el salto a Astro 7 es de los que se sienten solo en el cronómetro. La forma correcta de comprobarlo no es leer notas de versión, sino medir en tu propio proyecto:

Shell
# comparar el tiempo de build antes y despues de subir de versiontime astro build# repite tras actualizar Astro y observa la diferencia en sitios grandes

Deja que los tiempos hablen por sí solos: es el único benchmark que de verdad importa, el del proyecto que tienes entre manos.