Dans la nature dynamique du JavaScript moderne, il est essentiel de se rappeler que « vieux » ne signifie pas nécessairement « dépassé », et que « nouveau » n’implique pas toujours « meilleur ».

La clé du choix de la bonne technologie réside dans son alignement avec les besoins de ton projet. Ce principe résonne fortement lorsqu’il s’agit de regrouper des modules JavaScript. Qu’un bundler ait résisté à l’épreuve du temps ou qu’il soit fraichement introduit, chacun d’entre eux présente des avantages et des limites distincts.

Cet article explore deux outils importants et populaires : Vite et Webpack. Nous évaluons ces bundlers en fonction de leurs caractéristiques, de leurs distinctions, de leurs philosophies architecturales et de la façon dont ils s’intègrent à l’écosystème des développeurs.

Qu’est-ce qu’un module de bundler JavaScript ?

Bundler Bundling
Bundler Bundling

Un bundler JavaScript est un outil utilisé dans le développement web pour combiner plusieurs fichiers JavaScript en un seul fichier, appelé bundle. Il simplifie la gestion du code JavaScript en réduisant le nombre de requêtes que votre application web doit effectuer, ce qui améliore au final les performances.

Prenons l’exemple de deux fichiers JavaScript distincts : module1.js et module2.js. module1.js contient le contenu suivant :

// module1.js
export const greet = (name) => {
    console.log(`Hello, ${name}!`);
}

Et module2.js contient :

// module2.js
export const farewell = (name) => {
    console.log(`Goodbye, ${name}!`);
}

Pour regrouper ces modules en un seul fichier, vous pouvez utiliser un bundler comme Rollup, Webpack ou Parcel. Par exemple, si vous deviez créer un fichier index.js au sein de votre répertoire de projet avec le code ci-dessous :

// index.js
import { greet } from './module1.js';
import { farewell } from './module2.js';

greet('Kinsta');
farewell('Server Troubles');

Lorsque vous utilisez un bundler JavaScript, il combine module1.js, module2.js et index.js en un seul bundle optimisé et adapté à l’utilisation de votre application web.

Alors que les navigateurs web modernes prennent en charge les modules ES et les technologies telles que HTTP/2, qui répondent aux préoccupations liées à la surcharge des requêtes, les bundlers JavaScript restent indispensables pour toute une série d’améliorations du code. Ils effectuent des transformations de code essentielles, notamment la minification, la transpilation et l’optimisation.

En outre, les bundlers de modules JavaScript assurent la compatibilité entre les différents navigateurs. Ils aident à résoudre les problèmes spécifiques aux navigateurs et garantissent une expérience cohérente aux utilisateurs, quel que soit le navigateur web qu’ils choisissent.

Ce processus de regroupement permet non seulement d’accélérer la vitesse de chargement de votre application web, mais aussi de garantir des performances efficaces, en particulier dans les environnements de production. Maintenant que vous comprenez les bundlers JavaScript et leur rôle dans le développement web, passons à Vite et Webpack.

Vite et Webpack : Introduction et vue d’ensemble

Il est clair que Vite et Webpack sont en tête dans le domaine en pleine expansion du développement web moderne, où la gestion des ressources et les bundles optimisés sont vitaux. Mais avant de nous plonger dans une comparaison détaillée, jetons un rapide coup d’œil à ces bundlers et comprenons ce qui les distingue.

Vite : Swift et le développement à la demande

Vite, prononcé « veet », change la donne pour les développeurs web, en donnant la priorité à la vitesse et à l’efficacité. Ce qui distingue Vite, c’est son approche de regroupement à la demande. Au lieu de regrouper au préalable l’ensemble du code et des ressources, Vite exploite les modules ES natifs des navigateurs modernes, en fournissant le code directement au navigateur pendant le développement. Cela permet de remplacer presque instantanément les modules à chaud (HMR) et de réduire les temps de démarrage à froid.

Le serveur de développement de Vite brille par cette approche à la demande, permettant aux développeurs de voir les changements rapidement sans recompilation complète. Il utilise également Rollup, pour des constructions de production efficaces. Par conséquent, Vite offre un développement rapide comme l’éclair et des performances de production solides.

Webpack : Organisé et adaptable

Webpack sert de pierre angulaire au développement web moderne, évoluant régulièrement depuis 2012. Ce qui est génial avec Webpack, c’est la façon dont il organise les composants des sites web. Il optimise les temps de chargement et l’expérience utilisateur en organisant le code en modules.

L’adaptabilité de Webpack est un avantage remarquable. Les développeurs peuvent personnaliser les projets pour des tâches simples ou complexes. Il donne aux développeurs les moyens d’adapter les flux de travail et de construire des processus avec précision.

Similitudes et différences entre Vite et Webpack

Maintenant que nous avons saisi les concepts de base de Vite et de Webpack, explorons plus en détail leurs similitudes et leurs différences. Au fur et à mesure que nous analysons ces bundlers, nous examinons divers aspects afin d’acquérir une compréhension globale de la façon dont ils se comparent et des points sur lesquels chacun excelle.

[Sous-toc]

1. Architecture et philosophie

Les deux bundlers offrent des perspectives uniques sur la construction et l’optimisation des applications web. Ils partagent un point commun dans leur approche des extensions, permettant à la communauté de créer des extensions supplémentaires bénéfiques qui étendent leurs fonctionnalités, ce qui en fait des outils polyvalents pour les développeurs.

La philosophie de base de Vite tourne autour de la légèreté et de l’extensibilité. Il adhère à une stratégie minimaliste, en se concentrant sur les modèles de développement d’applications web les plus courants. Cette approche garantit la maintenabilité du projet à long terme.

Le fait que Vite s’appuie sur un système d’extensions basé sur Rollup empêche le gonflement du noyau en permettant l’implémentation de fonctionnalités par le biais d’extnsions externes. Cela favorise un noyau rationalisé et encourage un écosystème florissant d’extensions bien entretenus. De plus, Vite collabore activement avec le projet Rollup pour maintenir la compatibilité et un écosystème d’extensions partagé.

