Appearance
Caractéristiques
Au niveau le plus élémentaire, le développement à l'aide de Vite n'est pas très différent de l'utilisation d'un serveur de fichiers statiques. Toutefois, Vite apporte de nombreuses améliorations par rapport aux importations ESM natives, afin de prendre en charge diverses fonctionnalités généralement rencontrées dans les configurations basées sur des bundlers.
Résolution des dépendances NPM et pré-bundling
Les importations ES natives ne prennent pas en charge les importations de modules nus comme les suivants :
js
import { someMethod } from 'my-dep'.
Ce qui précède entraînera une erreur dans le navigateur. Vite détectera de telles importations de modules nus dans tous les fichiers sources servis et effectuera ce qui suit :
Pré-assemblage pour améliorer la vitesse de chargement des pages et convertir les modules CommonJS / UMD en ESM. L'étape de pré-regroupement est effectuée avec esbuild et rend le démarrage à froid de Vite beaucoup plus rapide que n'importe quel regroupeur basé sur JavaScript.
Réécrire les importations en URLs valides comme
/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd
pour que le navigateur puisse les importer correctement.
Les dépendances sont fortement mises en cache.
Vite met en cache les demandes de dépendances via les en-têtes HTTP, donc si vous souhaitez modifier/déboguer localement une dépendance, suivez les étapes ici.
Remplacement du module chaud
Vite fournit une API HMR sur l'ESM natif. Les frameworks dotés de capacités HMR peuvent exploiter l'API pour fournir des mises à jour instantanées et précises sans recharger la page ni détruire l'état de l'application. Vite fournit des intégrations HMR de première partie pour [Vue Single File Components] (https://github.com/vitejs/vite/tree/main/packages/plugin-vue) et [React Fast Refresh] (https://github.com/vitejs/vite/tree/main/packages/plugin-react). Il existe également des intégrations officielles pour Preact via [@prefresh/vite] (https://github.com/JoviDeCroock/prefresh/tree/main/packages/vite).
Notez que vous n'avez pas besoin de les configurer manuellement : lorsque vous créez une application via create-vite
, les modèles sélectionnés sont déjà préconfigurés pour vous.
TypeScript
Vite supporte l'importation de fichiers .ts
.
Vite n'effectue que la transpilation des fichiers .ts
et ne fait PAS de vérification de type. Il suppose que la vérification de type est prise en charge par votre IDE et le processus de construction (vous pouvez exécuter tsc --noEmit
dans le script de construction ou installer vue-tsc
et exécuter vue-tsc --noEmit
pour vérifier également le type de vos fichiers *.vue
).
Vite utilise esbuild pour transpiler TypeScript en JavaScript ce qui est environ 20~30x plus rapide que vanilla tsc
, et les mises à jour HMR peuvent se refléter dans le navigateur en moins de 50ms.
Utilisez la syntaxe Type-Only Imports and Export pour éviter les problèmes potentiels comme les importations de type-only qui sont incorrectement regroupées, par exemple :
ts
import type { T } from 'only/types'.
export type { T }
Options du compilateur TypeScript
Certains champs de configuration sous compilerOptions
dans tsconfig.json
nécessitent une attention particulière.
isolatedModules
Doit avoir la valeur true
.
C'est parce que esbuild
n'effectue que la transpilation sans information de type, il ne supporte pas certaines fonctionnalités comme les const enum et les importations implicites de type seulement.
Vous devez définir "isolatedModules" : true
dans votre tsconfig.json
sous compilerOptions
, afin que TS vous prévienne des fonctionnalités qui ne fonctionnent pas avec la transpilation isolée.
Cependant, certaines bibliothèques (par exemple vue
) ne fonctionnent pas bien avec "isolatedModules" : true
. Vous pouvez utiliser "skipLibCheck" : true
pour supprimer temporairement les erreurs jusqu'à ce qu'elles soient corrigées en amont.
useDefineForClassFields
À partir de Vite 2.5.0, la valeur par défaut sera true
si la cible TypeScript est ES2022
ou supérieure, y compris ESNext
. Cela est cohérent avec le [comportement de tsc
4.3.2 et plus] (https://github.com/microsoft/TypeScript/pull/42663). C'est également le comportement standard du runtime ECMAScript.
Mais il peut être contre-intuitif pour ceux qui viennent d'autres langages de programmation ou d'anciennes versions de TypeScript. Vous pouvez en savoir plus sur la transition dans les [notes de version de TypeScript 3.7] (https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier).
Si vous utilisez une bibliothèque qui s'appuie fortement sur les champs de classe, veuillez faire attention à l'usage que la bibliothèque entend en faire.
La plupart des bibliothèques attendent "useDefineForClassFields" : true
, comme MobX, Vue Class Components 8.x, etc.
Mais quelques bibliothèques n'ont pas encore adopté cette nouvelle valeur par défaut, notamment lit-element
. Veuillez définir explicitement useDefineForClassFields
à false
dans ces cas.
Autres options du compilateur affectant le résultat de la compilation
extends
](https://www.typescriptlang.org/tsconfig#extends)alwaysStrict
importsNotUsedAsValues
](https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues)jsx
jsxFactory
jsxFragmentFactory
jsxImportSource
preserveValueImports
Si la migration de votre base de code vers "isolatedModules" : true
représente un effort insurmontable, vous pouvez peut-être le contourner avec un plugin tiers tel que rollup-plugin-friendly-type-imports. Cependant, cette approche n'est pas officiellement supportée par Vite.
Types de clients
Les types par défaut de Vite sont pour son API Node.js. Pour limiter l'environnement du code côté client dans une application Vite, ajoutez un fichier de déclaration d.ts
:
typescript
/// <référence types="vite/client" />
Vous pouvez également ajouter vite/client
à compilerOptions.types
de votre tsconfig
:
json
{
"compilerOptions" : {
"types" : ["vite/client"]
}
}
Cela fournira les cales de type suivantes :
- Importations d'actifs (par exemple, l'importation d'un fichier
.svg
) - Types pour les [variables env] injectées par Vite(./env-and-mode#env-variables) dans
i
.mport.meta.env - Types pour l'API HMR dans
i
.mport.meta.hot
:: : conseil Pour remplacer le typage par défaut, déclarez-le avant la référence à triple barre oblique. Par exemple, pour faire de l'importation par défaut de *.svg
un composant React :
ts
declare module '*.svg' {
const content : React.FC<React.SVGProps<SVGElement>>.
export default content
}
/// <reference types="vite/client" />
:: :
Vue
Vite fournit un support Vue de première classe :
- Support de Vue 3 SFC via @vitejs/plugin-vue
- Support de Vue 3 JSX via @vitejs/plugin-vue-jsx
- Support de Vue 2.7 via @vitejs/plugin-vue2
- Prise en charge de Vue <2.7 via vite-plugin-vue2
JSX
Les fichiers .jsx
et .tsx
sont également supportés. La transpilation JSX est également gérée via esbuild.
Les utilisateurs de Vue doivent utiliser le plugin officiel @vitejs/plugin-vue-jsx, qui fournit des fonctionnalités spécifiques à Vue 3, notamment HMR, la résolution globale des composants, les directives et les slots.
Si vous n'utilisez pas JSX avec React ou Vue, les jsxFactory
et jsxFragment
personnalisés peuvent être configurés en utilisant l'option esbuild
. Par exemple pour Preact :
js
// vite.config.js
import { defineConfig } from 'vite'.
export default defineConfig({
esbuild : {
jsxFactory : 'h',
jsxFragment : 'Fragment'.
}
})
Plus de détails dans esbuild docs.
Vous pouvez injecter les aides JSX en utilisant jsxInject
(qui est une option réservée à Vite) pour éviter les importations manuelles :
js
// vite.config.js
import { defineConfig } de 'vite'.
export default defineConfig({
esbuild : {
jsxInject : `import React from 'react'``
}
})
CSS
L'importation de fichiers .css
injectera son contenu dans la page via une balise <style>
avec le support de HMR. Vous pouvez également récupérer le CSS traité en tant que chaîne de caractères comme l'export par défaut du module.
@import
Inlining et Rebasing
Vite est pré-configuré pour supporter l'inlining CSS @import
via postcss-import
. Les alias de Vite sont également respectés pour les CSS @import
. En outre, toutes les références CSS url()
, même si les fichiers importés se trouvent dans des répertoires différents, sont toujours automatiquement rebasées pour garantir leur exactitude.
Les alias @import
et le rebasage des URL sont également pris en charge pour les fichiers Sass et Less (voir Préprocesseurs CSS).
PostCSS
Si le projet contient une configuration PostCSS valide (tout format supporté par postcss-load-config, par exemple postcss.config.js
), elle sera automatiquement appliquée à tous les CSS importés.
Modules CSS
Tout fichier CSS se terminant par .module.css
est considéré comme un fichier de modules CSS. L'importation d'un tel fichier renverra l'objet module correspondant :
css
/* exemple.module.css */
.red {
couleur : rouge ;
}
js
import les classes de './exemple.module.css'.
document.getElementById('foo').className = classes.red
Le comportement des modules CSS peut être configuré via l'option [css.modules
] (/config/shared-options.md#css-modules).
Si l'option css.modules.localsConvention
est configurée pour activer les localisations en camelCase (par exemple, localsConvention : 'camelCaseOnly'
), vous pouvez également utiliser des importations nommées :
js
// .apply-color -> applyColor
import { applyColor } de './example.module.css'.
document.getElementById('foo').className = applyColor
Préprocesseurs CSS
Étant donné que Vite ne vise que les navigateurs modernes, il est recommandé d'utiliser des variables CSS natives avec les plugins PostCSS qui mettent en œuvre les projets du CSSWG (par exemple, postcss-nesting) et de créer des CSS simples, conformes aux normes futures.
Cela dit, Vite fournit un support intégré pour les fichiers .scss
, .sass
, .less
, .styl
et .stylus
. Il n'est pas nécessaire d'installer des plugins spécifiques à Vite pour ces fichiers, mais le pré-processeur correspondant doit être installé :
bash
# .scss et .sass
npm add -D sass
# .less
npm add -D less
# .styl et .stylus
npm add -D stylus
Si vous utilisez des composants Vue à fichier unique, cela active aussi automatiquement <style lang="sass">
et al.
Vite améliore la résolution @import
pour Sass et Less afin que les alias de Vite soient également respectés. De plus, les références relatives url()
à l'intérieur des fichiers Sass/Less importés qui se trouvent dans des répertoires différents du fichier racine sont aussi automatiquement rebasées pour garantir l'exactitude.
Les alias @import
et le rebasage des url ne sont pas supportés pour Stylus à cause des contraintes de son API.
Vous pouvez également utiliser des modules CSS combinés avec des pré-processeurs en ajoutant le suffixe .module
à l'extension du fichier, par exemple style.module.scss
.
Désactiver l'injection de CSS dans la page
L'injection automatique de contenus CSS peut être désactivée via le paramètre de requête ?inline
. Dans ce cas, la chaîne CSS traitée est renvoyée comme l'exportation par défaut du module comme d'habitude, mais les styles ne sont pas injectés dans la page.
js
import styles from './foo.css' // sera injecté dans la page
import otherStyles from './bar.css?inline' // ne sera pas injecté dans la page.
Actifs statiques
L'importation d'une ressource statique renvoie l'URL publique résolue lorsqu'elle est servie :
js
import imgUrl from './img.png'.
document.getElementById('hero-img').src = imgUrl
Des requêtes spéciales peuvent modifier la façon dont les ressources sont chargées :
js
// Chargement explicite des ressources sous forme d'URL
import assetAsURL from './asset.js?url'.
js
// Chargement des ressources sous forme de chaînes de caractères
import assetAsString from './shader.glsl?raw' (chaîne de caractères)
js
// Chargement de travailleurs Web
import Worker from "./worker.js?worker".
js
// Les travailleurs Web sont intégrés sous forme de chaînes base64 au moment de la construction.
import InlineWorker from "./worker.js?worker&inline".
Plus de détails dans Static Asset Handling.
JSON
Les fichiers JSON peuvent être importés directement - les importations nommées sont également supportées :
js
// importez l'objet entier
import json from './exemple.json'.
// importez un champ racine en tant qu'exportation nommée, ce qui permet d'éviter de secouer l'arbre !
import {champ } from './exemple.json'.
Importation globale
Vite supporte l'importation de plusieurs modules depuis le système de fichiers via la fonction spéciale i
:
js
const modules = import.meta.glob('./dir/*.js')
Ce qui précède sera transformé en ce qui suit :
js
// code produit par vite
const modules = {
'./dir/foo.js' : () => import('./dir/foo.js'),
'./dir/bar.js' : () => import('./dir/bar.js')
}
Vous pouvez ensuite itérer sur les clés de l'objet modules
pour accéder aux modules correspondants :
js
for (const path in modules) {
modules[path]().then((mod) => {
console.log(chemin, mod)
})
}
Les fichiers correspondants sont par défaut chargés paresseusement via l'importation dynamique et seront divisés en morceaux séparés pendant la construction. Si vous préférez importer tous les modules directement (par exemple, en comptant sur les effets secondaires de ces modules pour être appliqués en premier), vous pouvez passer { eager : true }
comme deuxième argument :
js
const modules = import.meta.glob('./dir/*.js', { eager : true })
Ce qui précède sera transformé en ce qui suit :
js
// code produit par vite
import * as __glob__0_0 from './dir/foo.js'.
import * as __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js' : __glob__0_0,
'./dir/bar.js' : __glob__0_1
}
Importation de Glob en tant que
i
prend également en charge l'importation de fichiers sous forme de chaînes (similaire à Importation d'un bien sous forme de chaîne) avec la syntaxe Import Reflection :
js
const modules = import.meta.glob('./dir/*.js', { as: 'raw' })
Ce qui précède sera transformé en ce qui suit :
js
// code produit par vite
const modules = {
'./dir/foo.js': 'export default "foo"\n',
'./dir/bar.js': 'export default "bar"\n'
}
{ as : 'url' }
est également pris en charge pour le chargement des ressources sous forme d'URL.
Motifs multiples
Le premier argument peut être un tableau de globs, par exemple
js
const modules = import.meta.glob(['./dir/*.js', './autre/*.js'])
Modèles négatifs
Les motifs glob négatifs sont également supportés (préfixés par !
). Pour ignorer certains fichiers du résultat, vous pouvez ajouter des motifs globaux d'exclusion au premier argument :
js
const modules = import.meta.glob(['./dir/*.js', '!**/bar.js'])
js
// code produit par vite
const modules = {
'./dir/foo.js' : () => import('./dir/foo.js')
}
Importations nommées
Il est possible d'importer seulement certaines parties des modules avec les options import
.
js
const modules = import.meta.glob('./dir/*.js', { import : 'setup' })
ts
// code produit par vite
const modules = {
'./dir/foo.js': () => import('./dir/foo.js').then((m) => m.setup),
'./dir/bar.js': () => import('./dir/bar.js').then((m) => m.setup)
}
En combinaison avec eager
, il est même possible d'activer le tree-shaking pour ces modules.
ts
const modules = import.meta.glob('./dir/*.js', { import : 'setup', eager : true })
ts
// code produit par vite :
import { setup as __glob__0_0 } from './dir/foo.js' (en anglais)
import { setup as __glob__0_1 } from './dir/bar.js' (en anglais)
const modules = {
./dir/foo.js' : __glob__0_0,
'./dir/bar.js' : __glob__0_1
}
Définissez import
à default
pour importer l'exportation par défaut.
ts
const modules = import.meta.glob('./dir/*.js', {
import : 'default',
eager : true
})
js
import __glob__0_0 from './dir/foo.js'
import __glob__0_1 from './dir/bar.js'
const modules = {
'./dir/foo.js': __glob__0_0,
'./dir/bar.js': __glob__0_1
}
Requêtes personnalisées
Vous pouvez également utiliser l'option query
pour fournir des requêtes personnalisées aux importations pour que d'autres plugins puissent les utiliser.
ts
const modules = import.meta.glob('./dir/*.js', {
query : { foo : 'bar', bar : true }
})
ts
// code produit par vite :
const modules = {
'./dir/foo.js' : () =>
import('./dir/foo.js?foo=bar&bar=true').then((m) => m.setup),
'./dir/bar.js' : () =>
import('./dir/bar.js?foo=bar&bar=true').then((m) => m.setup)
}
Caveats de l'importation Glob
Notez que :
- Ceci est une fonctionnalité réservée à Vite et n'est pas un standard web ou ES.
- Les motifs glob sont traités comme des spécificateurs d'importation : ils doivent être soit relatifs (commençant par
./
) ou absolus (commençant par/
, résolus relativement à la racine du projet) ou un chemin d'alias (voir l'optionresolve.alias
). - La correspondance des globes est effectuée par
fast-glob
- consultez sa documentation pour les modèles de globes supportés. - Vous devez également savoir que tous les arguments de la commande
i
doivent être passés comme des littéraux. Vous ne pouvez PAS utiliser de variables ou d'expressions dans ces arguments.mport.meta.glob
Importation dynamique
Similaire à glob import, Vite supporte également l'importation dynamique avec des variables.
ts
const module = await import(`./dir/${file}.js`)
Notez que les variables ne représentent les noms de fichiers qu'à un niveau de profondeur. Si file
est 'foo/bar'
, l'importation échouera. Pour une utilisation plus avancée, vous pouvez utiliser la fonctionnalité glob import.
WebAssembly
Les fichiers .wasm
précompilés peuvent être importés avec ?init
- l'exportation par défaut sera une fonction d'initialisation qui retourne une Promise de l'instance wasm :
js
import init from './example.wasm?init'
init().then((instance) => {
instance.exports.test()
})
La fonction init peut également prendre comme second argument l'objet imports
qui est passé à WebAssembly.instantiate
:
js
init({
imports : {
someFunc : () => {
/* ... */
}
}
}).then(() => {
/* ... */
})
Dans le build de production, les fichiers .wasm
plus petits que assetInlineLimit
seront inlined en tant que chaînes base64. Sinon, ils seront copiés dans le répertoire dist en tant que ressource et récupérés à la demande.
:: : avertissement Le module ES Module Integration Proposal for WebAssembly n'est pas pris en charge actuellement. Utilisez vite-plugin-wasm
ou d'autres plugins communautaires pour gérer cela. :: :
Travailleurs Web
Importer avec des constructeurs
Un script de travailleur Web peut être importé en utilisant new Worker()
et new SharedWorker()
. Comparée aux suffixes worker, cette syntaxe est plus proche des standards et est la manière recommandée de créer des workers.
ts
const worker = new Worker(new URL('./worker.js', import.meta.url))
Le constructeur de worker accepte également des options, qui peuvent être utilisées pour créer des workers "modules" :
ts
const worker = new Worker(new URL('./worker.js', import.meta.url), {
type : 'module'
})
Importation avec des suffixes de requête
Un script web worker peut être directement importé en ajoutant ?worker
ou ?sharedworker
à la requête d'importation. L'exportation par défaut sera un constructeur de travailleur personnalisé :
js
import MyWorker from './worker?worker'
const worker = new MyWorker()
Le script du travailleur peut également utiliser les instructions import
au lieu de importScripts()
- notez que pendant le développement, cela dépend du support natif du navigateur et ne fonctionne actuellement que dans Chrome, mais pour la construction de production, cela est compilé.
Par défaut, le script du travailleur sera émis comme un chunk séparé dans le build de production. Si vous souhaitez mettre en ligne le worker sous forme de chaînes base64, ajoutez la requête inline
:
js
import MyWorker from './worker?worker&inline'
Si vous souhaitez récupérer le worker sous forme d'URL, ajoutez la requête url
:
js
import MyWorker from './worker?worker&url'
Voir Options du travailleur pour plus de détails sur la configuration du regroupement de tous les travailleurs.
Optimisation de la construction
Les fonctionnalités énumérées ci-dessous sont automatiquement appliquées dans le cadre du processus de construction et il n'est pas nécessaire de les configurer explicitement, sauf si vous souhaitez les désactiver.
Fractionnement du code CSS
Vite extrait automatiquement le CSS utilisé par les modules dans un chunk asynchrone et génère un fichier séparé pour celui-ci. Le fichier CSS est automatiquement chargé via une balise <link>
lorsque le chunk asynchrone associé est chargé, et le chunk asynchrone est garanti d'être évalué seulement après que le CSS soit chargé pour éviter FOUC.
Si vous préférez que tout le CSS soit extrait dans un seul fichier, vous pouvez désactiver la division du code CSS en définissant build.cssCodeSplit
à false
.
Génération de directives de préchargement
Vite génère automatiquement des directives <link rel="modulepreload">
pour les chunks d'entrée et leurs imports directs dans le HTML construit.
Optimisation du chargement asynchrone des chunks
Dans les applications du monde réel, Rollup génère souvent des chunks "communs" - le code qui est partagé entre deux ou plusieurs autres chunks. Combiné avec les importations dynamiques, il est assez courant d'avoir le scénario suivant :
Dans les scénarios non optimisés, lorsque le chunk asynchrone A
est importé, le navigateur devra demander et analyser A
avant de comprendre qu'il a également besoin du chunk commun C
. Cela entraîne un aller-retour supplémentaire sur le réseau :
Entrée ---> A ---> C
Vite réécrit automatiquement les appels d'importation dynamique de code avec une étape de préchargement de sorte que lorsque A
est demandé, C
est récupéré en parallèle :
Entrée ---> (A + C)
Il est possible que C
ait d'autres importations, ce qui entraînera encore plus d'allers-retours dans le scénario non optimisé. L'optimisation de Vite tracera toutes les importations directes pour éliminer complètement les allers-retours, quelle que soit la profondeur des importations.