Explorer Vite à travers son code source

Comme vous l'avez probablement entendu, l'écosystème front-end a un nouvel enfant cool sur le bloc : un outil de construction appelé Vite. Bien qu'il ait été créé par Evan You (qui a également créé Vue.js), il n'est pas spécifique au framework, vous pouvez donc utiliser Vite avec Vue.js, React.js, Svelte.js ou même du JavaScript vanille.
Dans cet article, nous développerons lesAperçu qui a déjà été publié ici et examinez le code source de Vite pour en extraire quelques informations sur son architecture interne. En particulier, nous explorerons les systèmes de modèles et de plug-ins de Vite. À la fin, vous aurez une meilleure compréhension de la différence entre les modèles et les plugins, et comment le système central de Vite est connecté à un plugin.
Maintenant, sans plus tarder, créons une application avec Vite.
Créer une application avec Vite
Pour les besoins de cette démo, nous allons créer un projet Vue à l'aide de cette commande :
au dessus du niveau de la merinit vite@latest
(Avoir le@dernier
s'assurera que vous obtenez toujours la dernière version chaque fois que vous le faitesinstallation npm
dans ce projet nouvellement créé.)
En passant, vous avez peut-être vu une version obsolète duinitialiser
commande.
Comme vous pouvez le voir, l'avertissement d'obsolescence nous dit d'utilisernpm init vite
Au lieu.
Cette nouvelle commande est essentiellement un raccourci pour :
npx créer-vite
Cela installera et exécutera un outil appelécréer-vite
, qui vous indique le type de projet que vous créez. Vous sélectionnerez un nom et un modèle.
Sélectionnez un nom que vous aimez pour votre projet.
Et sélectionnez un modèle à utiliser.
À des fins d'exploration, vous pouvez choisir soitvanille
ou alorsvue
.
Ensuite, nous allons explorer cecicréer-vite
outil via son code source sur GitHub.
Explorer le code source de Vite
Tout d'abord, rendez-vous sur la page GitHub de Vite à l'adressegithub.com/vitejs/vite.
Rendez-vous ensuite à l'intérieur dupaquets
dossier.
Içi vous pouvez voircréer-app
etcréer-vite
.
créer-app
était responsable de la commande originale qui dit "obsolète". Ce qui nous intéresse ici, c'estcréer-vite
dossier. Il héberge tous les modèles intégrés pour la création de projets.
À l'intérieur depaquets
dossier, nous pouvons également voir des dossiers de plugins pour quelques plugins intégrés.
C'est maintenant le bon moment pour explorer les différences entremodèlesetpluginset comment ils fonctionnent ensemble dans le flux de travail de l'outil de génération.
Modèles
Modèledevrait être un concept facile à comprendre : c'est le code de démarrage d'un nouveau projet.
À l'intérieur depackages/create-vite
dossier, vous devriez voir une douzainemodèle-*
Dossiers.
📁/packages/create-vite
Comme vous pouvez le voir, Vite prend en charge des modèles pour différents frameworks (et leurs homologues TypeScript).
Tu peux choisirvanille
ducréer-vite
rapide.
Si vous choisissez vanille, il prendra essentiellement les fichiers dans lepackages/template-vanilla
dossier et clonez-les en tant que votre nouveau projet.
📁/packages/template-vanille
Vous pouvez également choisirvue
à partir de l'invite :
Si tu choisisvue
il clonera les fichiers dans lepackages/template-vue
dossier comme votre nouveau projet.
📁/packages/template-vue
Le projet généré à partir du modèle vue comportera la structure de dossiers standard que vous attendez d'un projet Vue.
Donc, c'estmodèle . Parlons maintenant debrancher.
Plugins
Comme je l'ai mentionné, Vite n'est pas spécifique au framework. Il est capable de créer des projets pour différents frameworks grâce à son système de plugins.
Prêt à l'emploi, Vite fournit des plugins pour Vue, Vue avec JSX et React.
Vous pouvez examiner le code de chaque plug-in intégré dans lepaquets
dossier:
📁/paquets
Noter:plugin-legacy
est destiné aux navigateurs hérités qui ne prennent pas en charge l'ESM natif.
La manière la plus courante d'utiliser ces plugins consiste à utiliser leurs modèles correspondants. Par exemple, le modèle Vue nécessitera l'utilisation du plugin Vue, et le modèle React nécessitera l'utilisation du plugin React.
En tant qu'option simple, un projet créé avec le modèle vanilla n'a aucune idée de la façon de servir les fichiers de composant à fichier unique (SFC) de Vue. Mais un projet Vue créé avec Vite pourra traiter le type de fichier SFC. Et il sait également comment regrouper l'ensemble du projet Vue pour la production.
Si l'on compare respectivementpackage.json
fichiers du modèle Vue et du modèle vanilla, nous pouvons facilement comprendre pourquoi.
📁/packages/template-vanilla/package.json
📁/packages/template-vue/package.json
template-vue
contient tout ce quimodèle-vanille
a, plus trois packages supplémentaires.
📁/packages/template-vue/package.json
"dépendances": {
"vue": "^3.2.6"
},
"devDépendances": {
"@vitejs/plugin-vue": "^1.6.1",
"@vue/compiler-sfc": "^3.2.6",
"vite": "^2.5.4"
}
vue
est la bibliothèque principale qui s'exécute pendant l'exécution@vitejs/plugin-vue
est le plugin qui est chargé de servir et de regrouper un projet Vue@vue/compiler-sfc
est nécessaire pour compiler un fichier SFC
Il est donc prudent de dire que ces trois packages donnent à un projet Vite la capacité de comprendre le code Vue. Le@vitejs/plugin-vue
Le package est le "pont" reliant le système central de Vite au framework Vue.js.
Selon les propres mots d'Evan You…
Dans la suite de l'article, nous poursuivrons notre exploration avec le template Vue. Mais si vous voulez voir plus de choses sympas avec le modèle vanille, vous pouvez consulter ce tutoriel d'Evan YouConstructions rapides comme l'éclair avec Vitecours.
Vue Plugin
Comme nous l'avons vu dans le plugin Vuepackage.json
la@vitejs/plugin-vue
package est responsable du regroupement d'un projet Vue.
Vite délègue le travail de regroupement à Rollup, qui est un autre outil de construction très populaire. La relation du plugin repose sur levite
noyau pour appeler lebrancher
code du package à certains moments spécifiques. Ces points spécifiques sont appelés «crochets ”. Le développeur du plugin doit décider quel code est exécuté dans chaque hook.
Par exemple, dans la source du plugin Vue, vous pouvez voir certains de ces crochets implémentés.
📁/packages/plugin-vue/src/index.ts
asynchrone ID de résolution(identifiant) {
si (identifiant=== EXPORT_HELPER_ID) {
retourneridentifiant}
si (parseVueRequest(identifiant).requête.vue) {
retourneridentifiant}
},
charge(identifiant,ssr= !!options.ssr) {
si (identifiant=== EXPORT_HELPER_ID) {
retournerhelperCode}
constante {nom de fichier,requête} = parseVueRequest(identifiant)
si (requête.vue) {
si (requête.src) {
retournerfs.readFileSync(nom de fichier, 'utf-8')
}
constantedescripteur= getDescriptor(nom de fichier,options)!
laisserbloc: SFCBloc | nul | indéfini
si (requête.taper === 'scénario') {bloc= getResolvedScript(descripteur,ssr)
} autre si (requête.taper === 'modèle') {bloc=descripteur.modèle!
} autre si (requête.taper === 'style') {bloc=descripteur.modes[requête.indice!]
} autre si (requête.indice != nul) {bloc=descripteur.blocs personnalisés[requête.indice]
}
si (bloc) {
retourner {code:bloc.teneur,carte:bloc.carte commequelconque}
}
}
},
transformer(code,identifiant,ssr= !!options.ssr) {
constante {nom de fichier,requête} = parseVueRequest(identifiant)
si (requête.cru) {
retourner
}
si (!filtre(nom de fichier) && !requête.vue) {
si (!requête.vue && refTransformFilter(nom de fichier)) {
si (!canUseRefTransform) {
cette.prévenir('refTransform requiert @vue/compiler-sfc@^3.2.5.')
} autre si (devraitTransformRef(code)) {
retourner transformRef(code, {nom de fichier,sourceMap: vrai
})
}
}
retourner
}
si (!requête.vue) {
retourner transformerMain(code,nom de fichier,options,
cette,ssr,
customElementFiltercustomElementFilter(nom de fichier)
)
} autre {
constantedescripteur= getDescriptor(nom de fichier,options)!
si (requête.taper === 'modèle') {
retourner transformerTemplateAsModule(code,descripteur,options, cette,ssr)
} autre si (requête.taper === 'style') {
retourner transformStyle(code,descripteur,
Numéro(requête.indice),options,
cette
)
}
}
}
Et dans l'essentielvite
package, Rollup sera utilisé pour appeler les hooks de plugin ci-dessus.
📁/packages/vite/src/node/build.ts
constanteplugins= (ssr?configuration.plugins.carte((p) => injectSsrFlagToHooks(p)) :configuration.plugins
) comme Brancher[]
...
constanterollupOptions: Options de cumul = {saisir,preserveEntrySignatures:ssr? 'autoriser-extension'
:libOptions? 'stricte'
: faux,
...options.rollupOptions,plugins,externe,
avertir(avertissement,prévenir) {
onRollupWarning(avertissement,prévenir,configuration)
}
}
...
constantepaquet= attendrecumul.cumul(rollupOptions)
Un plugin Rollup est très similaire à un plugin Vite. Mais comme Rollup n'est pas destiné à être utilisé comme un outil de développement prêt à l'emploi, un plugin Vite aura des options et des crochets supplémentaires qui ne sont pas disponibles dans un plugin Rollup classique.
En d'autres termes, un plugin Vite est une extension d'un plugin Rollup.
Commandes Vite
Pour en revenir au modèle Vue, portons une attention particulière auscénarios
option.
📁/packages/create-vite/template-vue/package.json
"scénarios": {
"dev": "vite",
"construire": "vite construire",
"servir": "aperçu rapide"
},
Ce sont les configurations qui nous permettent d'effectuer les commandes suivantes dans un projet Vite :
npm run dev
pour démarrer un serveur de développementconstruction d'exécution npm
pour créer une version de productionnpm exécuter servir
pour prévisualiser ladite construction de production localement
Les commandes ci-dessus sont mappées aux commandes suivantes :
vite
construire vite
aperçu rapide
Comme vous pouvez le voir, levite
le paquet est là où tout commence.
Vous pouvez avoir une idée des autres outils tiers impliqués en regardant à l'intérieur dupackage.json
dossier de lavite
emballer.
📁/packages/vite/package.json
"dépendances": {
"esbuild": "^0.12.17",
"postcss": "^8.3.6",
"résoudre": "^1.20.0",
"rouler": "^2.38.5"
},
Comme vous pouvez le voir,vite
utilise en fait deux bundlers différents dans les coulisses : Rollup et esbuild.
Rollup contre esbuild
Vite utilise ces deux bundlers pour différents types d'activités.
Rollup est utilisé par Vite pour les principaux besoins de regroupement. Et esbuild est utilisé pour la compatibilité et l'optimisation des modules. Ces étapes sont connues sous le nom de processus de « pré-groupage des dépendances ». Ce processus est considéré comme "lourd" car il doit être effectué module par module, et il existe généralement de nombreux modules utilisés dans un projet.
Compatibilité des modulesconsiste à convertir différents formats (modules UMD ou CommonJS) au format ESM standard.
Optimisationsert à regrouper tous les différents fichiers d'un seul paquet dépendant en une seule "chose", qui n'a ensuite besoin d'être récupérée qu'une seule fois.
Rollup serait trop lent pour gérer ces choses lourdes par rapport à esbuild. Esbuild est en fait l'outil de construction le plus rapide. C'est rapide car il est développé en Go (le langage de programmation).
Voici une comparaison affichée sur lesite officiel de documentation.
Comme vous pouvez le voir, esbuild n'est pas seulement rapide ; c'est à un tout autre niveau. Et c'est pourquoi Vite est rapide comme l'éclair. ⚡
Résumé
Dans cet article, nous avons parcouru la source et appris que :
- la
npm init vite
commande utilise lecréer-vite
outil - la
créer-vite
package contient tous les modèles intégrés - un modèle spécifique au framework dépend de son plugin spécifique au framework correspondant
- les plugins sont implémentés dans une architecture basée sur des crochets
- Vite utilise à la fois Rollup et esbuild dans les coulisses
Vous devriez maintenant avoir une solide compréhension du système Vite. Mais, en pratique, vous auriez besoin d'autres fonctionnalités communes que nous n'avons pas couvertes ici. Les plus courants seraient les supports de préprocesseur TypeScript et CSS.
Pour en savoir plus sur ces sujets et plus encore, vous pouvez consulter Evan You'sConstructions rapides comme l'éclair avec Vitecours disponible sur VueMastery.com.
Source link