Fermer

avril 11, 2022

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@derniers'assurera que vous obtenez toujours la dernière version chaque fois que vous le faitesinstallation npmdans ce projet nouvellement créé.)

En passant, vous avez peut-être vu une version obsolète duinitialisercommande.

@vitejs/create-app est obsolète

Comme vous pouvez le voir, l'avertissement d'obsolescence nous dit d'utilisernpm init viteAu 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.

Sélectionnez un nom de projet

Et sélectionnez un modèle à utiliser.

Sélectionnez un modèle

À des fins d'exploration, vous pouvez choisir soitvanilleou alorsvue.

Ensuite, nous allons explorer cecicréer-viteoutil 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.

Dépôt GitHub de Vite

Rendez-vous ensuite à l'intérieur dupaquetsdossier.

Dans le dossier packages

Içi vous pouvez voircréer-appetcré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 depaquetsdossier, 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-vitedossier, vous devriez voir une douzainemodèle-*Dossiers.

📁/packages/create-vite

Dans le dossier create-vite

Comme vous pouvez le voir, Vite prend en charge des modèles pour différents frameworks (et leurs homologues TypeScript).

Tu peux choisirvanilleducréer-viterapide.

Sélectionnez un modèle

Si vous choisissez vanille, il prendra essentiellement les fichiers dans lepackages/template-vanilladossier et clonez-les en tant que votre nouveau projet.

📁/packages/template-vanille

Dans le dossier template-vanilla

Vous pouvez également choisirvueà partir de l'invite :

Sélectionnez vue à partir de l'invite

Si tu choisisvueil clonera les fichiers dans lepackages/template-vuedossier comme votre nouveau projet.

📁/packages/template-vue

Dans le dossier 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 lepaquetsdossier:

📁/paquets

Divers plugins

Noter:plugin-legacyest 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.jsonfichiers du modèle Vue et du modèle vanilla, nous pouvons facilement comprendre pourquoi.

📁/packages/template-vanilla/package.json

Package vanille.json

📁/packages/template-vue/package.json

Modèle-vue package.json

template-vuecontient tout ce quimodèle-vanillea, 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"
  }
  • vueest la bibliothèque principale qui s'exécute pendant l'exécution
  • @vitejs/plugin-vueest le plugin qui est chargé de servir et de regrouper un projet Vue
  • @vue/compiler-sfcest 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-vueLe 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.jsonla@vitejs/plugin-vuepackage 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 levitenoyau 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'essentielvitepackage, 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énariosoption.

📁/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 devpour démarrer un serveur de développement
  • construction d'exécution npmpour créer une version de production
  • npm exécuter servirpour 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, levitele paquet est là où tout commence.

Vous pouvez avoir une idée des autres outils tiers impliqués en regardant à l'intérieur dupackage.jsondossier de laviteemballer.

📁/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,viteutilise 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.

Benchmark des bundlers

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 :

  • lanpm init vitecommande utilise lecréer-viteoutil
  • lacréer-vitepackage 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