Migración desde v4
Soporte de Node.js
Vite ya no es compatible con Node.js 14/16/17/19, versiones que alcanzaron su final de soporte. Ahora se requiere Node.js 18/20+.
Rollup 4
Vite ahora está usando Rollup 4, que también trae consigo sus cambios importantes, en particular:
- Se ha cambiado el nombre de importar aserciones (propiedad
assertions) a importar atributos (propiedadattributes). - Los plugins de Acorn ya no son compatibles.
- Para los plugins de Vite, la opción
this.resolveskipSelfahora estruepor defecto. - Para los plugins de Vite,
this.parseahora solo soporta la opciónallowReturnOutsideFunctionpor ahora.
Lee los cambios importantes completos en las notas de la versión de Rollup para conocer los cambios relacionados con la compilación en build.rollupOptions.
Si estás utilizando TypeScript, asegúrate de configurar moduleResolution: 'bundler' (o node16/nodenext) ya que Rollup 4 lo requiere. O puedes configurar skipLibCheck: true en su lugar.
API de Node para la compilación CJS de Vite, ahora obsoleta
La API de Node para la compilación CJS de Vite ahora está en desuso. Al llamar a require('vite'), ahora se registra una advertencia de obsolescencia. En su lugar, debes actualizar tus archivos o frameworks para importar la compilación ESM de Vite.
En un proyecto básico de Vite, asegúrate que:
- El contenido del archivo
vite.config.jsutiliza la sintaxis ESM. - El archivo
package.jsonmás cercano tiene"type": "module", o usa la extensión.mjs/.mts, por ejemplo,vite.config.mjsovite.config.mts.
Para otros proyectos, existen algunos enfoques generales:
- Configura ESM como predeterminado, optar por CJS si es necesario: Agrega
"type": "module"en elpackage.jsondel proyecto. Todos los archivos*.jsahora se interpretan como ESM y deben utilizar la sintaxis de ESM. Puedes cambiar el nombre de un archivo con la extensión.cjspara seguir usando CJS. - Mantén CJS como predeterminado, optar por ESM si es necesario: Si el
package.jsondel proyecto no tiene"type": "module", todos los archivos*.jsse interpretan como CJS. Puedes cambiar el nombre de un archivo con la extensión.mjspara usar ESM en su lugar. - Importar Vite dinámicamente: Si necesitas seguir usando CJS, puedes importar Vite dinámicamente usando
import('vite')en su lugar. Esto requiere que tu código esté escrito en un contexto "asíncrono", pero aún así debería ser manejable ya que la API de Vite es en su mayoría asíncrona.
Consulta la guía de solución de problemas para obtener más información.
Reelaborada la estrategia de reemplazo de define e import.meta.env.*
En Vite 4, las funciones define e import.meta.env.* utilizan diferentes estrategias de reemplazo en desarrollo y compilación:
- En desarrollo, ambas funciones se inyectan como variables globales en
globalThiseimport.metarespectivamente. - En la compilación, ambas funciones se reemplazan estáticamente con una expresión regular.
Esto da como resultado una inconsistencia en el desarrollo y la compilación al intentar acceder a las variables y, a veces, incluso provoca compilaciones fallidas. Por ejemplo:
// vite.config.js
export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify('1.0.0'),
},
})const data = { __APP_VERSION__ }
// dev: { __APP_VERSION__: "1.0.0" } ✅
// build: { "1.0.0" } ❌
const docs = 'Me gusta import.meta.env.MODE'
// dev: "Me gusta import.meta.env.MODE" ✅
// build: "Me gusta "production"" ❌Vite 5 soluciona este problema usando esbuild para manejar los reemplazos en las compilaciones, alineándose con el comportamiento de desarrollo.
Este cambio no debería afectar a la mayoría de las configuraciones, de hecho ya está documentado que los valores define deben seguir la sintaxis de esbuild:
Para ser coherente con el comportamiento de esbuild, las expresiones deben ser un objeto JSON (null, Boolean, number, string, array, o object) o un único identificador.
Sin embargo, si prefieres que se sigan reemplazado valores estáticamente de forma directa, puedes usar @rollup/plugin-replace.
Cambios generales
El valor de los módulos externalizados SSR ahora coincide con producción
En Vite 4, los módulos externalizados de SSR están empaquetados con el manejo .default y .__esModule para una mejor interoperabilidad, pero no coinciden con el comportamiento en producción cuando se cargan mediante el entorno de ejecución (por ejemplo, Node.js), lo que genera dificultades para depurar inconsistencias. Por defecto, todas las dependencias directas del proyecto están externalizadas por SSR.
Vite 5 ahora elimina el manejo de .default y .__esModule para que coincida con el comportamiento de producción. En la práctica, esto no debería afectar las dependencias empaquetadas correctamente, pero si encuentras nuevos problemas al cargar módulos, puedes probar estas reescrituras:
// Antes:
import { foo } from 'bar'
// Después:
import _bar from 'bar'
const { foo } = _bar// Antes:
import foo from 'bar'
// Después:
import * as _foo from 'bar'
const foo = _foo.defaultTen en cuenta que estos cambios coinciden con el comportamiento de Node.js, por lo que también puedes ejecutar las importaciones en Node.js para probarlo. Si prefieres seguir con el comportamiento anterior, puedes configurar legacy.proxySsrExternalModules en true.
worker.plugins ahora es una función
En Vite 4, worker.plugins aceptaba una serie de plugins ((Plugin | Plugin[])[]). Desde Vite 5, debe configurarse como una función que devuelve una serie de plugins (() => (Plugin | Plugin[])[]). Este cambio es necesario para que las compilaciones paralelas de workers se ejecuten de manera más consistente y predecible.
Habilitado que las rutas que contienen . recurran a index.html
En Vite 4, acceder a una ruta en dev que contenía . no recurría a index.html incluso si appType estaba configurado en 'spa' (predeterminado). Desde Vite 5, recurrirá a index.html.
Ten en cuenta que el navegador ya no mostrará un mensaje de error 404 en la consola si apuntas la ruta de la imagen a un archivo inexistente (por ejemplo, <img src="./file-does-not-exist.png">).
Alineado el comportamiento de servido HTML para desarrollo y vista previa
En Vite 4, los servidores de desarrollo y vista previa sirven HTML según su estructura de directorio y barra diagonal de manera diferente. Esto provoca inconsistencias al probar la aplicación creada. Vite 5 se refactoriza en un solo comportamiento como se muestra a continuación, dada la siguiente estructura de archivos:
├── index.html
├── file.html
└── dir
└── index.html| Solicitud | Antes (desarrollo) | Después (vista previa) | Después (desarrollo y vista previa) |
|---|---|---|---|
/dir/index.html | /dir/index.html | /dir/index.html | /dir/index.html |
/dir | /index.html (redirección SPA) | /dir/index.html | /index.html (redirección SPA) |
/dir/ | /dir/index.html | /dir/index.html | /dir/index.html |
/file.html | /file.html | /file.html | /file.html |
/file | /index.html (redirección SPA) | /file.html | /file.html |
/file/ | /index.html (redirección SPA) | /file.html | /index.html (redirección SPA) |
Los archivos de manifiesto ahora se generan en el directorio .vite por defecto
En Vite 4, los archivos de manifiesto (build.manifest y build.ssrManifest) se generaban en la raíz de build.outDir por defecto.
A partir de Vite 5, se generarán en el directorio .vite en build.outDir por defecto. Este cambio ayuda a eliminar el conflicto de archivos públicos con los mismos nombres de los archivos de manifiesto cuando se copian en build.outDir.
Los archivos CSS correspondientes no se listan como entrada de nivel superior en el archivo manifest.json
En Vite 4, el archivo CSS correspondiente a un punto de entrada de JavaScript también se listaba como una entrada de nivel superior en el archivo de manifiesto (build.manifest). Estas entradas se agregaban involuntariamente y solo funcionaban para casos simples.
En Vite 5, los archivos CSS correspondientes solo se pueden encontrar dentro de la sección del archivo JavaScript de entrada. Cuando se inyecta el archivo JS, los archivos CSS correspondientes deben ser inyectados. Cuando el CSS debe ser inyectado por separado, debe agregarse como una entrada separada.
Los accesos directos de CLI requieren una pulsación adicional de "Intro"
Los atajos del CLI, como r para reiniciar el servidor de desarrollo, ahora requieren presionar un Enter adicional para activar el atajo. Por ejemplo, r + Enter para reiniciar el servidor de desarrollo.
Este cambio evita que Vite absorba y controle accesos directos específicos del sistema operativo, lo que permite una mejor compatibilidad al combinar el servidor de desarrollo de Vite con otros procesos y evita las advertencias anteriores.
Actualizado el comportamiento de TypeScript experimentalDecorators y useDefineForClassFields
Vite 5 usa esbuild 0.19 y elimina la capa de compatibilidad para esbuild 0.18, lo que cambia la forma en que se manejan experimentalDecorators y useDefineForClassFields.
experimentalDecoratorsno está habilitado por defectoDebes configurar
compilerOptions.experimentalDecoratorsentrueentsconfig.jsonpara usar los decoradores.Los valores por defecto de
useDefineForClassFieldsdependen del valortargetde TypeScriptSi
targetno esESNextoES2022o más reciente, o si no hay un archivotsconfig.json,useDefineForClassFieldspor defecto seráfalse, lo que puede ser problemático con el valor por defecto deesbuild.targetdeESNext. Puede transpilarse a bloques de inicialización estáticos que pueden no ser compatibles con tu navegador.Como tal, se recomienda configurar
targetenESNextoES2022o más reciente, o configuraruseDefineForClassFieldsentrueexplícitamente en eltsconfig.json.
{
"compilerOptions": {
// Configurar en true si deseas usar decoradores
"experimentalDecorators": true,
// Configurar en true si ves errores de análisis en tu navegador
"useDefineForClassFields": true
}
}Eliminada los indicadores --https y https: true
El indicador --https configura server.https: true y preview.https: true internamente. Esta configuración estaba destinada a usarse junto con la función de generación automática de certificación https que se eliminó en Vite 3. Esto indica que dicha configuración ya no es útil, ya que iniciará un servidor HTTPS de Vite sin un certificado.
Si usas @vite/plugin-basic-ssl o vite-plugin-mkcert, estas configurarán https internamente, por lo que puedes eliminar --https, server.https: true y preview.https: true.
Eliminadas las APIs resolvePackageEntry y resolvePackageData
Las APIs resolvePackageEntry y resolvePackageData se eliminan ya que exponían componentes internos de Vite y bloqueaban posibles optimizaciones de Vite 4.3 en el pasado. Estas APIs se pueden reemplazar con paquetes de terceros, por ejemplo:
resolvePackageEntry:import.meta.resolveo el paqueteimport-meta-resolve.resolvePackageData: igual que arriba, rastreando el directorio del paquete para obtener la ruta raíz depackage.json. O utiliza el paquete de la comunidadvitefu.
import { resolve } from 'import-meta-resolve'
import { findDepPkgJsonPath } from 'vitefu'
import fs from 'node:fs'
const pkg = 'my-lib'
const basedir = process.cwd()
// `resolvePackageEntry`:
const packageEntry = resolve(pkg, basedir)
// `resolvePackageData`:
const packageJsonPath = findDepPkgJsonPath(pkg, basedir)
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))APIs obsoletas eliminadas
- Exportaciones predeterminadas de archivos CSS (por ejemplo,
import style from './foo.css'): usa la consulta?inlineen su lugar import.meta.globEager: usaimport.meta.glob('*', { eager: true })en su lugarssr.format: 'cjs' ylegacy.buildSsrCjsExternalHeuristics(#13816)server.middlewareMode: 'ssr'yserver.middlewareMode: 'html': UsaappType+server.middlewareMode: trueen su lugar (#8452)
Avanzado
Hay algunos cambios que solo afectan a los creadores de plugins/herramientas.
- [#14119] refactor!: fusiona
PreviewServerForHooken el tipoPreviewServer- El hook
configurePreviewServerahora acepta el tipoPreviewServeren lugar del tipoPreviewServerForHook.
- El hook
- [#14818] refactor(preview)!: usa middleware base
- Los middlewares agregados desde la función devuelta en
configurePreviewServerahora no tienen acceso abaseal comparar el valorreq.url. Esto alinea el comportamiento con el del servidor de desarrollo. Puedes verificarbasedesde el hookconfigResolvedsi es necesario.
- Los middlewares agregados desde la función devuelta en
- [#14834] fix(types)!: expone httpServer con la unión Http2SecureServer
- Ahora se utiliza
http.Server | http2.Http2SecureServeren lugar dehttp.Servercuando sea apropiado.
- Ahora se utiliza
También hay otros cambios importantes que sólo afectan a unos pocos usuarios.
- [#14098] fix!: evita reescribir esto (revierte #5312)
- El nivel superior "this" se reescribía a "globalThis" por defecto durante la compilación. Este comportamiento ahora se elimina.
- [#14231] feat!: agrega extensión a los módulos virtuales internos
- La identificación de los módulos virtuales internos ahora tiene una extensión (
.js).
- La identificación de los módulos virtuales internos ahora tiene una extensión (
- [#14583] refactor!: elimina APIs internas de exportación
- Se eliminaron las APIs internas exportadas accidentalmente:
isDepsOptimizerEnabledygetDepOptimizationConfig - Se eliminaron los tipos internos exportados:
DepOptimizationResult,DepOptimizationProcessingyDepsOptimizer. - Se cambió el nombre del tipo
ResolveWorkerOptionsaResolvedWorkerOptions
- Se eliminaron las APIs internas exportadas accidentalmente:
- [#5657] fix: devuelve 404 para solicitudes de recursos fuera de la ruta base
- En el pasado, Vite respondía a solicitudes fuera de la ruta base sin
Accept: text/html, como si fueran solicitadas con la ruta base. Vite ya no hace eso y responde con 404.
- En el pasado, Vite respondía a solicitudes fuera de la ruta base sin
- [#14723] fix(resolve)!: elimina el manejo especial de .mjs
- En el pasado, cuando un campo
"export"de librería se asignaba a un archivo.mjs, Vite aún intentaba hacer coincidir los campos"browser"y"module"para corregir la compatibilidad con ciertas librerías. Este comportamiento ahora se elimina para alinearse con el algoritmo de resolución de exportaciones.
- En el pasado, cuando un campo
- [#14733] feat(resolve)!: elimina
resolve.browserFieldresolve.browserFieldha sido marcado como obsoleto desde Vite 3 en favor de una actualización de valores por defecto de['browser', 'module', 'jsnext:main', 'jsnext']pararesolve.mainFields.
- [#14855] feat!: agrega isPreview a ConfigEnv y resolveConfig
- Se cambió el nombre de
ssrBuildaisSsrBuilden el objetoConfigEnv.
- Se cambió el nombre de
- [#14945] fix(css): Configura correctamente el nombre fuente del manifiesto y emite el archivo CSS
- Los nombres de los archivos CSS ahora se generan en función del nombre del fragmento (chunk).
Migración desde v3
Consulta primero la Guía de migración desde v3 para ver los cambios necesarios para migrar tu aplicación a Vite v4, y luego continúa con los cambios en esta página.