Webpack donne aux développeurs la possibilité de personnaliser, ce qui leur permet d’adapter les projets à des besoins spécifiques, qu’il s’agisse de tâches élémentaires ou d’entreprises complexes. Il offre une flexibilité dans la configuration de chaque aspect du processus de construction, ce qui en fait un choix de premier ordre pour ceux qui recherchent une expérience de développement personnalisée.

De plus, Webpack introduit l’approche modulaire, similaire à l’assemblage de blocs Lego pour les projets web. Tout dans votre base de code est un module pour Webpack, et il peut exprimer ses dépendances de nombreuses façons. En voici quelques exemples :

  1. Déclaration ES2015 import.
  2. Déclaration CommonJS require().
  3. Déclaration AMD define et require
  4. @import déclaration à l’intérieur d’un fichier css/sass/less.
  5. URL d’une image dans une feuille de style url() ou un fichier HTML <img src="">.

La philosophie de Vite en action

La philosophie architecturale de Vite, qui consiste à être léger et extensible, est évidente dans son approche de la création d’applications web. Supposons que vous développiez une application web et que vous vouliez inclure des fonctions JavaScript modernes telles que les modules ES. Avec Vite, vous pouvez le faire sans effort. Voici un exemple simplifié :

// app.js
import { greet } from './utilities.js';

const worker = new Worker(new URL('./worker.js', import.meta.url));

// Simulate a calculation in the web worker
worker.postMessage({ input: 42 });

worker.onmessage = (e) => {
  const result = e.data.result;
  console.log(`Result from the web worker: ${result}`);
};

const message = greet('Hello, Vite!');
console.log(message);

Dans cet extrait de code, Vite adopte l’utilisation des modules ES et regroupe sans effort le code à la volée, évitant ainsi les étapes de regroupement fastidieuses au cours du développement. Cette approche modulaire te permet de gérer efficacement les dépendances, créant ainsi une base de code facile à maintenir. Cela montre l’engagement de Vite en faveur du minimalisme et des expériences conviviales pour les développeurs.

La philosophie de Webpack en action

La philosophie modulaire de Webpack est particulièrement bénéfique lorsque vous travaillez sur des projets de grande envergure. Imaginez que vous construisiez une application web substantielle avec différents modules JavaScript. Avec Webpack, vous pouvez assembler ces modules de façon transparente, ce qui améliore la lisibilité, la maintenabilité et le temps de chargement du site web. Voici un exemple simplifié :

// webpack.config.js
const path = require('path');

module.exports = {
  entry: './app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /.js$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
};

Dans cet exemple, Webpack vous permet de configurer le processus de construction, d’optimiser le code et de gérer efficacement les ressources. En organisant votre projet en modules et en utilisant des chargeurs comme Babel, vous pouvez écrire un code propre et modulaire qui améliore l’expérience de l’utilisateur. Cela démontre l’engagement de Webpack à fournir de la personnalisation et de la flexibilité, en s’assurant que les développeurs peuvent adapter leurs projets à des besoins spécifiques.

Bien que Vite et Webpack aient tous deux des philosophies architecturales distinctes, ils partagent un engagement commun à repousser les limites du développement web moderne. Vite se concentre sur les modèles de codage modernes, en promouvant les modules ECMAScript (ESM) pour le code source et en encourageant les normes modernes telles que la nouvelle syntaxe Worker pour les travailleurs web.

Webpack, quant à lui, a évolué comme une réponse aux défis présentés par Node.js et CommonJS, conduisant à l’adoption de modules dans le développement web. La collecte automatique des dépendances de Webpack, associée à des améliorations de performance, garantit une expérience transparente pour le développeur.

2. Popularité, communauté et écosystème

Vite et Webpack ont des calendriers distincts, qui façonnent leur popularité et leur communauté.

Comparaison de Vite et Webpack sur Google Trends pour les 5 dernières années.
Comparaison de Vite et Webpack sur Google Trends pour les 5 dernières années.

Vite est un nouveau venu, qui a fait ses débuts en 2020. Malgré son existence relativement brève, Vite a rapidement attiré l’attention, ce qui en fait un acteur prometteur dans le domaine du développement web moderne.

En revanche, Webpack a une longueur d’avance considérable, puisqu’il a été créé en 2012. Le temps qu’il a passé dans l’industrie lui a permis de développer un écosystème mature et une communauté solide.

Comparaison de Vite et Webpack sur npmtrends au cours des 5 dernières années.
Comparaison de Vite et Webpack sur npmtrends au cours des 5 dernières années.

Le graphique ci-dessus de npmtrends illustre la comparaison du nombre de téléchargements entre Vite et Webpack. Il montre clairement que Webpack conserve constamment une position prépondérante en termes de nombre de téléchargements, ce qui souligne sa présence de longue date et l’étendue de son utilisation au sein de la communauté des développeurs.

Comparaison de Vite et Webpack sur star-history.
Comparaison de Vite et Webpack sur star-history.

Lorsque nous examinons les étoiles GitHub à l’aide de star-history, qui est une mesure de la popularité et du soutien de la communauté, nous constatons que Vite peut se targuer d’un nombre impressionnant de 60.318 étoiles, tandis que Webpack maintient une forte présence avec 63.598 étoiles. Ces nombres d’étoiles reflètent la reconnaissance et l’engagement actif dans les deux projets. La croissance rapide de Vite et la popularité soutenue de Webpack en font des atouts précieux dans le paysage du développement web.

3. Configuration et facilité d’utilisation

Vite et Webpack offrent tous deux de nombreuses options de configuration pour adapter votre bundle en fonction de tes besoins spécifiques. Cependant, il existe des différences significatives qui méritent votre attention. Explorons la configuration et la facilité d’utilisation des deux outils.

La configuration simplifiée de Vite

Vite se distingue par sa philosophie zéro-config, conçue pour simplifier votre parcours de développement web. Cela signifie que vous pouvez créer une bibliothèque de composants Vue 3 de base avec un minimum d’efforts. Voici une configuration simple de Vite pour un tel projet :

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
})

