Erste Schritte mit Webpack

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Moderne Browser bieten gute Unterstützung für JavaScript-Module, aber Modul-Bundler wie Webpack bleiben ein kritischer Bestandteil der JavaScript-Toolchain. Lassen Sie uns einen tiefen Blick darauf werfen, was Webpack ist und wie Sie es in Ihrem Entwicklungsworkflow verwenden.

In den frühen Tagen, als die Modularität in JavaScript eingeführt wurde, gab es keine native Unterstützung für die Ausführung von Modulen im Browser. Die Unterstützung für modulare Programmierung wurde in Node.js mithilfe des CommonJS-Blueprints implementiert und von denjenigen übernommen, die JavaScript zum Erstellen serverseitiger Anwendungen verwenden.

Es hatte auch Aussichten für große Webanwendungen, da Entwickler Namespace-Kollisionen vermeiden und besser wartbare Codebasen aufbauen konnten, indem sie Code in einem modulareren Muster schrieben. Aber es gab noch eine Herausforderung: Module konnten nicht innerhalb von Webbrowsern verwendet werden, in denen normalerweise JavaScript ausgeführt wurde.

Um dieses Problem zu lösen, wurden Modul-Bundler wie Webpack, Parcel, Rollup und auch der Closure Compiler von Google geschrieben, um optimierte Bundles Ihres Codes für den Browser Ihres Endbenutzers zum Herunterladen und Ausführen zu erstellen.

Was bedeutet es, Ihren Code zu „bündeln“?

Das Bündeln von Code bezieht sich auf das Kombinieren und Optimieren mehrerer Module zu einem oder mehreren produktionsbereiten Bündeln . Das hier erwähnte Bündel kann besser als Endprodukt des gesamten Bündelprozesses verstanden werden.

In diesem Artikel konzentrieren wir uns auf webpack, ein von Tobias Koppers geschriebenes Tool, das sich im Laufe der Zeit zu einem wichtigen Tool innerhalb der JavaScript-Toolchain entwickelt hat, das häufig in großen und kleinen Projekten verwendet wird.

Hinweis: Um von diesem Artikel zu profitieren, sollten Sie mit JavaScript-Modulen vertraut sein. Außerdem muss Node auf Ihrem lokalen Computer installiert sein, damit Sie Webpack lokal installieren und verwenden können.

Was ist Webpack?

webpack ist ein stark erweiterbarer und konfigurierbarer statischer Modulbundler für JavaScript-Anwendungen. Aufgrund seiner Erweiterbarkeit können Sie externe Ladeprogramme und Plugins anschließen, um Ihr Endziel zu erreichen.

Wie in der Abbildung unten gezeigt, durchläuft webpack Ihre Anwendung von einem Root-Einstiegspunkt aus , erstellt einen Abhängigkeitsgraphen, der aus Abhängigkeiten besteht, die direkt oder indirekt auf die Root-Datei wirken, und erzeugt optimierte Bündel der kombinierten Module.

Abbildung des Webpack-Abhängigkeitsdiagramms
Eine Veranschaulichung des Abhängigkeitsdiagramms, das von Webpack ausgehend von einem Einstiegspunkt generiert wird. (Große Vorschau)

Um zu verstehen, wie Webpack funktioniert, müssen wir einige der verwendeten Terminologien verstehen (lesen Sie das Webpack-Glossar). Diese Terminologie wird häufig in diesem Artikel verwendet und wird auch häufig in der Webpack-Dokumentation erwähnt.

  • Brocken
    Ein Chunk bezieht sich auf den aus Modulen extrahierten Code. Dieser Code wird in einer Chunk-Datei gespeichert . Chunks werden häufig verwendet, wenn Code-Splitting mit Webpack durchgeführt wird.
  • Module
    Module sind heruntergebrochene Teile Ihrer Anwendung, die Sie importieren, um eine bestimmte Aufgabe oder Funktion auszuführen. Webpack unterstützt Module, die mit der ES6-, CommonJS- und AMD-Syntax erstellt wurden.
  • Vermögenswerte
    Der Begriff Assets wird häufig in Webpacks und anderen Bundlern im Allgemeinen verwendet. Es bezieht sich auf die statischen Dateien , die während des Erstellungsprozesses gebündelt werden. Diese Dateien können alles sein, von Bildern über Schriftarten bis hin zu Videodateien. Wenn Sie den Artikel weiter unten lesen, werden Sie sehen, wie wir Loader verwenden, um mit verschiedenen Asset-Typen zu arbeiten.

