Skip to content

Para Além da Rapidez

ViteConf 2023

Assistir a repetição!

Migração da Versão 4

Suporte da Node.js

A Vite já não suporta a Node.js 14 / 16 / 17 / 19, as quais alcançaram o fim da sua expetativa de vida. A Node.js 18 / 20+ agora é obrigatória.

Rollup 4

A Vite agora usa Rollup 4 que também vem com suas mudanças de rutura, em particular:

  • As asserções de importação (propriedade assertions) foram renomeada para importar atributos (propriedade attributes).
  • As extensão da bolota já não são suportados.
  • Para extensões da Vite, a opção skipSelf de this.resolve agora é true por padrão.
  • Para extensão da Vite, this.parse agora apenas suportam a opção allowReturnOutsideFunction por agora.

Leia as mudanças de rutura completa nas notas de lançamento do Rollup por mudanças relacionadas à construção no build.rollupOptions.

Se estivermos usando a TypeScript, devemos certificar-nos de definir moduleResolution: 'bundler' (ou node16/nodenext) conforme a Rollup 4 o exige. Ou podemos definir skipLibCheck: true.

Depreciação da API da Node de CJS

A API da Node de CJS da Vite está depreciada. Quando chamamos require('vite'), um aviso de depreciação agora é registado. Nós devemos atualizar os nossos ficheiros ou abstrações para importar a construção de módulo de ECMAScript da Vite.

Num projeto de Vite básico, devemos certificar-nos de que:

  1. O conteúdo do ficheiro vite.config.js está a usar a sintaxe de módulo de ECMAScript.
  2. O ficheiro package.json mais próximo tem "type": "module", ou devemos usar a extensão .mjs ou .mts, por exemplo vite.config.mjs ou vite.config.mts.

Para outros projetos, existem algumas abordagens gerais:

  • Configurar o ESM como padrão, aderir à CJS se necessário: Adicionar "type": "module" no projeto package.json. Todos os ficheiros *.js agora são interpretados como módulo ECMAScript e precisa usar a sintaxe da módulo ECMAScript. Nós podemos renomear um ficheiro com a extensão .cjs para manter usando CJS.
  • Manter CJS como padrão, aderir à módulo de ECMAScript se necessário: Se o package.json do projeto não tem "type":"module", todos os ficheiros *.js são interpretados como CJS. Nós podemos renomear um ficheiro com a extensão .mjs para usar módulo de ECMAScript.
  • Importar dinamicamente a Vite: Se precisarmos de continuar a usar CJS, podemos importar dinamicamente a Vite usando import('vite'). Isto exige que o nosso código seja escrito num contexto async, mas ainda assim deve ser gerenciável como API da Vite é principalmente assíncrona.

Consulte o guia de resolução de problemas por mais informação.

Retrabalhar a Estratégia de Substituição de define e import.meta.env

Na Vite 4, as funcionalidades define e import.meta.env usam diferentes estratégias de substituição no desenvolvimento e na construção:

  • No desenvolvimento, ambas funcionalidades são injetadas como variáveis globais ao globalThis e import.meta respetivamente.
  • Na construção, ambas funcionalidades são estaticamente substituídas por uma expressão regular.

Isto resulta num inconsistência de desenvolvimento e construção quando tentamos acessar as variáveis, e algumas vezes até levava a construção à falhar. Por exemplo:

js
// vite.config.js
export default defineConfig({
  define: {
    __APP_VERSION__: JSON.stringify('1.0.0'),
  },
})
js
const data = { __APP_VERSION__ }
// dev: { __APP_VERSION__: "1.0.0" } ✅
// build: { "1.0.0" } ❌

const docs = 'I like import.meta.env.MODE'
// dev: "I like import.meta.env.MODE" ✅
// build: "I like "production"" ❌

A Vite 5 corrige isto usando a esbuild para lidar com as substituições nas construções, alinhando com o comportamento do desenvolvimento.

Esta mudança não deve afetar a maioria das configurações, uma vez que já é documentado que os valores de define seguem a sintaxe da esbuild:

Para ser consistente com o comportamento da esbuild, expressões devem ou ser um objeto de JSON (null, boolean, number, string, array, ou object) ou um único identificador.