Dans l’exemple ci-dessus, nous avons seulement importé et installé l’extension officielle de Vite pour Vue.js. La magie de Vite réside dans sa capacité à auto-détecter les bons réglages pour la plupart des projets.

Complexité de la configuration de Webpack

Webpack, en revanche, a tendance à nécessiter une configuration plus détaillée. Bien qu’il ait évolué vers une approche zéro-config dans les versions récentes, il n’est pas aussi automatique que Vite. Pour Vue 3, une configuration de base de Webpack pourrait ressembler à ceci :

const webpack = require('webpack');
const path = require('path');
const { HotModuleReplacementPlugin } = require('webpack');
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, './build'),
        filename: 'bundle.js',
    },
    module: {
        rules: [
            {
                test: /.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    },
                },
            },
            {
                test: /.vue$/,
                use: {
                    loader: 'vue-loader',
                },
            },
            {
                test: /.css$/,
                use: ['vue-style-loader', 'css-loader'],
            },
        ],
    },
    resolve: {
        alias: {
            vue: 'vue/dist/vue.js',
        },
    },
    plugins: [
    new HotModuleReplacementPlugin(),
    new VueLoaderPlugin(),
    ]
};

Comparée à Vite, la configuration de Webpack implique une configuration plus manuelle. Les complexités comprennent la spécification des chemins d’entrée et de sortie, la configuration des chargeurs pour différents types de fichiers et la configuration des plugins pour des fonctionnalités spécifiques. Décomposons chaque partie de la configuration et soulignons les complexités :

  • Entrée et sortie : entry spécifie le point d’entrée de ton application, où Webpack commencera le regroupement. Dans ce cas, il est défini sur ./src/main.js, en supposant que le fichier JavaScript principal de ton application se trouve dans le répertoire src, tandis que output définit l’endroit où les fichiers regroupés doivent être enregistrés. Le chemin de sortie est résolu à l’aide de path.resolve, et le fichier groupé résultant est nommé bundle.js et enregistré dans le répertoire de construction.
  • Règles des modules : La section module.rules définit la manière dont les différents types de fichiers sont traités. Dans ce cas, il existe des règles pour les fichiers JavaScript (babel-loader pour la transpilation), les composants Vue à fichier unique (vue-loader) et les fichiers CSS (vue-style-loader et css-loader pour la gestion des styles).
  • Configuration des alias : La section resolve.alias définit les alias pour les importations de modules. Dans ce cas, il s’agit de configurer un alias pour Vue vers vue/dist/vue.js.
  • Extensions : La section des extensions comprend HotModuleReplacementPlugin qui permet le remplacement à chaud des modules, une fonctionnalité qui te permet de voir les changements sans recharger complètement la page pendant le développement, tandis queVueLoaderPlugin est nécessaire pour le traitement des composants Vue à fichier unique.

Pour compléter cette section, Vite se démarque en termes de facilité d’utilisation, offrant une configuration simplifiée et une expérience de développement rationalisée. Ses exigences minimales en matière de configuration et l’utilisation de modules ES natifs en font un outil idéal pour les débutants et le développement rapide.

En revanche, la configurabilité étendue de Webpack, bien que bénéfique pour les projets complexes, peut poser des défis aux développeurs débutants. La configuration et la maintenance complexes peuvent ralentir le développement, en particulier pour les petits projets.

4. Serveur de développement

Le serveur de développement joue un rôle crucial dans le flux de travail d’un développeur, influençant l’efficacité et la productivité. Comparons Vite et Webpack, en évaluant leurs performances de serveur de développement et leur facilité d’utilisation afin de trouver l’outil supérieur pour votre projet de développement web.

Configuration du serveur

Vite se distingue par son serveur de développement intégré et prêt à l’emploi, ce qui élimine souvent la nécessité d’une configuration approfondie.

En revanche, Webpack offre de la flexibilité mais nécessite une configuration supplémentaire. Les développeurs peuvent choisir des options telles que le mode Watch de Webpack, webpack-dev-serveret webpack-dev-middleware pour une compilation automatique du code en cas de modification. Cependant, une configuration est généralement nécessaire pour établir et affiner ces options.

Vitesse de démarrage à froid

Les configurations traditionnelles basées sur le bundler impliquent un crawling avide et nécessitent de construire l’ensemble de l’application avant de la servir, ce qui entraine des retards notables, en particulier dans les projets complexes.

Vite révolutionne les démarrages à froid avec une approche fondamentalement différente, réduisant considérablement le temps d’initialisation :

Le temps nécessaire à Esbuild pour créer un paquet de production de 10 copies de la bibliothèque three.js à partir de zéro en utilisant les paramètres par défaut.
Le temps nécessaire à Esbuild pour créer un paquet de production de 10 copies de la bibliothèque three.js à partir de zéro en utilisant les paramètres par défaut. (Source de l’image : Esbuild)
  • Gestion efficace des dépendances: Vite s’appuie sur esbuild, un bundler très performant basé sur Go, pour pré-bundler les dépendances, y compris le JavaScript simple et les gros modules. Dans le cadre de son processus de pré-regroupement, Vite optimise les performances en fusionnant les dépendances ESM avec de nombreux modules internes en un seul module.Par exemple, lodash-es contient plus de 600 modules internes. Lorsque l’on utilise les méthodes traditionnelles et que l’on importe une fonction comme debounce, cela déclenche plus de 600 requêtes HTTP. La solution de Vite consiste à regrouperlodash-es en un seul module, réduisant ainsi les requêtes HTTP à une seule. Cette réduction spectaculaire des requêtes augmente considérablement la vitesse de chargement des pages dans le serveur de développement.

    Graphique du serveur de développement basé sur ESM.
    Graphique du serveur de développement basé sur ESM. (Source de l’image : Vite)

  • Chargement du code source à la demande : Vite utilise des modules ES natifs pour servir le code source, minimisant ainsi la charge et la latence du serveur. La transformation et le chargement du code source s’effectuent à la demande du navigateur, ce qui améliore l’efficacité et réduit les temps d’attente.

    Graphique du serveur de développement basé sur le Bundle.
    Graphique du serveur de développement basé sur le Bundle. (Source de l’image : Vite)

