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 les Aperç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 :
npm init vite@latest
(Avoir le @latest
s’assurera que vous obtenez toujours la dernière version chaque fois que vous le faites npm install
dans ce projet nouvellement créé.)
En passant, vous avez peut-être vu une version obsolète du init
commande.
Comme vous pouvez le voir, l’avertissement d’obsolescence nous dit d’utiliser npm init vite
Au lieu.
Cette nouvelle commande est essentiellement un raccourci pour :
npx create-vite
Cela installera et exécutera un outil appelé create-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 soit vanilla
ou alors vue
.
Ensuite, nous allons explorer ceci create-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’adresse github.com/vitejs/vite.
Rendez-vous ensuite à l’intérieur du packages
dossier.
Içi vous pouvez voir create-app
et create-vite
.
create-app
était responsable de la commande originale qui dit « obsolète ». Ce qui nous intéresse ici, c’est create-vite
dossier. Il héberge tous les modèles intégrés pour la création de projets.
À l’intérieur de packages
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 entre modèles et pluginset comment ils fonctionnent ensemble dans le flux de travail de l’outil de génération.
Modèles
Modèle devrait être un concept facile à comprendre : c’est le code de démarrage d’un nouveau projet.
À l’intérieur de packages/create-vite
dossier, vous devriez voir une douzaine template-*
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 choisir vanilla
du create-vite
rapide.
Si vous choisissez vanille, il prendra essentiellement les fichiers dans le packages/template-vanilla
dossier et clonez-les en tant que votre nouveau projet.
📁 /packages/template-vanille
Vous pouvez également choisir vue
à partir de l’invite :
Si tu choisis vue
il clonera les fichiers dans le packages/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’est modèle. Parlons maintenant de brancher.
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 le packages
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 respectivement package.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 qui template-vanilla
a, plus trois packages supplémentaires.
📁 /packages/template-vue/package.json
"dependencies": {
"vue": "^3.2.6"
},
"devDependencies": {
"@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 You Constructions rapides comme l’éclair avec Vite cours.
Vue Plugin
Comme nous l’avons vu dans le plugin Vue package.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 le vite
noyau pour appeler le plugin
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
async resolveId(id) {
if (id === EXPORT_HELPER_ID) {
return id
}
if (parseVueRequest(id).query.vue) {
return id
}
},
load(id, ssr = !!options.ssr) {
if (id === EXPORT_HELPER_ID) {
return helperCode
}
const { filename, query } = parseVueRequest(id)
if (query.vue) {
if (query.src) {
return fs.readFileSync(filename, 'utf-8')
}
const descriptor = getDescriptor(filename, options)!
let block: SFCBlock | null | undefined
if (query.type === 'script') {
block = getResolvedScript(descriptor, ssr)
} else if (query.type === 'template') {
block = descriptor.template!
} else if (query.type === 'style') {
block = descriptor.styles[query.index!]
} else if (query.index != null) {
block = descriptor.customBlocks[query.index]
}
if (block) {
return {
code: block.content,
map: block.map as any
}
}
}
},
transform(code, id, ssr = !!options.ssr) {
const { filename, query } = parseVueRequest(id)
if (query.raw) {
return
}
if (!filter(filename) && !query.vue) {
if (!query.vue && refTransformFilter(filename)) {
if (!canUseRefTransform) {
this.warn('refTransform requires @vue/compiler-sfc@^3.2.5.')
} else if (shouldTransformRef(code)) {
return transformRef(code, {
filename,
sourceMap: true
})
}
}
return
}
if (!query.vue) {
return transformMain(
code,
filename,
options,
this,
ssr,
customElementFilter(filename)
)
} else {
const descriptor = getDescriptor(filename, options)!
if (query.type === 'template') {
return transformTemplateAsModule(code, descriptor, options, this, ssr)
} else if (query.type === 'style') {
return transformStyle(
code,
descriptor,
Number(query.index),
options,
this
)
}
}
}
Et dans l’essentiel vite
package, Rollup sera utilisé pour appeler les hooks de plugin ci-dessus.
📁 /packages/vite/src/node/build.ts
const plugins = (
ssr ? config.plugins.map((p) => injectSsrFlagToHooks(p)) : config.plugins
) as Plugin[]
...
const rollupOptions: RollupOptions = {
input,
preserveEntrySignatures: ssr
? 'allow-extension'
: libOptions
? 'strict'
: false,
...options.rollupOptions,
plugins,
external,
onwarn(warning, warn) {
onRollupWarning(warning, warn, config)
}
}
...
const bundle = await rollup.rollup(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.
Vite Commands
Pour en revenir au modèle Vue, portons une attention particulière au scripts
option.
📁 /packages/create-vite/template-vue/package.json
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
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éveloppementnpm run build
pour créer une version de productionnpm run serve
pour prévisualiser ladite construction de production localement
Les commandes ci-dessus sont mappées aux commandes suivantes :
vite
vite build
vite preview
Comme vous pouvez le voir, le vite
le paquet est là où tout commence.
Vous pouvez avoir une idée des autres outils tiers impliqués en regardant à l’intérieur du package.json
dossier de la vite
emballer.
📁 /packages/vite/package.json
"dependencies": {
"esbuild": "^0.12.17",
"postcss": "^8.3.6",
"resolve": "^1.20.0",
"rollup": "^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 modules consiste à convertir différents formats (modules UMD ou CommonJS) au format ESM standard.
Optimisation sert à 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 le site 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 lecreate-vite
outil - la
create-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’s Constructions rapides comme l’éclair avec Vite cours disponible sur VueMastery.com.
Source link