No entanto, se preferirmos continuar à estaticamente substituir os valores diretamente, podemos usar @rollup/plugin-replace.

Mudanças Gerais

O Valor dos Módulos Expostos da Interpretação do Lado do Servidor agora Corresponde à Produção

Na Vite 4, os módulos expostos da interpretação do lado do servidor são embrulhados com .default e a manipulação de __esModule para melhor interoperabilidade, mas não corresponde o comportamento de produção quando carregado pelo ambiente de execução (por exemplo, Node.js), causando incoerências difíceis de detetar. Por padrão, todas as dependências diretas do projeto são expostas pela interpretação do lado do servidor.

A Vite 5 agora remove o .default e a manipulação de .__esModule para corresponder o comportamento de produção. Em prática, isto não deve afetar as dependências empacotadas apropriadamente, mas se encontrarmos novos problemas carregando módulos, podemos tentar estas alterações:

js
// Antes:
import { foo } from 'bar'

// Depois:
import _bar from 'bar'
const { foo } = _bar
js
// Antes:
import foo from 'bar'

// Depois:
import * as _foo from 'bar'
const foo = _foo.default

Nota que estas mudanças correspondem o comportamento da Node.js, então podemos também executar as importações na Node.js para testar. Se preferirmos permanecer com o comportamento anterior, podemos definir legacy.proxySsrExternalModules para true.

worker.plugins agora é uma Função

Na Vite 4, worker.plugins aceitava uma vetor de extensões ((Plugin | Plugin[])[]). Desde a Vite 5, precisa de ser configurada como uma função que retorna um vetor de extensões (() => (Plugin | Plugin[])[]). Esta mudança é necessária para que as construções dos operários paralelas sejam executadas de maneira mais consistente e previsível.

Permitir Caminho Contendo . Para Recuar para index.html

Na Vite 4, acessar um caminho contendo . não recuava para index.html mesmo se appType for definida para 'SPA' (padrão). A partir da Vite 5, recuará para index.html.

Nota que o navegador já não mostrará a mensagem de erro de 404 na consola se apontarmos o caminho da imagem para um ficheiro inexistente (por exemplo, <img src="./file-does-not-exist.png">).

Alinhar o Comportamento Serviço de HTML do Desenvolvimento e Pré-visualização

Na Vite 4, os servidores de desenvolvimento e pré-visualização servem o HTML baseado na sua estrutura de diretório e na barra final de maneira diferente. Isto causa inconsistências quando testamos a nossa aplicação construída. A Vite 5 refaz este comportamento à um único comportamento como de baixo, dado a seguinte estrutura de ficheiro:

├── index.html
├── file.html
└── dir
    └── index.html
RequisiçãoAntes (desenvolvimento)Antes (pré-visualização)Depois (desenvolvimento & pré-visualização)
/dir/index.html/dir/index.html/dir/index.html/dir/index.html
/dir/index.html (retrocesso de SPA)/dir/index.html/index.html (retrocesso de SPA)
/dir//dir/index.html/dir/index.html/dir/index.html
/file.html/file.html/file.html/file.html
/file/index.html (retrocesso de SPA)/file.html/file.html
/file//index.html (retrocesso de SPA)/file.html/index.html (retrocesso de SPA)

Ficheiros de Manifesto Agora São Gerados no Diretório .vite Por Padrão

Na Vite 4, os ficheiros de manifesto (build.manifest e build.ssrManifest) eram gerados na raiz do build.outDir por padrão.

Na Vite 5, estes serão gerados no diretório .vite no build.outDir por padrão. Esta mudança ajuda desfazer o conflito os ficheiros públicos com os mesmos nomes de ficheiro de manifesto quando são copiados ao build.outDir.

Os ficheiros de CSS correspondentes não são listados como entradas de alto nível no ficheiro manifest.json

Na Vite 4, o ficheiro de CSS correspondente para um ponto de entrada de JavaScript também era listado como uma entrada de alto nível no ficheiro de manifesto (build.manifest). Estas entradas foram adicionadas de forma não intencional e só funcionavam para casos simples.