Webpack, quant à lui, adopte une approche basée sur les bundles, en pré-bundlant le code source et les dépendances, ce qui prolonge les temps de démarrage des serveurs pendant le développement. Comparé à l’initialisation efficace de Vite, le temps de configuration du serveur de Webpack est intrinsèquement plus long.

Cependant, l’approche de chargement à la demande de Vite peut introduire un léger retard lorsque les utilisateurs naviguent vers des itinéraires qui nécessitent des données, des CSS et des ressources supplémentaires. Cela est particulièrement perceptible si ces ressources exigent des étapes de regroupement supplémentaires. À l’inverse, la stratégie de Webpack garantit que toutes les données du site sont disponibles, ce qui entraine une navigation plus rapide du navigateur vers les nouvelles pages du serveur de développement.

HMR (Hot Module Replacement)

Vite utilise HMR plutôt que l’ESM natif, ce qui réduit la charge du serveur et la latence en déchargeant le navigateur d’une partie du travail de regroupement. Cela garantit des mises à jour rapides sans rechargement complet de la page, ce qui est crucial pour un retour d’information en temps réel pendant le développement.

Webpack prend également en charge le HMR, ce qui permet des mises à jour en temps réel et préserve l’état de l’application pendant le développement. Cependant, les limites potentielles de l’exploitation des modules ES natifs peuvent entrainer une charge de serveur et une latence plus élevées.

Performance de la mise en cache

La mise en cache est essentielle pour améliorer les performances des applications web, en réduisant les temps de chargement et de construction par la réutilisation des ressources stockées.

La mise en cache dans Vite est gérée par un cache du système de fichiers, qui met à jour les dépendances en fonction des changements dans package.json, lockfiles et vite.config.js. Il optimise les rechargements de page en mettant en cache les demandes de dépendances résolues.

Webpack utilise également la mise en cache du système de fichiers, en effaçant les fichiers modifiés en mode veille, et en purgeant le cache avant chaque compilation en mode sans veille, ce qui nécessite une configuration personnalisée pour une mise en cache optimale.

Pour conclure la comparaison des serveurs de développement, Vite et Webpack offrent des approches distinctes pour les serveurs de développement :

  • Vite fournit un serveur de développement prêt à l’emploi, minimisant les frais généraux de configuration.
  • Webpack offre une flexibilité de configuration mais nécessite une installation supplémentaire.
  • Vite excelle en matière de vitesse de démarrage à froid et de HMR pour les changements de code rapides.
  • Webpack est plus performant en matière de vitesse de navigation dans le navigateur grâce aux données de site pré-regroupées.
  • Les deux prennent en charge HMR mais ont des mécanismes de service de modules différents.
  • Vite gère la mise en cache locale et du navigateur de manière transparente, tandis que Webpack nécessite une configuration personnalisée.

5. Temps de construction et taille du paquet

Comparons maintenant le temps de construction et la taille des paquets entre Vite et Webpack, en considérant la construction de développement, les changements à chaud pendant le serveur de développement et la construction de production.

Notre environnement de test comprend :

  • L’exécution des tests sur un MacBook Air avec une puce Apple M1 et un GPU à 8 cœurs.
  • Un projet Vue 3 d’échelle moyenne comprenant 10 composants, utilisant Vuex pour la gestion des états et Vue Router pour le routage.
  • Incorporation de feuilles de style (CSS/SASS), de ressources telles que des images et des polices, ainsi qu’un nombre modéré de dépendances.

Commençons par comparer le temps de regroupement :

Vite [v4.4.11] Webpack [v5.89.0]
Première construction de Dev 376ms 6s
Changement à chaud Instantané 1.5s
Construction du produit 2s 11s

Vite ressort comme le grand gagnant de la vitesse de regroupement, en réduisant drastiquement les temps de construction. Bien que Webpack offre la configurabilité et des outils de développement robustes, il est à la traîne par rapport à Vite.

Vite [v4.4.11] (Ko) Webpack [v5.89.0] (Ko)
Taille du Prod Bundle 866 Ko 934ko

Ces chiffres sont basés sur une application Vue.js de taille moyenne avec un nombre modéré de dépendances. La taille réelle du bundle peut varier en fonction de la complexité du projet, des dépendances et des techniques d’optimisation.

La petite taille du bundle de Vite est due à son pré-bundling efficace avec esbuild et les modules ES natifs.

La taille du bundle de Webpack peut être optimisée grâce à diverses options de configuration et extensions, mais il produit généralement des bundles plus volumineux en raison de son processus de bundling complet.

6. Optimisation de la construction

Lorsqu’il s’agit d’optimiser le processus de construction dans le développement web moderne, Vite et Webpack proposent des approches distinctes, chacune avec son propre ensemble de fonctionnalités et de capacités. Plongeons dans l’optimisation de la construction en explorant les principales différences entre Vite et Webpack.

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 importations directes dans le HTML construit. Cela permet d’améliorer les temps de chargement en préchargeant efficacement les modules selon les besoins.

Ainsi, cela peut ressembler à ceci lors de l’inspection de la page :

<!-- Vite - Module Preloading -->
<link rel="modulepreload" href="/module-a.js">

Webpack ne prenait pas nativement en charge les indices du navigateur pour les ressources. Mais à partir de Webpack v4.6.0, il a inclus la prise en charge du prefetching et du preloading. L’utilisation d’une directive en ligne lors de la déclaration des importations permet à Webpack de produire un indice de ressource, qui fournit au navigateur des informations sur le moment où il doit charger le fichier importé. Par exemple :

import(/* webpackPreload: true */ '/module-a.js');

Ceci produira :

<!-- Webpack - Manual Module Preloading -->
<link rel="preload" as="script" href="/module-a.js">