Empfohlene Lektüre : Webpack - Eine ausführliche Einführung

Nachdem wir verstanden haben, was Webpack ist und welche Terminologie es verwendet, sehen wir uns an, wie sie beim Zusammenstellen einer Konfigurationsdatei für ein Demoprojekt angewendet werden.

Hinweis : Sie müssen auch webpack-cli installiert haben, um webpack auf Ihrem Computer verwenden zu können. Wenn es nicht installiert ist, werden Sie von Ihrem Terminal aufgefordert, es zu installieren.

Webpack-Konfigurationsdateien

Neben der Verwendung des webpack-cli von einem Terminal aus können Sie webpack auch über eine Konfigurationsdatei in Ihrem Projekt verwenden. Aber mit den neueren Versionen von Webpack können wir es in unserem Projekt ohne Konfigurationsdatei verwenden. Wir können webpack als Wert eines der Befehle in unserer Datei package.json “ verwenden – ohne Flag. Auf diese Weise geht Webpack davon aus, dass sich die Einstiegspunktdatei Ihres Projekts im src -Verzeichnis befindet. Es bündelt die Eintragsdatei und gibt sie im dist -Verzeichnis aus.

Ein Beispiel ist die Beispieldatei package.json unten. Hier verwenden wir webpack, um die Anwendung ohne Konfigurationsdatei zu bündeln:

 { "name" : "Smashing Magazine", "main": "index.js", "scripts": { "build" : "webpack" }, "dependencies" : { "webpack": "^5.24.1" } }

Wenn Sie den build-Befehl in der obigen Datei ausführen, bündelt webpack die Datei im Verzeichnis src/index.js und gibt sie in einer main.js -Datei in einem dist -Verzeichnis aus. webpack ist jedoch viel flexibler als das. Wir können den Einstiegspunkt ändern , den Ausgabepunkt anpassen und viele andere Standardverhalten verfeinern, indem wir eine Konfigurationsdatei mit dem Flag -- config bearbeiten.

Ein Beispiel ist der modifizierte Build-Befehl aus der obigen Datei package.json :

 "build" : "webpack --config webpack.config.js"

Oben haben wir das Flag --config hinzugefügt und eine webpack.config.js als Datei mit der neuen Webpack-Konfiguration angegeben.

Die Datei webpack.config.js existiert jedoch noch nicht. Also müssen wir es in unserem Anwendungsverzeichnis erstellen und den folgenden Code unten in die Datei einfügen.

 # webpack.config.js const path = require("path") module.exports = { entry : "./src/entry", output : { path: path.resolve(__dirname, "dist"), filename: "output.js" } }

Die obige Datei konfiguriert webpack immer noch, um Ihre JavaScript-Datei zu bündeln, aber jetzt können wir anstelle des von webpack verwendeten Standardpfads einen benutzerdefinierten Eingabe- und Ausgabedateipfad definieren.

Ein paar Dinge, die Sie bei einer Webpack-Konfigurationsdatei beachten sollten:

  • Eine Webpack-Konfigurationsdatei ist eine JavaScript-Datei, die als JavaScript-CommonJS-Modul geschrieben ist.
  • Eine Webpack-Konfigurationsdatei exportiert ein Objekt mit mehreren Eigenschaften. Jede dieser Eigenschaften wird als Option zum Konfigurieren von Webpack beim Bündeln Ihres Codes verwendet. Ein Beispiel ist die mode :
    • mode
      In der Konfiguration wird diese Option verwendet, um den NODE_ENV Wert während des Bündelns festzulegen. Es kann entweder einen production oder einen development haben. Wenn nichts angegeben ist, ist es standardmäßig none . Es ist auch wichtig zu beachten, dass Webpack Ihre Assets basierend auf dem mode unterschiedlich bündelt. Beispielsweise speichert webpack Ihre Bundles automatisch im Entwicklungsmodus, um die Bundle-Zeit zu optimieren und zu reduzieren. Sehen Sie sich den Modus-Abschnitt der Webpack-Dokumentation an, um ein Änderungsprotokoll der Optionen zu sehen, die automatisch in jedem Modus angewendet werden.
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Webpack-Konzepte

