2 de septiembre de 2026

Vite 8: qué se rompe al actualizar (y por qué ya lo trae Astro 7)

Foto de Marco Orta Marco Orta | 11 min de lectura
Compartir
Un rayo brillante en degradado amarillo a violeta partiéndose por una fisura irregular, con fragmentos flotando lejos
Tabla de Contenidos

    Vite 8 llegó a estable el 12 de marzo de 2026 y reemplaza a Rollup y esbuild por un solo bundler en Rust: Rolldown. Casi todo lo que se rompe lo hace en silencio — sin error rojo, nada más un output distinto. Y aquí está la parte que agarra a la gente en curva: si actualizaste a Astro 7 en cualquier momento después de su lanzamiento de junio de 2026, te llevaste Vite 8 de fábrica, lo hayas pedido o no. Este sitio corre Astro 7.2.2, y su node_modules/astro/package.json fija "vite": "^8.0.13". Si seguiste la migración a Astro 7, este post es la parte que nadie te contó.

    ¿De dónde vienes?

    La lista de abajo aplica distinto según de dónde vengas:

    • Corres Vite directo y ya estás en Vite 7. El caso sencillo. Lee los renombres de config y la sección de interop CJS, corre un build, listo.
    • Estás en Vite 6 o antes. Estás saltando dos majors de cambios de un jalón — la migración a Vite 7 (Node 20.19+, salida ESM) más todo lo de abajo. Hazlo en dos pasos: aterriza primero en 7, verifica, y luego brinca a 8.
    • No tocaste Vite. Actualizaste Astro, Nuxt, SvelteKit u otro meta-framework, y Vite 8 se vino de arrastre. Este es el grupo para el que en realidad es este post. Nadie puso “nuevo bundler” en tu changelog; nada más apareció como una línea de vite en tu package-lock.json. Todo lo de aquí en adelante te aplica igual — nada más no elegiste cuándo.

    Qué cambió de verdad, en una sola tabla

    ÁreaVite 7Vite 8
    Bundler de producciónRollupRolldown (Rust)
    Pre-bundling de dependencias en devesbuildRolldown
    Transform / minify de JSesbuildOxc
    Minify de CSSesbuildLightning CSS
    build.rollupOptionsválidodeprecado, renombrado a build.rolldownOptions
    DistribuciónESMSolo ESM (sin cambio, nada más más estricto)
    Mínimo de Node.js20.19+ / 22.12+igual
    Tamaño de instalaciónbase+~15 MB (binarios nativos)
    build.target por defectoChrome 107, Safari 16.0Chrome 111, Safari 16.4

    El número que se roba el titular es real: el propio anuncio de Vite cita el build de producción de Linear bajando de 46s a 6s, Ramp 57% más rápido, Beehiiv 64%, Mercedes-Benz.io 38%. Eso es lo bueno. El resto de este post es la parte que no sale en el titular del release.

    Rupturas, ordenadas por impacto

    1. Los imports default de CommonJS resuelven distinto — en silencio

    Esta es la que vale la pena leer dos veces, porque no produce ningún error de build. La guía de migración de Vite 8 lo dice claro: el import default de un módulo CJS solía resolver distinto entre dev y build; ahora es consistente, pero la regla cambió. El import default es el valor completo de module.exports solo si se cumple una de estas — el que importa es .mjs/.mts, el package.json más cercano al que importa tiene "type": "module", o la bandera __esModule del módulo CJS no es true. Si no, te toca module.exports.default.

    En la práctica, esto significa que un import que ya funcionaba puede empezar a devolver un objeto envoltorio en vez de la función que esperas:

    // cjs-pkg exporta: module.exports = { __esModule: true, default: function greet() {} }
    
    import greet from 'cjs-pkg';
    greet(); // Vite 7, en dev: funcionaba
              // Vite 8, .js normal sin "type": "module": TypeError: greet is not a function
    

    La válvula de escape es una línea, y te compra tiempo para arreglar imports uno por uno en vez de todos de golpe:

    // vite.config.js
    export default defineConfig({
      legacy: { inconsistentCjsInterop: true }, // restaura el comportamiento viejo e inconsistente
    });
    

    Está marcada como deprecada a propósito — trátala como puente, no como destino final. Si es un paquete de terceros el que dispara esto, la documentación pide reportarlo al autor del paquete con un link a la explicación de interop CJS de Rolldown, no solo parcharlo por siempre.

    2. build.rollupOptions ahora es build.rolldownOptions

    Esta al menos falla lo bastante fuerte como para notarla — una advertencia de deprecación en cada build, todavía no un crash, porque un shim de compatibilidad mantiene viva la llave vieja:

    // Antes (Vite 7)
    export default defineConfig({
      build: {
        rollupOptions: {
          input: { main: './src/main.ts' },
        },
      },
    });
    
    // Después (Vite 8)
    export default defineConfig({
      build: {
        rolldownOptions: {
          input: { main: './src/main.ts' },
        },
      },
    });
    

    worker.rollupOptions recibe el mismo trato (worker.rolldownOptions). Si tienes ambas en una config de monorepo compartida entre paquetes, un grep -rn "rollupOptions" . antes de empezar te encuentra todos los lugares de un jalón.

    3. manualChunks como objeto no está deprecado — está eliminado

    Escondido dentro del renombre de arriba hay un filo más cortante: la forma de objeto de output.manualChunks ya no está soportada, punto. Solo la forma de función sigue funcionando, y también está marcada como deprecada, a favor de la opción propia de Rolldown, codeSplitting.

    // Vite 7 — este patrón aparece seguido en configs reales
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            vendor: ['react', 'react-dom'], // forma de objeto
          },
        },
      },
    },
    
    // Vite 8 — la forma de objeto truena en build; convertir a función es el arreglo mínimo
    build: {
      rolldownOptions: {
        output: {
          manualChunks(id) {
            if (id.includes('node_modules/react')) return 'vendor';
          },
        },
      },
    },
    

    Esta es la que más probablemente rompa tu build de verdad (no nada más avise), porque un montón de configs de Vite copiadas y pegadas usan la forma de objeto para separar vendors.

    4. build.commonjsOptions ahora es un no-op

    Sin advertencia, sin error — nada más se ignora. Si tu config trae build.commonjsOptions.include, .exclude, o .requireReturnsDefault para rodear algún paquete CJS específico, ese parche deja de aplicar en silencio después del upgrade. El síntoma aparece río abajo, en lo que sea que la opción arreglaba, no en la línea de la config — lo que hace fácil culpar a lo que no es.

    5. Node.js 20.19+ / 22.12+ es un piso duro, y es por require(esm)

    Es el mismo requisito de Vite 7, así que si vienes de ahí esto no cambia nada. Pero si brincas desde Vite 6, esto es nuevo: Vite se distribuye solo en ESM, y esas versiones de patch específicas son justo las que soportan require(esm) sin flag — el mecanismo que deja a un toolchain de la era CJS seguir cargando un paquete que solo existe en ESM. Cualquier versión más vieja ni siquiera instala bien, no nada más corre raro.

    6. Yarn PnP: sin veredicto oficial, pero tampoco está sólido

    La documentación de Vite no trae una línea de “Yarn PnP: no soportado”, pero el issue tracker de rolldown-vite tiene varios reportes abiertos de resolución de dependencias fallando específicamente bajo el modo Plug’n’Play de Yarn — paquetes que resuelven bien con node_modules y truenan con Failed to resolve import bajo PnP. Si tu equipo corre Yarn Berry con nodeLinker: pnp, trata a Vite 8 como “prueba en una rama antes de tocar CI”, no como un reemplazo seguro todavía.

    7. El tamaño de instalación crece unos 15 MB

    Confirmado en el anuncio de la release: cerca de 10 MB de Lightning CSS (ahora el minificador de CSS por defecto, ya no opcional) y cerca de 5 MB del binario nativo de Rolldown. Nada se rompe funcionalmente, pero si construyes imágenes Docker con presupuesto de capas apretado o metes node_modules completo en un bundle de Lambda, es una línea real que vale la pena revisar — y aplica aunque nunca toques Vite directamente, porque viaja de polizón como dependencia de Astro (o Nuxt, o SvelteKit).

    8. Los targets de navegador por defecto subieron — y los navegadores viejos fallan sin avisar en el build

    Los valores por defecto de build.target subieron: Chrome 107→111, Edge 107→111, Firefox 104→114, Safari 16.0→16.4, alineados a Baseline Widely Available de enero de 2026. Vite compila sin quejarse de cualquier forma — la falla, si la tienes, aparece como JavaScript roto en un Safari viejo dentro del analytics de producción de alguien, semanas después, sin nada en tu log de build que señale la causa. Si tienes una matriz de soporte de navegadores documentada que incluya algo más viejo que Safari 16.4, fija build.target a mano en vez de confiar en el default.

    9. Los plugins en general nada más funcionan — con dos excepciones reales

    Rolldown implementa la misma API de plugins que Rollup, y los plugins de framework que importan ya están al día: @vitejs/plugin-react v6 usa Oxc en vez de Babel para el transform de Refresh (la v5 sigue corriendo bien en Vite 8 si todavía no la actualizas), y @vitejs/plugin-vue no necesita cambios. Donde sí se rompe de verdad:

    • Plugins que dependen del hook moduleParsed: está documentado que no se llama en dev en absoluto, para evitar un parse completo de AST en cada archivo.
    • Plugins construidos contra el formato propio de esbuild (onLoad/onResolve, no el de Rollup) — esa es una API completamente distinta y Rolldown no la habla. Si el README de un plugin menciona “esbuild plugin”, busca un reemplazo nativo de Rolldown antes de asumir que se actualiza gratis.

    ¿Cuándo conviene actualizar?

    Corres Vite directo, ya en 7, sin dependencias CJS exóticas: actualiza ya. La ganancia en tiempo de build es real y la superficie de ruptura es chica si no dependes de manualChunks como objeto.

    Estás en Vite 6: pasa por 7 primero. Vite mantiene un paquete rolldown-vite que es “Vite 7 con Rolldown, nada más” pensado como paso intermedio — úsalo para aislar el cambio de bundler del salto de versión.

    Llegaste aquí vía Astro 7 (o Nuxt, SvelteKit, similar): ya lo estás corriendo. La movida no es “¿le entro?” — es auditar tu vite.config existente en busca de rollupOptions.output.manualChunks como objeto y cualquier override de commonjsOptions, porque esas son las dos que fallan o se apagan en silencio sin que hayas tocado la versión del framework para nada.

    Tu equipo corre Yarn PnP: espera, o fija [email protected] y vigila los issues abiertos antes de moverte a Vite 8 de verdad.

    Mantienes un plugin de Rollup con uso pesado de moduleParsed o de hooks de output: presupuesta tiempo real, no un ajuste de config — es un problema de forma de API, no un renombre.

    Para seguir:

    Preguntas frecuentes

    Compartir

    Buscar

    Etiquetas

    PHP Laravel IA Tutorial JavaScript Migración Desarrollo Web Buenas Prácticas Upgrade Seguridad Laravel 13 Backend SEO Claude Herramientas