Construir para Produção
Quando for o momento de implementar a nossa aplicação em produção, simplesmente executamos o comando vite build
. Por padrão, este usa <root>/index.html
como o ponto de entrada da construção, e produz um pacote de aplicação que é adequado para ser servido sobre um serviço de hospedagem estática. Consultar o Implementando uma Aplicação Estática por orientações sobre os serviços populares.
Compatibilidade do Navegador
O pacote de produção pressupõe suporte para JavaScript moderno. Por padrão, a Vite dirige-se aos navegadores que suportam os módulos de ECMAScript nativo, importação dinâmica de Módulo de ECMAScript nativo, e import.meta
:
- Chrome >=87
- Firefox >=78
- Safari >=14
- Edge >=88
Nós podemos especificar alvos personalizados através da opção de configuração build.target
, onde o alvo inferior é es2015
.
Nota que por padrão, a Vite apenas manipula os transformações de sintaxe e não cobre os enchimentos de polietileno de funcionalidades. Nós podemos consultar o https://cdnjs.cloudflare.com/polyfill/, o qual gera automaticamente pacotes de enchimentos de polietileno baseado na sequência de caracteres do UserAgent
do navegador do utilizador.
Os navegadores antigos podem ser suportados através do @vitejs/plugin-legacy
, que gerará os pedaços para os navegadores antigos e enchimentos de polietileno de funcionalidade da linguagem do ECMAScript correspondente. Os pedaços para os navegadores antigos são carregados condicionalmente apenas nos navegadores que não tem suporte ao Módulo de ECMAScript nativo.
Caminho de Base Pública
- Relacionado com: Manipulação de Recurso
Se estivermos implementando o nosso projeto em produção sob um caminho público encaixado, simplesmente especificamos a opção de configuração base
e todos os caminhos do recurso serão reescritos em conformidade. Esta opção também pode ser especificada como um sinal da linha de comando, por exemplo, vite build --base=/my/public/path/
.
As URLs do recurso importado da JavaScript, as referências da url()
da CSS, e as referências do recurso nos nossos ficheiros .html
são todos automaticamente ajustados para respeitarem esta opção durante a construção.
A exceção é quando precisamos concatenar dinamicamente as URLs em tempo real. Neste caso, podemos usar a variável import.meta.env.BASE_URL
injetado globalmente que será o caminho de base pública. Nota que esta variável é substituída estaticamente durante a construção, então deve aparecer exatamente como está (isto é, import.meta.env['BASE_URL']
não funcionará).
Para controlo avançado do caminho de base, consultar as Opções Avançadas da Base.
Base Relativa
Se não soubermos o caminho base com antecedência, podemos definir um caminho base relativo com "base": "./"
ou "base": ""
. Isto fará com que todos os endereços de localização de recursos gerados sejam relativos a cada ficheiro.
Suporte para navegadores mais antigos quando se utilizam bases relativas
O suporte a import.meta
é obrigatório para bases relativas. Se precisarmos de suportar navegadores que não suportam import.meta
, podemos usar a extensão legacy
.
Personalizar a Construção
A construção pode ser personalizada através de várias opções de configuração da construção. Especificamente, podemos ajustar diretamente as opções de Rollup subjacentes através da build.rollupOptions
:
export default defineConfig({
build: {
rollupOptions: {
// https://rollupjs.org/configuration-options/
},
},
})
Por exemplo, podemos especificar várias saídas da Rollup com as extensões que apenas são aplicadas durante a construção.
Estratégia de Fragmentação
Nós podemos configurar como os pedaços são separados usando build.rollupOptions.output.manualChunks
(consultar documentação da Rollup). Se usarmos uma abstração, precisamos consultar a sua documentação pela configuração de como os pedaços são separados.
Manipulação do Erro de Carregamento
A Vite emite o evento vite:preloadError
quando não consegue carregar as importações dinâmicas. event.payload
contém o erro de importação original. Se chamarmos event.preventDefault()
, o erro não será lançado:
window.addEventListener('vite:preloadError', (event) => {
window.location.reload() // por exemplo, atualizar a página
})
Quando uma nova implementação de produção ocorre, o serviço de hospedagem pode eliminar os recursos das implementações anteriores da produção. Como resultado, um utilizador que visitou a nossa aplicação antes da nova implementação de produção pode encontrar um erro de importação. Este erro acontece porque os recursos executando sobre o dispositivo do utilizador estão desatualizados e esta tenta importar o pedaço antigo correspondente, que foi eliminado. Este evento é útil para solucionar esta situação.
Reconstruir Sobre as Mudanças dos Ficheiros
Nós podemos ativar o observador da Rollup com vite build --watch
. Ou, podemos ajustar diretamente a WatcherOptions
subjacente através da build.watch
:
export default defineConfig({
build: {
watch: {
// https://rollupjs.org/configuration-options/#watch
},
},
})
Com a opção --watch
ativada, as mudanças ao vite.config.js
, bem como às quaisquer ficheiros à serem empacotados, acionarão uma reconstrução.
Aplicação de Várias Páginas
Suponhamos que temos a seguinte estrutura de código-fonte:
├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
├── index.html
└── nested.js
Durante o desenvolvimento, simplesmente navegamos a ou ligamos ao /nested/
- este funciona como esperado, tal como para um servidor de ficheiro estático normal.
Durante a construção, tudo o que precisamos fazer é especificar vários ficheiros .html
como pontos de entrada:
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
nested: resolve(__dirname, 'nested/index.html'),
},
},
},
})
Se especificarmos uma raiz diferente, devemos lembrar de que __dirname
ainda será a pasta do nosso ficheiro vite.config.js
quando resolvermos os caminhos de entrada. Portanto, precisaremos adicionar a nossa entrada root
aos argumentos para resolve
.
Nota que para os ficheiros HTML, a Vite ignora o nome dado à entrada no objeto rollupOptions.input
e ao invés disto respeita o identificador único resolvido do ficheiro quando geramos o recurso de HTML na pasta de distribuição (dist
). Isto garante uma estrutura consistente com a maneira que o servidor de desenvolvimento funciona.
Modo de Biblioteca
Quando estivermos desenvolvimento uma biblioteca orienta ao navegador, estaremos provavelmente gastando a maior parte do tempo numa página de teste ou demonstração que importa de fato a nossa biblioteca. Com a Vite, podemos usar o nosso index.html
para este propósito para obter uma experiência de desenvolvimento mais suave.
Na hora de empacotar a nossa biblioteca para distribuição, usamos a opção de configuração build.lib
. Temos que certificar-nos de também expomos quaisquer dependências que não queremos empacotar na nossa biblioteca, por exemplo, vue
ou react
:
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
// Também poderia ser um diretório ou
// vetor de vários pontos de entrada
entry: resolve(__dirname, 'lib/main.js'),
name: 'MyLib',
// as extensões apropriadas serão adicionadas
fileName: 'my-lib',
},
rollupOptions: {
// certificar de expor as dependências que não
// devem ser empacotadas na nossa biblioteca
external: ['vue'],
output: {
// fornecer as variáveis globais para usar na
// construção UMD para as dependências expostas
globals: {
vue: 'Vue',
},
},
},
},
})
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
entry: {
'my-lib': resolve(__dirname, 'lib/main.js'),
secondary: resolve(__dirname, 'lib/secondary.js'),
},
name: 'MyLib',
},
rollupOptions: {
// certificar de expor as dependências que não
// devem ser empacotadas na nossa biblioteca
external: ['vue'],
output: {
// fornecer as variáveis globais para usar na
// construção UMD para as dependências expostas
globals: {
vue: 'Vue',
},
},
},
},
})
O ficheiro de entrada conteria as exportações que poderiam ser importadas pelos utilizadores do nosso pacote:
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export { Foo, Bar }
Executar vite build
com esta configuração usa uma predefinição de Rollup que é orientada para bibliotecas de entrega e produz dois formatos de pacote:
es
eumd
(para única entrada)es
ecjs
(para várias entradas)
Os formatos podem ser configurados com a opção build.lib.formats
:
$ vite build
building for production...
dist/my-lib.js 0.08 kB / gzip: 0.07 kB
dist/my-lib.umd.cjs 0.30 kB / gzip: 0.16 kB
O package.json
recomendado para a nossa biblioteca:
{
"name": "my-lib",
"type": "module",
"files": ["dist"],
"main": "./dist/my-lib.umd.cjs",
"module": "./dist/my-lib.js",
"exports": {
".": {
"import": "./dist/my-lib.js",
"require": "./dist/my-lib.umd.cjs"
}
}
}
{
"name": "my-lib",
"type": "module",
"files": ["dist"],
"main": "./dist/my-lib.cjs",
"module": "./dist/my-lib.js",
"exports": {
".": {
"import": "./dist/my-lib.js",
"require": "./dist/my-lib.cjs"
},
"./secondary": {
"import": "./dist/secondary.js",
"require": "./dist/secondary.cjs"
}
}
}
Suporte da CSS
Se nossa biblioteca importa qualquer folha de estilo, esta será empacotada como um único ficheiro de folha de estilo em cascata para além dos ficheiros .js
construídos, por exemplo, dist/my-lib.css
. O nome é predefinido pela build.lib.fileName
, mas também pode ser alterada com build.lib.cssFileName
.
Podemos exportar o ficheiro de folha de estilo no nosso package.json
para ser importado pelos utilizadores:
{
"name": "my-lib",
"type": "module",
"files": ["dist"],
"main": "./dist/my-lib.umd.cjs",
"module": "./dist/my-lib.js",
"exports": {
".": {
"import": "./dist/my-lib.js",
"require": "./dist/my-lib.umd.cjs"
},
"./style.css": "./dist/my-lib.css"
}
}
EXTENSÕES DE FICHEIRO
Se o package.json
não contiver "type": "module"
, a Vite gerará extensões de ficheiro diferentes para fins de compatibilidade com a Node.js. A .js
tornar-se-á em .mjs
e .cjs
tornar-se-á em .js
.
VARIÁVEIS DE AMBIENTE
No modo de biblioteca, todos os usos de import.meta.env.*
serão substituídos estaticamente quando construirmos para produção. No entanto, os usos de process.env.*
não são, então para que os consumidores da nossa biblioteca possam mudá-lo dinamicamente. Se isto for indesejável, podemos usar define: { 'process.env.NODE_ENV': '"production"' }
por exemplo, os substituir estaticamente, ou usamos esm-env
para melhor compatibilidade com os empacotadores e executores.
USO AVANÇADO
O modo de biblioteca inclui uma simples e opinativa configuração para as bibliotecas orientadas ao navegador e para a abstração de JavaScript. Se estivermos a construir bibliotecas que não destinadas ao navegador, ou exigem fluxos de construção avançados, podemos usar diretamente a Rollup ou esbuild.
Opções de Base Avançadas
AVISO
Esta funcionalidade é experimental. Comentar.
Para os casos de uso avançados, os recursos e ficheiros públicos implementados em produção podem estar em caminhos diferentes, por exemplo para usarmos diferentes estratégias de armazenamento de consulta imediata. Um utilizador pode escolher implementar em produção nestes três caminhos diferentes:
- Os ficheiros de HTML de entrada gerados (os quais podem ser processados durante a interpretação do lado do servidor)
- Os recursos de nome embaralhado gerados (JavaScript, CSS, e outros tipos de ficheiro como imagens)
- Os ficheiros públicos copiados
Uma única base estática não é o suficiente nestes cenários. A Vite fornece suporte experimental para opções de base avançadas durante a construção, usando a experimental.renderBuiltUrl
.
experimental: {
renderBuiltUrl(filename, { hostType }) { if (hostType === 'js') {
return {
runtime: `window.__toCdnUrl(${JSON.stringify(filename)})`
}
} else {
return {
relative: true
}
}
},
},
Se os recursos de nome embaralhado e os ficheiros públicos são forem implementados em produção em conjunto, as opções para grupo podem ser definidas de maneira independente usando a type
de recurso incluída no segundo parâmetro context
dado à função:
experimental: {
renderBuiltUrl(filename, { hostId, hostType, type }) { if (type === 'public') {
return 'https://www.domain.com/' + filename
} else if (path.extname(hostId) === '.js') {
return {
runtime: `window.__assetsPath(${JSON.stringify(filename)})`
}
} else {
return 'https://cdn.domain.com/assets/' + filename
}
},
},
Notemos que a filename
passada é um endereço de recurso uniforme descodificado, e se a função retorna uma sequência de caracteres de endereço de recurso uniforme, esta também deve ser descodificada. A Vite tratará da codificação automaticamente quando produzir os endereços de recurso uniforme. Se um objeto com runtime
for retornado, a codificação deve ser tratada por nós próprios sempre que necessário, uma vez que o código da execução será produzido tal como está.