Bei der Konfiguration von Webpack entweder über die CLI oder über eine Konfigurationsdatei gibt es vier Hauptkonzepte , die als Optionen angewendet werden. Der nächste Abschnitt dieses Artikels konzentriert sich auf diese Konzepte und wendet sie beim Erstellen der Konfiguration für eine Demo-Webanwendung an.

Bitte beachten Sie, dass die unten erläuterten Konzepte einige Ähnlichkeiten mit anderen Modul-Bundlern aufweisen. Wenn Sie beispielsweise Rollup mit einer Konfigurationsdatei verwenden, können Sie ein Eingabefeld definieren, um den Einstiegspunkt des Abhängigkeitsdiagramms anzugeben, ein Ausgabeobjekt, das konfiguriert, wie und wo die produzierten Chunks platziert werden, und auch ein Plugins-Objekt zum Hinzufügen externer Plugins.

Eintrag

Das Eingabefeld in Ihrer Konfigurationsdatei enthält den Pfad zu der Datei, von der aus webpack mit dem Erstellen eines Abhängigkeitsdiagramms beginnt. Von dieser Eingangsdatei geht webpack zu anderen Modulen über, die direkt oder indirekt vom Eingangspunkt abhängen.

Der Einstiegspunkt Ihrer Konfiguration kann ein Einzeleintragstyp mit einem einzelnen Dateiwert sein, ähnlich wie im folgenden Beispiel:

 # webpack.configuration.js module.exports = { mode: "development", entry : "./src/entry" }

Der Einstiegspunkt kann auch ein Multi-Main-Eintragstyp mit einem Array sein, das den Pfad zu mehreren Eintragsdateien enthält, ähnlich wie im folgenden Beispiel:

 # webpack.configuration.js const webpack = require("webpack") module.exports = { mode: "development", entry: [ './src/entry', './src/entry2' ], }

Ausgabe

Wie der Name schon sagt, befindet sich das erstellte Bundle im Ausgabefeld einer Konfiguration. Dieses Feld ist praktisch, wenn Sie mehrere Module eingerichtet haben. Anstatt den vom Webpack generierten Namen zu verwenden, können Sie Ihren eigenen Dateinamen angeben .

 # webpack.configuration.js const webpack = require("webpack"); const path = require("path"); module.exports = { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), } }

Lader

Standardmäßig versteht webpack nur JavaScript-Dateien innerhalb Ihrer Anwendung. Webpack behandelt jedoch jede als Modul importierte Datei als Abhängigkeit und fügt sie dem Abhängigkeitsdiagramm hinzu. Um statische Ressourcen wie Bilder, CSS-Dateien, JSON-Dateien oder sogar Ihre in CSV gespeicherten Daten zu verarbeiten, verwendet webpack Loader, um diese Dateien in das Bundle zu „laden“.

Loader sind flexibel genug, um für viele Dinge verwendet zu werden, von der Transpilierung Ihres ES-Codes über die Handhabung der Stile Ihrer Anwendung bis hin zum Linting Ihres Codes mit ESLint.

Es gibt drei Möglichkeiten, Loader in Ihrer Anwendung zu verwenden . Eine davon ist die Inline- Methode, indem sie direkt in die Datei importiert wird. Um beispielsweise die Bildgröße zu minimieren, können wir den image-loader Loader direkt in der Datei verwenden, wie unten gezeigt:

 // main.js import ImageLoader from 'image-loader'

Eine weitere bevorzugte Option zur Verwendung von Loadern ist über Ihre Webpack-Konfigurationsdatei. Auf diese Weise können Sie mehr mit Ladeprogrammen tun, z. B. die Dateitypen angeben , auf die Sie die Ladeprogramme anwenden möchten. Dazu erstellen wir ein rules und spezifizieren die Loader in einem Objekt, die jeweils ein Testfeld mit einem Regex-Ausdruck haben, der mit den Assets übereinstimmt, auf die wir die Loader anwenden möchten.

Wenn beispielsweise der image-loader im vorherigen Beispiel direkt importiert wurde, können wir ihn in der Webpack-Konfigurationsdatei mit den grundlegendsten Optionen aus der Dokumentation verwenden. Das wird so aussehen:

 # webpack.config.js const webpack = require("webpack") const path = require("path") const merge = require("webpack-merge") module.exports = { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), }, module: { rules: [ { test: /\.(jpe?g|png|gif|svg)$/i, use: [ 'img-loader' ] } ] } }