Fractionnement du code CSS

Vite se distingue par son approche rationalisée du découpage du code CSS. Il extrait automatiquement le CSS utilisé par les modules dans les morceaux asynchrones et génère des fichiers séparés. Cela signifie que seul le CSS nécessaire est chargé via une balise <link> lorsque le morceau asynchrone associé est chargé.

Vite s’assure notamment que le bloc asynchrone n’est évalué qu’après le chargement du CSS, ce qui permet d’éviter les Flash of Unstyled Content (FOUC). Comme cette fonction est préconfigurée, vous pouvez continuer à importer vos fichiers CSS sans aucune étape supplémentaire :

import './main.css';

Webpack offre de la flexibilité mais nécessite plus de configuration pour le fractionnement du code CSS. Il permet aux développeurs de fractionner le CSS à l’aide de diverses extensions et options de configuration, comme par ex. mini-css-extract-plugin.

// Webpack - CSS Code Splitting
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

Fractionnement du code et chargement de morceaux

Le fractionnement du code est une technique fondamentale utilisée pour diviser ton code en morceaux plus petits et plus faciles à gérer, en ne chargeant que ce qui est nécessaire précisément quand c’est nécessaire. Cette pratique réduit considérablement les temps de chargement initiaux et préserve les ressources.

L’approche de Vite en matière de découpage

Dans certains cas, Vite utilise Rollup pour diviser automatiquement le code en morceaux distincts, comme le chargement dynamique ou les points d’entrée multiples, et il existe un moyen d’indiquer explicitement à Rollup quels modules doivent être divisés en morceaux distincts grâce à l’option output.manualChunks.

Outre la fonction préconfigurée de découpage du code de Vite, Vite prend également en charge les importations dynamiques avec des variables :

const module = await import(`./dir/${kinsta}.js`)

Vite permet également aux développeurs de diviser les morceaux des vendeurs à l’aide de l’option officielle splitVendorChunkPlugin():

import { splitVendorChunkPlugin } from 'vite'
export default defineConfig({
  plugins: [splitVendorChunkPlugin()],
})

Avec toutes ces importations dynamiques et ce fractionnement du code, il est courant que le code soit structuré en modules ou en morceaux, et certains de ces modules sont partagés entre différentes parties d’une application web. Vite reconnaît les morceaux communs et optimise le processus de chargement. Pour mieux comprendre cela, jetons un coup d’œil à l’exemple tiré de la documentation officielle de Vite.

Un graphique qui affiche les chunks communs nécessaires dans deux chunks asynchrones.
Un graphique qui affiche les chunks communs nécessaires dans deux chunks asynchrones. (Image source : Vite)

Sans optimisation, lorsqu’un utilisateur ouvre une section d’une application web, appelons-la section A, qui repose sur le code partagé Common Chunk C, le navigateur commence par récupérer la section A. En analysant la section A, il se rend compte qu’il a besoin du Common Chunk C. Cela nécessite un aller-retour supplémentaire sur le réseau, ce qui peut ralentir le chargement initial de la page :

Entry (Section A) ---> async chunk A ---> common chunk C

Vite, en revanche, utilise une fonction sophistiquée appelée optimisation du chargement des morceaux asynchrones. Il n’attend pas que le navigateur découvre ses besoins ; au contraire, il s’y prépare de manière proactive. Lorsqu’un utilisateur demande la section A, Vite envoie simultanément la section A et le bloc commun C. Cette recherche parallèle des morceaux nécessaires accélère considérablement le processus de chargement :

Entry (Section A) ---> (async chunk A + common chunk C)

Mais cela ne s’arrête pas là. Le Common Chunk C peut avoir ses propres dépendances, ce qui pourrait entrainer d’autres allers-retours dans un scénario non optimisé. Vite ne néglige pas cet aspect. Il analyse rigoureusement ces dépendances et s’assure que tout ce qui est nécessaire, quelle que soit sa profondeur, est chargé efficacement en une seule fois. Cela élimine la nécessité d’effectuer des allers-retours supplémentaires sur le réseau, garantissant ainsi une application web très réactive.

L’approche asynchrone du chargement de morceaux de Vite optimise le processus de chargement en allant chercher et en servant de manière proactive tous les morceaux de code nécessaires en parallèle. Cette élimination des allers-retours supplémentaires sur le réseau se traduit par une expérience web plus rapide. Cela revient à fournir un itinéraire de voyage bien préparé à ton navigateur, en veillant à ce qu’il reçoive toutes les ressources nécessaires sans retards inutiles.

L’approche de Webpack pour diviser le code

En ce qui concerne Webpack, il existe trois techniques générales disponibles pour le fractionnement du code :

  1. Les points d’entrée : C’est la façon la plus simple de scinder un morceau de code. Nous pouvons simplement définir un nouveau point d’entrée dans le fichier de configuration et Webpack avec l’ajouter comme un morceau séparé :
    const path = require('path');
     module.exports = {
      mode: 'development',
      entry: {
        index: './src/index.js',
        another: './src/separate-module.js',
      },
       output: {
        filename: '[name].bundle.js',
         path: path.resolve(__dirname, 'dist'),
       },
     };

    Cependant, cette approche a des limites. Si des modules sont importés dans différents chunks d’entrée, ils se retrouvent dans les deux bundles, ce qui entraine une duplication du code. De plus, elle n’est pas très adaptable pour diviser la logique de l’application principale lorsque cela est nécessaire.

  2. Empêcher la duplication : Une autre approche consiste à utiliser les dépendances entry ou SplitChunksPlugin Voici un exemple de la façon dont vous pouvez configurer la division du code à l’aide des dépendances entry:
    const path = require('path');
    
     module.exports = {
       mode: 'development',
       entry: {
         index: {
           import: './src/index.js',
           dependOn: 'shared',
         },
         another: {
           import: './src/another-module.js',
           dependOn: 'shared',
         },
         shared: 'lodash',
       },
       output: {
         filename: '[name].bundle.js',
         path: path.resolve(__dirname, 'dist'),
       },
      optimization: {
        runtimeChunk: 'single',
      },
     };
  3. Importations dynamiques: Enfin, Webpack prend en charge les importations dynamiques, une fonctionnalité précieuse pour le chargement de code à la demande. Il utilise une syntaxe conforme à la proposition ECMAScript pour les importations dynamiques. Cette méthode est plus souple et plus granulaire, ce qui la rend adaptée à divers scénarios de fractionnement du code.
    const { default: _ } = await import('lodash');

    Nous pouvons également utiliser les commentaires magiques de Webpack pour définir un nom pour le chunk, le charger en différé, spécifier les exportations de modules et définir une priorité de récupération :

    import(
      /* webpackChunkName: "my-chunk-name" */
      /* webpackMode: "lazy" */
      /* webpackExports: ["default", "named"] */
      /* webpackFetchPriority: "high" */
      'module'
    );

