Fermer

mai 10, 2022

Explorer Vite à travers son code source

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.

@vitejs/create-app est obsolète

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.

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 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.

Dépôt GitHub de Vite

Rendez-vous ensuite à l’intérieur du packages dossier.

Dans le dossier packages

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

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 choisir vanilla du create-vite rapide.

Sélectionnez un modèle

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

Dans le dossier template-vanilla

Vous pouvez également choisir vue à partir de l’invite :

Sélectionnez vue à partir de l'invite

Si tu choisis vueil clonera les fichiers dans le packages/template-vue dossier 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’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

Divers plugins

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

Package vanille.json

📁 /packages/template-vue/package.json

Modèle-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.jsonla @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éveloppement
  • npm run build pour créer une version de production
  • npm 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.

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 :

  • la npm init vite commande utilise le create-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