Sehen Sie sich das test in dem Objekt, das oben den image-loader enthält, genauer an. Wir können den Regex-Ausdruck erkennen, der mit allen Bilddateien übereinstimmt: entweder jp(e)g , png , gif oder svg -Format.

Die letzte Methode zur Verwendung von Loadern ist über die CLI mit dem --module-bind .

Die Readme-Datei von awesome-webpack enthält eine umfassende Liste von Loadern, die Sie mit webpack verwenden können, die jeweils in Kategorien von Operationen gruppiert sind, die sie ausführen. Unten sind nur einige Lader aufgeführt, die Sie in Ihrer Anwendung nützlich finden könnten:

  • Responsive-Loader Sie werden diesen Loader sehr hilfreich finden, wenn Sie Bilder hinzufügen, die zu Ihrer responsiven Website oder App passen. Es erstellt mehrere Bilder verschiedener Größen aus einem einzigen Bild und gibt ein srcset zurück, das den Bildern zur Verwendung bei geeigneten Anzeigebildschirmgrößen entspricht.
  • Babel-Loader
    Dies wird zum Transpilieren Ihres JavaScript-Codes von der modernen ECMA-Syntax in ES5 verwendet.
  • GraphQL-Loader
    Wenn Sie ein GraphQL-Enthusiast sind, werden Sie diesen Loader sehr hilfreich finden, da er Ihre .graphql Dateien lädt, die Ihr GraphQL-Schema, Abfragen und Mutationen enthalten – zusammen mit der Option, die Validierung zu aktivieren.

Plugins

Die Verwendung von Plugins ermöglicht es dem Webpack-Compiler , Aufgaben an Chunks auszuführen, die aus den gebündelten Modulen erstellt wurden. Obwohl Webpack kein Task Runner ist, können wir mit Plugins einige benutzerdefinierte Aktionen ausführen, die die Ladeprogramme nicht ausführen konnten, als der Code gebündelt wurde.

Ein Beispiel für ein Webpack-Plugin ist das in Webpack integrierte ProgressPlugin . Es bietet eine Möglichkeit, den Fortschritt anzupassen, der während der Kompilierung in der Konsole ausgedruckt wird.

 # webpack.config.js const webpack = require("webpack") const path = require("path") const merge = require("webpack-merge") const config = { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), }, module: { rules: [ { test: /\.(jpe?g|png|gif|svg)$/i, use: [ 'img-loader' ] } ] }, plugins: [ new webpack.ProgressPlugin({ handler: (percentage, message ) => { console.info(percentage, message); }, }) ] } module.exports = config

Mit dem Progress-Plugin in der obigen Konfiguration haben wir eine Handler-Funktion bereitgestellt, die während des Kompilierungsprozesses den Kompilierungsprozentsatz und eine Meldung an die Konsole ausgibt.

Ausgabe des Webpack-Fortschritts-Plugins
Eine Shell-Ausgabe, die Meldungen vom Webpack-Fortschritts-Plugin anzeigt. (Große Vorschau)

Unten sind einige Plugins aus der Readme-Datei von awesome-webpack aufgeführt, die Sie in Ihrer Webpack-Anwendung praktisch finden werden.

  • Offline-Plugin
    Dieses Plugin nutzt zuerst Servicemitarbeiter oder den AppCache, sofern verfügbar, um eine Offline-Erfahrung für Webpack-verwaltete Projekte bereitzustellen.
  • Purgecss-Webpack-Plugin
    Dieses Plugin ist praktisch, wenn Sie versuchen, Ihr Webpack-Projekt zu optimieren, da es während der Kompilierung unbenutztes CSS in Ihrer Anwendung entfernt.

An diesem Punkt haben wir unsere erste Webpack-Konfiguration für eine relativ kleine Anwendung vollständig eingerichtet. Lassen Sie uns weiter überlegen, wie wir bestimmte Dinge mit webpack in unserer Anwendung tun können.

Umgang mit mehreren Umgebungen