Na Vite 5, os ficheiros de CSS correspondentes só podem ser encontrados dentro da seção do ficheiro de entrada de JavaScript. Quando injetamos o ficheiro de JavaScript, os ficheiros de CSS correspondentes devem ser injetados. Quando o CSS deve ser injetado separadamente, deve ser adicionado como um ponto de entrada separado.

Atalhos da Interface da Linha de Comando Exigem Uma Pressão de Enter Adicional

Os atalhos da interface da linha de comando, como r para reiniciar o servidor de desenvolvimento, agora exige uma pressão de Enter adicional para acionar o atalho. Por exemplo, r + Enter para reiniciar o servidor de desenvolvimento.

Esta mudança impedi a Vite de engolir e controlar atalhos específicos do sistema operacional, permitindo melhor compatibilidade quando combinamos o servidor de desenvolvimento da Vite com outros processos, e evita as advertências anteriores.

Atualizar o Comportamentos da TypeScript de experimentalDecorators e useDefineForClassFields

A Vite 5 usa a esbuild 0.19 e remove a camada de compatibilidade para esbuild 0.18, a qual muda como experimentalDecorators e useDefineForClassFields são manipuladas.

  • experimentalDecorators não é ativada por padrão

    Nós precisamos definir compilerOptions.experimentalDecorators para true no tsconfig.json para usarmos os decoradores.

  • useDefineForClassFields predefini-se dependendo do valor de target da TypeScript

    Se target não for ESNext ou ES2022 ou mais recente, ou se não existir nenhum ficheiro tsconfig.json, useDefineForClassFields pré-definirá para false o que pode ser problemático com valor de esbuild.target padrão de esnext. Esta pode traduzir o código para blocos de inicialização estática que podem não ser suportadas no nosso navegador.

    Como tal, é recomendado definir target para ESNext ou ES2022 ou mais recente, ou definir useDefineForClassFields para true explicitamente quando configuramos tsconfig.json.

jsonc
{
  "compilerOptions": {
    // Definir `true` se usarmos decoradores
    "experimentalDecorators": true,
    // Definir `true` se vermos erros de analise no navegador
    "useDefineForClassFields": true,
  }
}

Remover a Opção --https e http: true

A opção --https define http: true. Esta configuração foi concebida para ser usada em conjunto com a funcionalidade de geração de certificação de https automática que foi abandonada na Vite 3. Portanto, esta configuração já não faz sentido, uma vez que fará a Vite iniciar um servidor de HTTPs sem um certificado.

Se usarmos @vitejs/plugin-basic-ssl ou vite-plugin-mkcert, estas já definirão o configuração de https internamente, então podemos remover --https, server.https: true e preview.https: true da nossa configuração.

Remover as APIs resolvePackageEntry e resolvePackageData

As APIs resolvePackageEntry e resolvePackageData foram removidas uma vez que expunham os interiores da Vite e bloqueavam potenciais otimizações da Vite 4.3 no passado. Estas APIs podem ser substituídas por pacotes de terceiros, por exemplo:

  • resolvePackageEntry: import.meta.resolve ou o pacote import-meta-resolve.
  • resolvePackageData: O mesmo que o de cima, e rastreie o diretório do pacote para obter o package.json da raiz. Ou use o pacote vitefu da comunidade.
js
import { resolve } from 'import-meta-env'
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 Depreciadas Removida

  • As exportações padrão de ficheiros de CSS (por exemplo, import style from './foo.css'): Usamos a consulta ?inline.
  • import.meta.globEager: Usamos import.meta.glob('*', { eager: true }).
  • ssr.format: 'cjs' e legacy.buildSsrCjsExternalHeuristics (#13816)
  • server.middlewareMode: 'ssr' e server.middlewareMode: 'html': Usamos appType + server.middlewareMode: true ao invés de (#8452)

Avançado

Existe algumas mudanças que apenas afetam os criadores de extensão e ferramenta.

Além disto, existem outras mudanças de rutura que apenas afetam alguns utilizadores.

Migração da Versão 3

Consulte primeiro o Guia de Migração da Versão 3 na documentação da versão 4 da Vite para veres as mudanças necessárias para portar a nossa aplicação para a versão 4 da Vite, e depois prossiga com as mudanças nesta página.

Lançada sob a Licença MIT. (126b88bb)