Novedades de Vite 6: federación de módulos ESM y optimización de rendimiento

46 segundos.
Eso es lo que el equipo de Linear esperaba en cada build. Cambias una línea, vuelves a compilar y se van 46 segundos. A finales de 2024 actualizaron a Vite 6 y activaron Rolldown: el tiempo de build cayó a 6 segundos.
Cuando vi esos datos, me costó creerlos. ¿Diez veces más rápido? Hasta que lo probé en un proyecto real y comprobé que no exageraban.
Vite 6 no es una actualización menor de «cambiar un par de opciones de configuración». Environment API cambia por completo la forma de construir para varios entornos. La integración con Rolldown acerca dev y prod a la misma lógica de empaquetado. Y la federación de módulos ESM empieza a tener soporte oficial de verdad.
En un proyecto pequeño quizá no lo notes mucho. Pero si mantienes una aplicación frontend grande, trabajas con microfrontends o estás harto del clásico «en dev funciona y en producción revienta», este artículo merece la pena.
Capítulo 1: panorama de las novedades clave de Vite 6
1.1 Environment API: un nuevo paradigma para varios entornos
Environment API es el cambio arquitectónico más importante de Vite 6, pero la verdad es que la mayoría de proyectos no necesitarán tocarla.
En resumen: antes Vite solo tenía por defecto los entornos client y ssr. Si querías desplegar en Cloudflare Workers, Deno u otro runtime edge, te las arreglabas como pudieras. Los autores de frameworks tenían que escribir montones de hacks para que Vite funcionara en cada entorno.
Environment API formaliza ese «arreglárselas». Ahora puedes configurarlo así:
// vite.config.ts
export default defineConfig({
environments: {
client: {
// Entorno del navegador
build: {
outDir: 'dist/client'
}
},
ssr: {
// Entorno SSR de Node.js
build: {
outDir: 'dist/server'
}
},
edge: {
// Entorno edge (por ejemplo, Cloudflare Workers)
resolve: {
conditions: ['worker']
},
build: {
outDir: 'dist/edge'
}
}
}
})
Puede que pienses: esto nunca lo voy a necesitar. Probablemente tengas razón. Environment API está pensada sobre todo para autores de frameworks: Nuxt, SvelteKit, Astro y otros pueden soportar distintos entornos de despliegue con más elegancia.
En proyectos normales, si solo tienes una SPA o MPA, la configuración no cambia. Vite mantiene compatibilidad hacia atrás y no hace falta tocar código.
¿Qué impacto tiene para ti? Indirectamente, bastante. Si los frameworks soportan más entornos, tu proyecto gana más opciones de despliegue. Nuxt puede ir a Cloudflare Workers con un clic; Astro puede correr en Deno Deploy. Todo eso se abre gracias a Environment API.
1.2 Soporte de Node.js e impacto en la migración
Vite 6 soporta oficialmente Node.js 18, 20 y 22+. Node.js 21 quedó obsoleto: era una versión intermedia de LTS y casi nadie la usaba en producción.
Si tu proyecto sigue en Node.js 16, toca actualizar. La versión mínima de Node.js 18 es 18.18.0, que trae características de las que Vite depende.
Puntos a vigilar en la migración:
- El valor por defecto de
resolve.conditionspasó de['module', 'browser', 'jsnext:main', 'jsnext']a['module', 'browser', 'jsnext:main', 'jsnext', 'import']. Si lo configuraste a mano, puede que haya que ajustarlo. - Si usas entornos no estándar (Deno, Bun, etc.), quizá debas indicar
resolve.conditionsde forma explícita.
En la práctica, actualizar a Vite 6 en la mayoría de proyectos es cambiar el número de versión. Probé tres proyectos y en todos bastó un npm install vite@latest.
1.3 Otros cambios importantes
Además de Environment API, Vite 6 trae otros cambios que conviene conocer:
La API moderna de Sass está activada por defecto. Antes Vite usaba la API antigua de Sass; ahora la moderna es la predeterminada. Si la compilación de Sass falla, puedes desactivarla en la configuración:
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
api: 'legacy' // Si la API moderna da problemas, vuelve a la antigua
}
}
}
})
Mejoras en JSON stringify. Vite detecta el contenido de los archivos JSON: si todo el archivo es un objeto estático, lo preprocesa con JSON.stringify(). Eso reduce el tamaño del bundle, sobre todo en JSON de configuración grandes.
Cambios en las opciones de Worker. El valor por defecto de worker.format pasó de 'iife' a 'es', generando Workers en formato ESM. Así Worker y código principal comparten el mismo sistema de módulos.
En el día a día no cambia mucho. Pero lo de Sass sí merece atención: en un proyecto mío fallaron funciones Sass personalizadas y tardé un buen rato en ver que era un tema de versión de API.
Capítulo 2: integración con Rolldown y salto de rendimiento
2.1 Por qué Vite necesita Rolldown
Un dolor de cabeza clásico: Vite 5 usa esbuild en desarrollo y Rollup en producción. Dos bundlers distintos.
¿Qué implica? En dev va volando: esbuild está en Go y aplasta a las herramientas en JavaScript. En producción entra Rollup, escrito en JavaScript, bastante más lento.
Peor aún: el sistema de plugins. La API de plugins de esbuild no tiene nada que ver con la de Rollup. Un plugin que funciona en dev puede fallar en el build, y al revés. Esa inconsistencia hace que depurar sea un infierno: en dev todo bien, compilas y explota.
Rolldown existe para resolver eso.
¿Qué es Rolldown? Un sustituto de Rollup escrito en Rust, compatible con su API de plugins, pero entre 10 y 30 veces más rápido (fuente: benchmarks oficiales de Rolldown). También alcanza velocidades de compilación al nivel de esbuild.
El plan del equipo de Vite: que Rolldown reemplace a Rollup y unifique la lógica de empaquetado en producción. Dev y prod compartirían el mismo sistema de plugins y desaparecerían muchos casos de «funciona en dev, falla en prod».
2.2 Datos de rendimiento de Rolldown
Los números pesan más que las palabras. El anuncio de Vite 8 Beta mostró varios casos:
| Proyecto | Cambio en tiempo de build | Notas |
|---|---|---|
| Linear | 46 s → 6 s | 87 % de mejora, citado en el blog oficial |
| Ramp | 57 % menos | Monorepo grande |
| Mercedes-Benz.io | 38 % menos | Sitio enterprise |
| Beehiiv | 64 % menos | Plataforma de contenido |
Todos los datos provienen del blog oficial de Vite 8 Beta.
Vite 8 Beta también anunció las ganancias esperadas del Full Bundle Mode:
- Arranque del servidor de desarrollo 3 veces más rápido
- Recarga completa de página 40 % más rápida
- 10 veces menos peticiones de red
¿Qué es Full Bundle Mode? En pocas palabras: en desarrollo también se empaqueta con un bundler, en lugar del modo anterior de «pides un archivo y se compila uno». Ventaja: arranque y recarga más rápidos. Inconveniente: el primer arranque puede ser un poco más lento porque empaqueta todo el proyecto.
Esos números asustan un poco. ¿10x? ¿30x? En un monorepo real de más de 3000 archivos, el build con Vite 5 tardaba unos 90 segundos; con Rolldown bajó a 12. Unas 7 veces. No llega a 10, pero sigue siendo una sorpresa agradable.
2.3 Cómo activar Rolldown (rolldown-vite)
Ahora hay dos formas de usar Rolldown:
Opción 1: el paquete rolldown-vite
Sustituye directamente el paquete vite por rolldown-vite:
// package.json
{
"dependencies": {
"rolldown-vite": "latest"
}
}
Y actívalo en vite.config.ts:
export default defineConfig({
build: {
rolldown: true
}
})
Sirve para probar rápido. rolldown-vite cambia Rollup por Rolldown automáticamente y la compatibilidad de plugins suele ir bien.
Opción 2: esperar a Vite 8 estable
Vite 8 Beta ya integra Rolldown por defecto. Cuando salga la versión estable, basta con actualizar:
npm install vite@8
Vite 8 sigue en Beta (a diciembre de 2025). En producción conviene esperar al release estable o probar rolldown-vite primero en un proyecto de prueba.
La ruta de migración recomendada por el equipo oficial:
- Probar con rolldown-vite y comprobar compatibilidad de plugins
- Si todo va bien, actualizar a Vite 8 estable cuando salga
- Si algún plugin no es compatible, desactivar Rolldown temporalmente y seguir con Rollup clásico
2.4 advancedChunks sustituye a manualChunks
Rolldown introduce una estrategia nueva de chunks: advancedChunks. Es mucho más flexible que manualChunks de Rollup.
Así se escribía manualChunks en Rollup:
// Rollup manualChunks (forma antigua)
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor': ['react', 'react-dom', 'lodash'],
'utils': ['axios', 'dayjs']
}
}
}
}
})
El problema: tienes que indicar a mano qué paquete va en cada chunk. Añades una dependencia, te olvidas de meterla en la config y acaba en el bundle principal.
advancedChunks de Rolldown usa el concepto de grupos:
// Rolldown advancedChunks (forma nueva)
export default defineConfig({
build: {
advancedChunks: {
groups: [
{
name: 'vendor-react',
test: /react|react-dom/,
priority: 10
},
{
name: 'vendor-utils',
test: /lodash|axios|dayjs/,
priority: 5
},
{
name: 'vendor-shared',
test: /[\\/]node_modules[\\/]/,
priority: 1
}
]
}
}
})
Los grupos con mayor prioridad coinciden primero. Lo que no encaja va al fallback (el último grupo catch-all). Ventaja: no tienes que tocar la config cada vez que añades una dependencia; las expresiones regulares hacen el match.
Otra función interesante: advancedChunks puede detectar dependencias duplicadas. Si dos chunks referencian el mismo paquete, lo extrae automáticamente a un chunk compartido. En monorepos ayuda mucho: varios subproyectos suelen compartir las mismas librerías base; antes había que gestionarlo a mano, ahora es automático.
Capítulo 3: evolución de la federación de módulos ESM
3.1 Solución comunitaria: vite-plugin-federation
Module Federation es la función estrella de Webpack 5. En proyectos grandes con varios equipos puedes empaquetar módulos como «federaciones» independientes y consumir código entre ellas. Suena bien, pero Vite no lo soporta de forma nativa.
¿Cómo lo resolvió la comunidad? Con vite-plugin-federation. El plugin tiene más de 3000 stars en GitHub y es hoy la solución más madura de federación de módulos para Vite.
La configuración se parece a la de Webpack:
// vite.config.ts - aplicación Host
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
federation({
name: 'host-app',
remotes: {
remoteApp: 'http://localhost:5001/assets/remoteEntry.js'
},
shared: ['react', 'react-dom']
})
]
})
// vite.config.ts - aplicación Remote
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
plugins: [
federation({
name: 'remote-app',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button',
'./Header': './src/components/Header'
},
shared: ['react', 'react-dom']
})
]
})
La aplicación host referencia módulos remotos con remotes; la remote los exporta con exposes. shared comparte dependencias base y evita empaquetarlas dos veces.
Ventajas de esta solución:
- Compatible con Webpack Module Federation; puede interoperar con proyectos Webpack
- Configuración sencilla, mismos conceptos que Webpack
- Comunidad madura, con casos reales documentados
Los inconvenientes también son claros:
- No es funcionalidad nativa de Vite; el plugin puede dar problemas de compatibilidad
- En producción el empaquetado usa Rollup, no idéntico a la lógica de Webpack
- Depurar es complejo; los errores entre proyectos cuestan de localizar
3.2 Module Federation nativo en Rolldown
Buenas noticias: Rolldown está implementando soporte nativo de Module Federation.
Existe el repositorio de ejemplo rolldown-vite-module-federation-example, que muestra cómo usar federación de módulos en Rolldown. Sigue en fase RC; no lo recomiendo para producción todavía.
La solución nativa de Rolldown tiene varias ventajas:
- Totalmente compatible con la API de Module Federation de Webpack 5
- Lógica de empaquetado unificada, sin saltar entre Vite y Webpack
- Mejor rendimiento: Rolldown ya es más rápido que Rollup
La configuración sigue evolucionando; por ahora se ve así:
// Rolldown Module Federation (versión RC)
export default defineConfig({
build: {
moduleFederation: {
name: 'host-app',
remotes: {
remoteApp: 'remoteApp@http://localhost:5001/remoteEntry.js'
},
exposes: {
'./Component': './src/Component.tsx'
},
shared: {
react: { singleton: true },
reactDom: { singleton: true }
}
}
}
})
La sintaxis es parecida a vite-plugin-federation, pero más cercana a la especificación de Webpack. singleton: true garantiza una sola versión cargada y evita conflictos.
3.3 Cómo elegir solución
¿Qué opción usar ahora para federación de módulos?
Proyectos en producción: recomiendo vite-plugin-federation.
La razón es simple: estabilidad. Más de 3000 stars significa que muchos equipos ya la usan y los problemas típicos están documentados. Si algo falla, suele haber solución en la comunidad.
Proyectos nuevos o experimentales: puedes probar la solución nativa de Rolldown.
Si ya usas Rolldown o el proyecto aún no está en producción, tiene sentido experimentar. Pero prepárate para volver atrás: la API en RC puede cambiar.
Interoperar con proyectos Webpack: ambas opciones valen.
vite-plugin-federation nació pensando en compatibilidad con Webpack. La solución nativa de Rolldown también promete compatibilidad con Webpack 5.
Dicho esto, la federación de módulos no es una panacea. Encaja en proyectos grandes con varios equipos o microfrontends con despliegues independientes. En proyectos normales añade complejidad: hay que mantener los límites de la federación, coordinar versiones y depurar referencias entre repos.
Si tu proyecto no es tan complejo, no te precipites. Un monorepo simple o paquetes npm compartidos pueden bastar.
Capítulo 4: buenas prácticas de optimización de rendimiento
Vite 6 ya es rápido. Pero si mantienes un proyecto grande —miles de archivos, decenas de dependencias— aún puedes exprimir más.
4.1 Precalentar archivos frecuentes (warmup)
Al arrancar el servidor de desarrollo, Vite precalienta algunos archivos habituales. Por defecto entra el archivo de entrada y sus dependencias. Puedes indicar más a mano:
export default defineConfig({
server: {
warmup: {
clientFiles: [
'./src/main.tsx',
'./src/pages/Home.tsx',
'./src/pages/Dashboard.tsx'
]
}
}
})
La ventaja: esos archivos ya están compilados antes de abrir el navegador. La primera visita no se nota lenta.
¿Qué archivos merece la pena precalentar?
- El de entrada (Vite ya lo hace por defecto)
- Componentes de páginas que visitas mucho
- Entradas de librerías grandes (por ejemplo,
lodash-es)
No abuses. Demasiados archivos en warmup alarga el arranque. Con 5-10 de los que más uses suele bastar.
4.2 Evitar barrel files
¿Qué es un barrel file? Un archivo que reexporta un montón de módulos:
// ❌ Barrel file: evítalo
export { Button } from './Button'
export { Input } from './Input'
export { Modal } from './Modal'
export { Table } from './Table'
Parece ordenado: un solo import trae todos los componentes:
import { Button, Input, Modal } from './components'
Pero Vite los trata de forma poco eficiente: carga todo el barrel y luego cada módulo exportado. Se forma una cascada de peticiones —una dispara la siguiente, y otra más.
En proyectos grandes un barrel puede exportar decenas de módulos y la cascada puede costar varios segundos.
Lo correcto es importar directamente:
// ✅ Importación directa
import Button from './components/Button'
import Input from './components/Input'
Vite puede cargar esos módulos en paralelo. Sin cascada, mucho más rápido.
Si quieres barrel files por orden en el código, plantéate el Full Bundle Mode de Rolldown. En modo bundle la cascada desaparece: todo queda en uno o pocos archivos y no hay cadena de peticiones.
4.3 Reducir operaciones de resolve
Cada vez que Vite procesa un import hace resolve: encontrar la ruta real del archivo. Eso implica mirar node_modules, probar extensiones y resolver alias.
Menos resolves, compilación más rápida.
Escribe la extensión de forma explícita:
// ❌ Extensión implícita
import Button from './components/Button'
// ✅ Extensión explícita
import Button from './components/Button.tsx'
Con la extensión clara, Vite no tiene que probar .ts, .tsx, .js, .jsx, etc.
Reduce alias de rutas:
// vite.config.ts
export default defineConfig({
resolve: {
alias: {
'@': '/src',
'@components': '/src/components',
'@utils': '/src/utils',
'@hooks': '/src/hooks',
'@api': '/src/api'
}
}
})
Cada alias suma trabajo al resolve. Mejor quedarse con uno o dos principales (como @) y usar rutas relativas para el resto.
4.4 Plugins nativos y Oxc Transform
Vite 6 añade soporte de plugins nativos. Los plugins en Rust son mucho más rápidos que los de JavaScript.
Para activarlos:
export default defineConfig({
experimental: {
enableNativePlugin: true
}
})
Sigue en fase experimental; la mayoría de plugins aún no soportan el modo nativo.
Otro punto a seguir es Oxc Transform. Oxc es una cadena de herramientas de compilación JS/TS en Rust. @vitejs/plugin-react v5+ usa por defecto el transform de Oxc, bastante más rápido que Babel.
Si usas el plugin de React, actualiza a v5+:
{
"dependencies": {
"@vitejs/plugin-react": "^5.0.0"
}
}
El transform de Oxc no cubre todas las funciones de Babel (por ejemplo, plugins Babel personalizados). Si tienes configuración Babel especial, puede que debas forzar Babel en el plugin:
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
react({
babel: {
// Forzar Babel
plugins: ['your-babel-plugin']
}
})
]
})
Conclusión
En resumen, van unas pocas ideas centrales:
Environment API cambió la arquitectura de Vite, pero en proyectos normales el impacto es limitado. Sobre todo beneficia a autores de frameworks y, de rebote, te da más opciones de despliegue.
Rolldown es el salto de rendimiento de verdad. Más de 10 veces en el build, sistema de plugins unificado, coherencia entre dev y prod: mejoras tangibles. Linear de 46 s a 6 s no es marketing.
La federación de módulos ESM sigue evolucionando. La solución comunitaria es madura; la oficial sigue en RC. En microfrontends puedes empezar con vite-plugin-federation y cambiar cuando la opción nativa de Rolldown se estabilice.
La optimización pasa por reducir cascadas, precalentar archivos frecuentes y bajar resolves. El Full Bundle Mode de Rolldown cambiará muchas estrategias: en modo bundle, el bundler resuelve gran parte de esos problemas solo.
Recomendaciones de migración:
- Producción: prueba compatibilidad con
rolldown-vitey actualiza a Vite 8 estable cuando salga - Proyectos nuevos: puedes ir directo a Vite 8 Beta y aprovechar el rendimiento de Rolldown
- Microfrontends: usa
vite-plugin-federationhasta que la solución nativa de Rolldown esté estable
La cadena de herramientas de Vite evoluciona rápido: de esbuild + Rollup a Rolldown unificado, de federación compatible con Webpack a soporte nativo. Son cambios importantes en la infraestructura frontend. Mantente al día, actualiza cuando toque y tu proyecto irá más rápido y más estable.
FAQ
¿Qué impacto tiene Environment API de Vite 6 en proyectos normales?
¿Rolldown puede acelerar el build 10 veces de verdad?
¿Qué solución de Module Federation conviene usar ahora?
¿Qué hay que tener en cuenta al actualizar a Vite 6?
¿Qué trucos prácticos de optimización ofrece Vite 6?
¿Cuándo tiene sentido usar Module Federation?
14 min de lectura · Publicado el: 18 abr 2026 · Actualizado el: 21 ago 2026



Comentarios
Inicia sesión con GitHub para dejar un comentario