In Ihrer Anwendung müssen Sie Webpack möglicherweise entweder für eine Entwicklungs- oder eine Produktionsumgebung anders konfigurieren . Beispielsweise möchten Sie möglicherweise nicht, dass Webpack jedes Mal kleinere Warnprotokolle ausgibt, wenn eine neue Bereitstellung in Ihrer Continuous-Integration-Pipeline in Ihrer Produktionsumgebung vorgenommen wird.

Es gibt mehrere Möglichkeiten, dies zu erreichen, wie von Webpack und der Community empfohlen. Eine Möglichkeit besteht darin , Ihre Konfigurationsdatei zu konvertieren , um eine Funktion zu exportieren, die ein Objekt zurückgibt. Auf diese Weise wird die aktuelle Umgebung vom Webpack-Compiler als erster Parameter und andere Optionen als zweiter Parameter an die Funktion übergeben.

Diese Methode zum Umgang mit Ihrer Webpack-Umgebung ist praktisch, wenn Sie einige Vorgänge basierend auf der aktuellen Umgebung anders ausführen möchten. Bei größeren Anwendungen mit komplexeren Konfigurationen könnten Sie jedoch mit einer Konfiguration enden, die mit vielen bedingten Anweisungen vollgepackt ist.

Das folgende Code-Snippet zeigt ein Beispiel dafür, wie eine production und eine development in derselben Datei mithilfe der functions -Methode behandelt werden.

 // webpack.config.js module.exports = function (env, args) { return { mode : env.production ? 'production' : 'development', entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), }, plugins: [ env.development && ( new webpack.ProgressPlugin({ handler: (percentage, message ) => { console.info(percentage, message); }, }) ) ] } }

Wenn Sie die exportierte Funktion im obigen Code-Snippet durchgehen, werden Sie sehen, wie der an die Funktion übergebene env -Parameter mit einem ternären Operator zum Wechseln von Werten verwendet wird. Es wird zuerst verwendet, um den Webpack-Modus einzustellen, dann wird es auch verwendet, um das ProgressPlugin nur im Entwicklungsmodus zu aktivieren.

Eine weitere elegantere Möglichkeit, mit Ihrer Produktions- und Entwicklungsumgebung umzugehen, besteht darin, unterschiedliche Konfigurationsdateien für die beiden Umgebungen zu erstellen. Sobald wir das getan haben, können wir sie mit verschiedenen Befehlen in den package.json Skripten verwenden, wenn wir die Anwendung bündeln. Schauen Sie sich den folgenden Ausschnitt an:

 { "name" : "smashing-magazine", "main" : "index.js" "scripts" : { "bundle:dev" : "webpack --config webpack.dev.config.js", "bundle:prod" : "webpack --config webpack.prod.config.js" }, "dependencies" : { "webpack": "^5.24.1" } }

In der Datei „ package.json oben haben wir zwei Skriptbefehle , die jeweils eine andere Konfigurationsdatei verwenden, die geschrieben wurde, um eine bestimmte Umgebung zu handhaben, wenn die Assets der Anwendung gebündelt werden. Jetzt können Sie Ihre Anwendung mit npm run bundle:dev im Entwicklungsmodus oder npm run bundle:prod , wenn Sie ein produktionsreifes Bundle erstellen.

Mit dem zweiten Ansatz vermeiden Sie bedingte Anweisungen , die bei der Rückgabe Ihres Konfigurationsobjekts von einer Funktion eingeführt werden. Allerdings müssen Sie jetzt auch mehrere Konfigurationsdateien pflegen.

Konfigurationsdatei aufteilen

Zu diesem Zeitpunkt umfasst unsere Webpack-Konfigurationsdatei 38 Codezeilen (LOC). Das ist für eine Demo-Anwendung mit einem einzigen Ladeprogramm und einem einzigen Plugin ganz in Ordnung.

Für eine größere Anwendung wird unsere Webpack-Konfigurationsdatei jedoch definitiv viel länger sein und mehrere Loader und Plugins mit jeweils ihren benutzerdefinierten Optionen enthalten. Um die Konfigurationsdatei sauber und lesbar zu halten, können wir die Konfiguration in kleinere Objekte auf mehrere Dateien aufteilen und dann das Paket webpack-merge verwenden, um die Konfigurationsobjekte in einer Basisdatei zusammenzuführen.