Tree-Shaking

Le tree-shaking est une technique d’optimisation cruciale que Vite et Webpack utilisent pour réduire la taille de vos bundles JavaScript.

Vite utilise Rollup, qui permet non seulement d’utiliser des modules ES mais aussi d’analyser statiquement le code que vous importez. Cela signifie que Vite peut exclure toutes les parties d’un module que vous n’utilisez pas, ce qui permet de réduire la taille des paquets. Par exemple, si vous avez un module avec plusieurs fonctions mais que vous n’en utilisez qu’une seule, Vite n’inclura que cette fonction dans le paquet. Voici un exemple simple :

  • Sans utiliser les modules ES, si vous voulez importer ajax à partir de ./utils.js, vous devrez importer tout le fichier.
    const utils = require('./utils');
    const query = 'Kinsta';
    // Use the 'ajax' method of the 'utils' object
    utils.ajax(`https://api.example.com?search=${query}`).then(handleResponse);
  • L’utilisation des modules ES, en revanche, vous permet d’importer uniquement ce dont vous avez besoin, ce qui se traduit par des bibliothèques et des applications plus légères, plus rapides et moins complexes. Comme Vite utilise des déclarations explicites import et export, il peut effectuer un tree-shaking très efficace sans dépendre uniquement d’un minificateur automatisé pour détecter le code inutilisé.
    import { ajax } from './utils';
    const query = 'Kinsta';
    // Call the 'ajax' function
    ajax(`https://api.example.com?search=${query}`).then(handleResponse);

Enfin, pour Vite, nous pouvons utiliser les options préconfigurées de Rollup pour le tree-shaking.

Webpack prend également en charge le tree-shaking, mais son mécanisme est différent. Il analyse les dépendances de votre code et supprime les parties inutilisées pendant le processus de regroupement. Bien que cette méthode soit efficace, elle n’est peut-être pas aussi approfondie que l’approche de Vite, en particulier lorsqu’il s’agit de gérer des modules ou des bibliothèques de grande taille.

De plus, selon la documentation de Webpack. Nous devons marquer les fichiers comme étant sans effets secondaires pour garantir qu’il ne supprimera aucun code dont un autre code en production s’appuie sur lui.

Pour cela, il faut utiliser la propriété sideEffects package.json:

{
  "name": "kinsta-app",
  "sideEffects": false
}

Il est intéressant de noter qu’une option de configuration similaire pour définir les effets de bord existe également dans les options de Rollup de Vite.

7. Gestion des ressources statiques

Les ressources statiques, telles que les images, les polices et autres fichiers, font partie intégrante du développement web. Vite et Webpack abordent la gestion de ces ressources différemment, chacune ayant ses propres forces et optimisations.

Traitement des ressources par Vite

L’approche de Vite en matière de gestion des ressources statiques est rationalisée et efficace. Lorsque vous importez une ressource statique, Vite renvoie l’URL publique résolue lorsqu’elle est servie. Par exemple, lorsque vous importez une image comme celle-ci :

import kinstaImage from './kinsta-image.png';

Pendant le développement, imgUrl sera résolu en /img.png. Dans la version de production, il deviendra quelque chose comme /assets/img.2d8efhg.png, optimisé pour la mise en cache et la performance.

Vite peut gérer ces importations avec des chemins publics absolus ou des chemins relatifs, ce qui lui permet de s’adapter aux besoins de votre projet. Ce comportement s’étend aux références URL dans les CSS, que Vite gère de manière transparente.

De plus, si vous utilisez Vite dans un composant à fichier unique (SFC) Vue, les références aux ressources dans les modèles sont automatiquement converties en importations, ce qui simplifie votre flux de travail de développement.

La gestion des ressources de Vite va encore plus loin en détectant les types de fichiers d’images, de médias et de polices courants, qu’il traite comme des ressources. Ces ressources sont incluses dans le graphe des ressources de construction, obtiennent des noms de fichiers hachés et peuvent être traités par des extensions à des fins d’optimisation.

Traitement des ressources par Webpack

Webpack, quant à lui, a une approche différente de la gestion des ressources statiques. Avec Webpack, vous importez les actifs comme vous le faites habituellement :

import kinstaImage from './kinsta-image.png';

Webpack traite cette importation en ajoutant l’image à votre répertoire de sortie et en vous fournissant l’URL finale de l’image. Cela facilite le travail avec les ressources et fonctionne également dans votre CSS en utilisant url('./my-image.png'). Le site css-loader de Webpack reconnaît qu’il s’agit d’un fichier local et remplace le chemin par l’URL finale de l’image dans le répertoire de sortie. Il en va de même lorsque vous utilisez le html-loader pour<img src="./kinsta-image.png" />.

Les modules de ressources de Webpack introduits dans la version 5 peuvent gérer différents types de ressources, et pas seulement des images. Par exemple, vous pouvez configurer Webpack pour qu’il gère les fichiers de polices de caractères :

module.exports = {
  module: {
    rules: [
      {
        test: /.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
      },
    ],
  },
};

Cette configuration vous permet d’incorporer des polices dans votre projet via une déclaration @font-face.