Um es auf unser Webpack-Projekt anzuwenden, können wir die einzelne Konfigurationsdatei in drei kleinere Dateien aufteilen: eine für Loader, eine für Plugins und die letzte Datei als Basiskonfigurationsdatei, in der wir die beiden anderen Dateien zusammenfügen.

Erstellen Sie eine webpack.plugin.config.js -Datei und fügen Sie den folgenden Code ein, um die Plugins mit zusätzlichen Optionen zu verwenden.

 // webpack.plugin.config.js const webpack = require('webpack') const plugin = [ new webpack.ProgressPlugin({ handler: (percentage, message ) => { console.info(percentage, message); }, }) ] module.exports = plugin

Oben haben wir ein einzelnes Plugin, das wir aus der Datei webpack.configuration.js extrahiert haben.

Erstellen Sie als Nächstes eine webpack.loader.config.js -Datei mit dem folgenden Code für die Webpack-Loader.

 // webpack.loader.config.js const loader = { module: { rules: [ { test: /\.(jpe?g|png|gif|svg)$/i, use: [ 'img-loader' ] } ] } }

Im obigen Codeblock haben wir den Webpack-Img img-loader in eine separate Datei verschoben.

Erstellen Sie schließlich eine webpack.base.config.js -Datei, in der die grundlegende Eingabe- und Ausgabekonfiguration für die Webpack-Anwendung neben den beiden oben erstellten Dateien gespeichert wird.

 // webpack.base.config.js const path = require("path") const merge = require("webpack-merge") const plugins = require('./webpack.plugin.config') const loaders = require('./webpack.loader.config') const config = merge(loaders, plugins, { mode: "development", entry: './src/entry', output: { filename: "webpack-output.js", path: path.resolve(__dirname, "dist"), } }); module.exports = config

Wenn Sie einen Blick auf die obige webpack-Datei werfen, können Sie feststellen, wie kompakt sie im Vergleich zur ursprünglichen webpack.config.js -Datei ist. Jetzt wurden die drei Hauptteile der Konfiguration in kleinere Dateien aufgeteilt und können einzeln verwendet werden.

Optimierung großer Builds

Wenn Sie über einen längeren Zeitraum an Ihrer Anwendung arbeiten, wird Ihre Anwendung definitiv an Funktionen und Größe zunehmen. Dabei werden neue Dateien erstellt, alte Dateien modifiziert oder umgestaltet und neue externe Pakete installiert – all dies führt zu einer Erhöhung der von Webpack ausgegebenen Bundle-Größe .

Standardmäßig versucht webpack automatisch, Bundles in Ihrem Namen zu optimieren, wenn Ihr Konfigurationsmodus auf production eingestellt ist. Beispielsweise ist Tree-Shaking eine Technik, die webpack standardmäßig anwendet (beginnend mit webpack 4+), um Ihre Bundle-Größe zu optimieren und zu reduzieren. Im Wesentlichen handelt es sich um eine Optimierungstechnik, mit der nicht verwendeter Code entfernt wird. Auf einer einfachen Ebene werden während des Bündelns die Import- und Exportanweisungen verwendet, um ungenutzte Module zu erkennen, bevor sie aus den ausgegebenen Bündeln entfernt werden.

Sie können Ihr Anwendungspaket auch manuell optimieren, indem Sie Ihrer Konfigurationsdatei ein optimization mit bestimmten Feldern hinzufügen. Der Optimierungsabschnitt der Webpack-Dokumentation enthält eine vollständige Liste der Felder, die Sie im optimization verwenden können, um Ihre Anwendung zu optimieren. Betrachten wir eines der 20 dokumentierten Felder.

  • minimize
    Dieses boolesche Feld wird verwendet, um Webpack anzuweisen, die Bündelgröße zu minimieren. Standardmäßig versucht Webpack, dies mit TerserPlugin zu erreichen, einem Code-Minifizierungspaket, das mit Webpack geliefert wird.
Bei der Minimierung wird Ihr Code minimiert, indem unnötige Daten aus dem Code entfernt werden, was wiederum die nach dem Prozess erzeugte Codegröße reduziert.

Wir können auch andere bevorzugte Minifier verwenden, indem wir ein minimizer -Array-Feld innerhalb des optimization hinzufügen. Ein Beispiel ist die Verwendung von Uglifyjs-webpack-plugin unten.

 // webpack.config.js const Uglify = require("uglifyjs-webpack-plugin") module.exports = { optimization { minimize : true, minimizer : [ new Uglify({ cache : true, test: /\.js(\?.*)?$/i, }) ] } }