8. Prise en charge des sites statiques

Les sites statiques offrent de nombreux avantages, tels que des temps de chargement rapides, une meilleure sécurité et un hébergement simplifié. Un site statique est composé de HTML, de CSS et de JavaScript, ce qui permet d’offrir une expérience utilisateur simplifiée et une diffusion efficace du contenu. Vite et Webpack peuvent tous deux aider les développeurs à générer des sites statiques performants, mais pas avec la même efficacité.

L’approche de Vite en matière de génération de sites statiques

Vite propose des instructions dédiées au déploiement de sites statiques, en capitalisant sur son approche rationalisée du développement et du déploiement, particulièrement adaptée aux sites statiques.

Un autre aspect intéressant de Vite est qu’il dispose d’un script preview, qui aide les développeurs à lancer leur version de production localement pour voir le résultat final de leur application en action. Cette fonction permet aux développeurs de tester et de prévisualiser leur version de production avant de la déployer sur un serveur réel.

Cependant, il est important de noter que le script preview de Vite est destiné à la prévisualisation de la version locale et n’est pas conçu pour servir de serveur de production. Cela signifie que c’est un excellent outil pour les développeurs qui souhaitent tester leurs applications avant de les déployer, mais qu’il n’est pas adapté à l’hébergement d’un site de production en direct.

{
  "scripts": {
    "preview": "vite preview --port 3000"
  }
}

Il convient de souligner VitePress, l’un des outils les plus puissants de l’écosystème Vite. VitePress est un générateur de sites statiques (SSG) qui permet de créer rapidement des sites web axés sur le contenu. VitePress prend votre texte source basé sur Markdown, applique un thème et produit des pages HTML statiques qui peuvent être rapidement déployées gratuitement sur Kinsta.

L’approche de Webpack en matière de génération de sites statiques

Bien que Webpack ne soit pas spécifiquement conçu pour la génération de sites statiques, il peut être utilisé pour créer des sites statiques grâce à diverses extensions et configurations. Cependant, le processus est généralement plus complexe et moins rationalisé par rapport à Vite. L’objectif principal de Webpack réside dans le regroupement et l’optimisation des modules JavaScript, ce qui en fait un outil puissant pour la création d’applications web complexes.

9. Prise en charge du rendu côté serveur

Le rendu côté serveur (SSR) est une technique de développement web qui rend les pages web sur le serveur et envoie le HTML entièrement rendu au navigateur du client. Comparons les deux bundlers en termes de prise en charge du SSR :

  • Vite : Vite prend en charge le rendu côté serveur, offrant ainsi une approche rationalisée pour les applications qui nécessitent la RSS. Avec Vite, les frameworks frontend qui peuvent exécuter la même application dans Node.js, la pré-rendre en HTML, puis l’hydrater côté client peuvent être intégrés de manière transparente. Cela fait de Vite un excellent choix pour les applications qui exigent des capacités de RSS, en fournissant aux développeurs les outils dont ils ont besoin pour optimiser leurs applications rendues par le serveur.
  • Webpack: Webpack peut également être utilisé pour le rendu côté serveur. Cependant, la mise en œuvre du RSS avec Webpack a tendance à être plus complexe et nécessite une compréhension plus approfondie de la configuration et de l’installation. Les développeurs peuvent avoir besoin d’investir du temps supplémentaire dans la configuration du SSR avec Webpack par rapport à l’approche plus rationalisée proposée par Vite.

.

10. Prise en charge de JSON

Vite et Webpack prennent tous deux en charge l’importation de fichiers JSON. Sauf dans Vite, les importations nommées JSON sont également prises en charge pour faciliter le tree-shaking.

// import an object
import json from './example.json'
// import a root field as named exports.
import { test } from './example.json'

11. Vue.js et prise en charge de JSX

Vue.js, un framework JavaScript de premier plan, suit la syntaxe SFC (Single File Component), ce qui simplifie le processus de création d’interfaces utilisateur. En revanche, JSX est une extension de la syntaxe JavaScript, principalement utilisée dans React, permettant aux développeurs de définir des structures d’interface utilisateur à l’aide de balises et d’éléments de type HTML.

Vite offre une prise en charge de Vue.js de premier ordre grâce à des extensions officielles qui intègrent de manière transparente Vite à Vue. Il gère également les fichiers JSX (.jsx et .tsx) dès le départ, grâce à sa transpilation esbuild. Les utilisateurs de Vue.js peuvent utiliser le plugin@vitejs/plugin-vue-jsx , conçu pour Vue 3, qui offre des fonctionnalités telles que HMR, la résolution globale des composants, les directives et les emplacements.

Dans les cas où JSX est utilisé avec d’autres frameworks comme React ou Preact, Vite permet de configurer des jsxFactory et jsxFragment personnalisés via l’option esbuild. Ce niveau de flexibilité est précieux pour les projets qui nécessitent une personnalisation de JSX.

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  esbuild: {
    jsxFactory: 'h',
    jsxFragment: 'Fragment',
  },
})

En revanche, Webpack ne dispose pas d’une prise en charge native de Vue.js ou de toute autre bibliothèque ou framework spécifique. Les développeurs doivent installer les chargeurs et les dépendances pertinents pour configurer un projet pour un framework JavaScript moderne, ce qui en fait un processus plus manuel et potentiellement complexe.

12. Prise en charge de TypeScript

Vite offre une prise en charge native de TypeScript, ce qui permet d’incorporer de façon transparente les fichiers .ts dans les projets. Il utilise le transpondeur esbuild pour une transformation rapide du code pendant le développement. Vite se concentre sur la transpilation et non sur la vérification des types. Il s’attend à ce que votre IDE et votre processus de construction gèrent la vérification du type.

Webpack ne prend pas en charge TypeScript en mode natif, les développeurs doivent donc configurer manuellement TypeScript à l’aide du compilateur typescript et de la commande ts-loader. Cela nécessite de configurer tsconfig.json pour spécifier les options TypeScript. Une fois configuré, Webpack utilise ts-loader pour compiler le code TypeScript. Bien que cela introduise des étapes de configuration supplémentaires, cela offre une certaine flexibilité et une compatibilité avec d’autres fonctionnalités de Webpack.

13. Prise en charge de l’importation Glob

Vite prend en charge Glob Import. Cette fonctionnalité est utilisée pour importer plusieurs modules depuis le système de fichiers viaa la fonction import.meta.glob:

const modules = import.meta.glob('./kinsta/*.js')

Ceci produira un résultat :

const modules = {
  './kinsta/isCool.js': () => import('./kinsta/isCool.js'),
  './kinsta/isAwesome.js': () => import('./kinsta/isAwesome.js'),
  './kinsta/isFun.js': () => import('./kinsta/isFun.js'),
}

Vite prend également en charge Glob Import As, pour importer des fichiers sous forme de chaînes de caractères en utilisant import.meta.glob. Voici un exemple de code :

const modules = import.meta.glob('./kinsta/*.js', { as: 'raw', eager: true })

Qui sera transformé en ceci :

const modules = {
  './kinsta/rocks.js': 'export default "rocks"n',
  './kinsta/rules.js': 'export default "rules"n',
}

{ as: 'url' } est également pris en charge pour le chargement des actifs sous forme d’URL.

Alors que Webpack nécessite des extensions supplémentaires comme webpack-import-glob-loader et glob-import-loader pour effectuer des importations globales. Ils permettront d’étendre cette fonctionnalité :

import modules from "./test/**/*.js";

En ceci :

import * as moduleOne from "./foo/1.js";
import * as moduleTwo from "./test/bar/2.js";
import * as moduleThree from "./test/bar/3.js";

var modules = [moduleOne, moduleTwo, moduleThree];

14. Prise en charge des workers web

Les workers web sont essentiels pour exécuter des tâches lourdes en arrière-plan sans geler la page web principale. Voici comment Vite et Webpack les gèrent :

Vite facilite l’utilisation des workers web. Vous créez un fichier de worker web séparé, vous l’importez dans votre code principal et vous communiquez avec lui. Vite propose deux façons d’importer un worker dans votre code principal :

  1. new Worker() et les nouveaux constructeurs SharedWorker():
    const worker = new Worker(new URL('./worker.js', import.meta.url));
    
    // OR
    
    const worker = new SharedWorker(new URL('./worker.js', import.meta.url));
  2. Directement importés en ajoutant ?worker ou ?sharedworker:
    import MyWorker from './worker?worker';
    
    const worker = new MyWorker();
    
    myWorker.postMessage('Hello from the main thread!');

    Webpack prend également en charge les workers web, et à partir de Webpack 5, nous ne sommes pas obligés d’utiliser un chargeur pour utiliser les workers.

    Const worker = new Worker(new URL('./worker.js', import.meta.url));

15. Capacité de développement de bibliothèques

Les bibliothèques et les frameworks donnent aux développeurs les moyens de créer et de partager des outils qui accélèrent le développement des applications web. Vite et Webpack offrent tous deux des solutions robustes.

Vite fait passer le développement de bibliothèques à un niveau supérieur grâce à son mode Bibliothèque spécialisé, qui simplifie le processus de création de bibliothèques axées sur le navigateur. De plus, Vite offre la flexibilité d’externaliser des dépendances spécifiques, comme Vue ou React, que vous préférez peut-être ne pas inclure dans votre bundle de bibliothèques.

Webpack, quant à lui, est un bundler polyvalent qui s’adresse également aux auteurs de bibliothèques. Si vous utilisez Webpack pour créer une bibliothèque JavaScript, vous pouvez le configurer pour qu’il réponde à vos besoins uniques en matière de regroupement de bibliothèques. Il vous permet de définir comment le code de votre bibliothèque doit être empaqueté, ce qui en fait un choix approprié pour la construction d’un large éventail de bibliothèques.

16. Compatibilité avec les navigateurs

Vite donne la priorité aux navigateurs modernes, en ciblant ceux qui prennent en charge les modules ES natifs, tels que Chrome >=87, Firefox >=78, Safari >=14, et Edge >=88. Des cibles personnalisées peuvent également être définies via build.targetà partir de es2015. Les anciens navigateurs sont pris en charge par l’intermédiaire de @vitejs/plugin-legacy.

Webpack prend en charge tous les navigateurs compatibles avec ES5 (à l’exception d’IE8 et des versions inférieures). Pour s’adapter aux navigateurs plus anciens, des polyfills sont nécessaires pour des fonctionnalités telles que import() et require.ensure().

En termes de compatibilité avec les navigateurs, les deux sont excellents, mais votre choix doit dépendre du public cible de votre projet et des capacités de son navigateur.

Résumé

Vite offre un développement rapide comme l’éclair avec des mises à jour rapides et des options de personnalisation étendues grâce à son approche native des modules ES. À l’inverse, Webpack, connu pour sa robustesse et son large écosystème, excelle dans les builds de production mais nécessite une courbe d’apprentissage plus raide.

Pour choisir entre Vite et Webpack, considérez les besoins du projet et votre familiarité avec les subtilités de la configuration. Les deux ont leurs avantages, alors choisissez en fonction des exigences spécifiques de votre projet.

Enfin, si vous envisagez d’héberger vos projets alimentés par Vite, vous pouvez explorer l’hébergement de sites statiques de Kinsta, qui offre une solution robuste et efficace pour les développeurs web.

Partagez votre bundler préféré et les considérations clés qui ont guidé votre choix dans la section des commentaires ci-dessous.

Mostafa Said

Je suis Mostafa, un développeur full-stack avec un don pour tout ce qui concerne Laravel, Inertia, et les frameworks JavaScript. Quand je ne code pas, vous pouvez me trouver en train de partager mes connaissances par le biais de tutoriels, de participer à des hackathons (et d'en gagner quelques-uns), et de répandre l'amour de la technologie en enseignant ce que j'ai appris.