Oben wird uglifyjs-webpack-plugin als Minifier mit zwei ziemlich wichtigen Optionen verwendet. Erstens bedeutet die Aktivierung des cache , dass Uglify vorhandene Dateien nur minimiert, wenn es sich um neue Änderungen handelt, und die test gibt die spezifischen Dateitypen an, die wir minimieren möchten.

Hinweis: Das uglifyjs-webpack-plugin bietet eine umfassende Liste der verfügbaren Optionen, wenn Sie Ihren Code damit verkleinern.

Eine kleine Optimierungs-Demo

Lassen Sie uns versuchen, eine Demoanwendung manuell zu optimieren, indem wir einige Felder in einem größeren Projekt anwenden, um den Unterschied zu sehen. Obwohl wir nicht tief in die Optimierung der Anwendung eintauchen werden, werden wir den Unterschied in den Bundle-Größen zwischen der Ausführung von Webpack im development und im production sehen.

Für diese Demo verwenden wir eine mit Electron erstellte Desktop-Anwendung, die auch React.js für ihre Benutzeroberfläche verwendet – alles zusammen mit dem Webpack. Electron und React.js klingen nach einer ziemlich schweren Kombination und könnten wahrscheinlich ein größeres Bündel erzeugen.

Hinweis : Wenn Sie Electron zum ersten Mal kennenlernen, gibt dieser Artikel einen guten Einblick, was Electron ist und wie Sie es zum Erstellen plattformübergreifender Desktop-Anwendungen verwenden können.

Um die Demo lokal auszuprobieren, klonen Sie die Anwendung aus dem GitHub-Repository und installieren Sie die Abhängigkeiten mit den folgenden Befehlen.

 # clone repository git clone https://github.com/vickywane/webpack-react-demo.git # change directory cd demo-electron-react-webpack # install dependencies npm install

Die Desktop-Anwendung ist ziemlich einfach mit einer einzelnen Seite, die mit Stilkomponenten gestaltet ist. Wenn die Desktop-Anwendung mit dem Befehl yarn start gestartet wird, zeigt die einzelne Seite eine Liste von Bildern an, die von einem CDN abgerufen wurden, wie unten gezeigt.

Electron-Anwendung mit React.js-Schnittstellenvorschau.
Desktop-Vorschau von Bildern innerhalb der Electron-Anwendung mit der React.js-Oberfläche. (Große Vorschau)

Lassen Sie uns zunächst ein Entwicklungspaket dieser Anwendung ohne manuelle Optimierung erstellen, um die endgültige Paketgröße zu analysieren.

Durch Ausführen von yarn build:dev von einem Terminal im Projektverzeichnis wird das Entwicklungspaket erstellt. Außerdem werden die folgenden Statistiken auf Ihrem Terminal gedruckt:

Webpack-Compiler-Protokolle im Entwicklungsmodus
Terminalprotokolle vom Webpack-Compiler bei Ausführung im Entwicklungsmodus ohne manuelle Optimierungen. (Große Vorschau)

Der Befehl zeigt uns die Statistiken der gesamten Zusammenstellung und der ausgegebenen Bundles.

Beachten Sie, dass der mainRenderer.js 1,11 Mebibyte (ca. 1,16 MB) groß ist. Der mainRenderer ist der Einstiegspunkt für die Electron-Anwendung.

Als Nächstes fügen wir uglifyjs-webpack-plugin als installiertes Plug-in in der Datei webpack.base.config.js für die Codeminimierung hinzu.

 // webpack.base.config.js const Uglifyjs = require("uglifyjs-webpack-plugin") module.exports = { plugins : [ new Uglifyjs({ cache : true }) ] }

Lassen Sie uns abschließend die Anwendung mit dem Webpack im production bündeln. Wenn Sie den Befehl „ yarn build:prod “ von Ihrem Terminal aus ausführen, werden die folgenden Daten an Ihr Terminal ausgegeben.

Webpack-Compiler-Protokolle im Produktionsmodus.
Protokolle vom Webpack-Compiler, wenn die Anwendung im Produktionsmodus mit Codeminimierung gebündelt wird. (Große Vorschau)

Notieren Sie sich dieses Mal den mainRenderer Chunk. Es ist auf satte 182 Kibibyte (ca. 186 KB) gesunken, und das sind mehr als 80 % der zuvor mainRenderer Chunk-Größe!

Lassen Sie uns die ausgegebenen Bündel mit dem webpack-bundler-analyzer weiter visualisieren. Installieren Sie das Plug-in mit dem Befehl yarn add webpack-bundle-analyzer “ und ändern Sie die Datei webpack.base.config.js “ so, dass sie den folgenden Code enthält, der das Plug-in hinzufügt.

 // webpack.base.config.js const Uglifyjs = require("uglifyjs-webpack-plugin"); const BundleAnalyzerPlugin = require("webpack-bundle-analyzer"); .BundleAnalyzerPlugin; const config = { plugins: [ new Uglifyjs({ cache : true }), new BundleAnalyzerPlugin(), ] }; module.exports = config;

Führen Sie auf Ihrem Terminal yarn build:prod aus, damit die Anwendung neu gebündelt werden kann. Standardmäßig startet webpack-bundle-analyzer einen HTTP-Server, der die visualisierte Übersicht der Bundles in Ihrem Browser bereitstellt.

Bundle-Analyzer-Darstellung des emittierten Bundles.
Webpack-Bundle-Analyzer, der eine visuelle Darstellung des ausgegebenen Bundles und der darin enthaltenen Dateien zeigt. (Große Vorschau)

Aus dem obigen Bild können wir eine visuelle Darstellung des ausgegebenen Bündels und der Dateigrößen innerhalb des Bündels sehen. Im Bild können wir beobachten, dass im Ordner node_modules die größte Datei react-dom.production.min.js ist, gefolgt von stylis.min.js .

Anhand der vom Analysator visualisierten Dateigrößen haben wir eine bessere Vorstellung davon, welches installierte Paket den größten Teil des Pakets ausmacht. Wir können dann nach Möglichkeiten suchen, es zu optimieren oder durch ein leichteres Paket zu ersetzen.

Hinweis: Die Webpack-Analyzer-Plug-in- Dokumentation listet andere Mittel auf, die zum Anzeigen der Analyse verfügbar sind, die aus Ihren ausgegebenen Paketen erstellt wurde.

Webpack-Community

Eine der Stärken von Webpack war die große Community von Entwicklern dahinter, und dies war für Entwickler, die Webpack zum ersten Mal ausprobierten, von großem Nutzen. Genau wie dieser Artikel gibt es mehrere Artikel, Leitfäden und Ressourcen mit der Dokumentation, die als großartige Anleitung bei der Verwendung von Webpack dient.

Beispielsweise enthält der Build Performance Guide aus dem Blog von webpack Tipps zur Optimierung Ihrer Webpack-Builds, und die Fallstudie von Slack (obwohl sie etwas alt ist) erklärt, wie Webpack bei Slack optimiert wurde.

Mehrere Community-Ressourcen erklären Teile der Webpack-Dokumentation und stellen Ihnen Beispiel-Demoprojekte zur Verfügung, um zu zeigen, wie Funktionen von Webpack verwendet werden. Ein Beispiel ist ein Artikel über Webpack 5 Module Federation, der erklärt, wie die neue Module Federation-Funktion von Webpack in einer React-Anwendung verwendet wird.

Zusammenfassung

Nach sieben Jahren seines Bestehens hat sich webpack wirklich als wichtiger Bestandteil der JavaScript-Toolchain erwiesen, die von einer Vielzahl von Projekten verwendet wird. Dieser Artikel gibt nur einen Einblick in die Dinge, die man mit der flexiblen und erweiterbaren Natur von webpack erreichen kann.

Wenn Sie das nächste Mal einen Modul-Bundler für Ihre Anwendung auswählen müssen, werden Sie hoffentlich einige Kernkonzepte von Webpack, das Problem, das es löst, und auch die Schritte zum Einrichten Ihrer Konfigurationsdateien besser verstehen.

Weiterführende Literatur zu SmashingMag:

  • Webpack - Eine ausführliche Einführung
  • Erstellen Sie eine PWA mit Webpack und Workbox
  • Einrichten von TypeScript für moderne React-Projekte mit Webpack
  • So nutzen Sie die Maschinen: Mit Task Runnern produktiv sein