Webpack: Ein Leitfaden für Anfänger





Guten Tag, Freunde!



Ich präsentiere Ihnen eine Übersetzung des Artikels "Webpack: Eine sanfte Einführung" von Tyler McGinnis.



Stellen Sie sich vor der Erforschung einer neuen Technologie zwei Fragen:



  1. Warum wird dieses Tool benötigt?
  2. Welche Aufgaben führt es aus?


Wenn Sie diese Fragen nicht beantworten können, benötigen Sie möglicherweise nicht die Technologie, die Sie studieren. Versuchen wir, diese Fragen in Bezug auf Webpack zu beantworten.



Warum brauchst du ein Webpack?



Webpack ist ein Modul-Builder. Es analysiert die Module der Anwendung, erstellt ein Abhängigkeitsdiagramm und setzt die Module in der richtigen Reihenfolge zu einem oder mehreren Bundles zusammen, auf die in der Datei "index.html" verwiesen werden kann.



App.js ->       |
Dashboard.js -> | Bundler | -> bundle.js
About.js ->     |


Welche Probleme löst Webpack?



Normalerweise wird der Code beim Erstellen einer JavaScript-Anwendung in mehrere Teile (Module) aufgeteilt. Anschließend müssen Sie in der Datei "index.html" einen Link zu jedem Skript angeben.



<body>

    ...
    
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="libs/react.min.js"></script>
    <script src='src/admin.js'></script>
    <script src='src/dashboard.js'></script>
    <script src='src/api.js'></script>
    <script src='src/auth.js'></script>
    <script src='src/rickastley.js'></script>
</body>


Dies ist nicht nur mühsam, sondern auch fehleranfällig. Es ist wichtig, ein Skript nicht nur nicht zu vergessen, sondern auch in der richtigen Reihenfolge anzuordnen. Wenn Sie ein Skript laden, das von React abhängt, bevor Sie React selbst laden, wird Ihre Anwendung unterbrochen. Webpack löst diese Probleme. Sie müssen sich nicht darum kümmern, alle Skripte nacheinander einzuschließen.



<body>

    ...
    
    <script src='dist/bundle.js'></script>
</body>


Wie wir bald erfahren werden, ist das Sammeln von Modulen nur ein Aspekt der Funktionsweise eines Webpacks. Bei Bedarf können Sie das Webpack zwingen, einige Modultransformationen durchzuführen, bevor Sie sie dem Bundle hinzufügen. Zum Beispiel Konvertieren von SASS / LESS in normales CSS oder modernes JavaScript in ES5 für ältere Browser.



Installieren eines Webpacks



Nachdem Sie das Projekt mit npm initialisiert haben, müssen Sie zwei Pakete installieren, damit das Webpack funktioniert - webpackund webpack-cli.



npm i webpack webpack-cli -D


webpack.config.js



Nach der Installation dieser Pakete muss das Webpack konfiguriert werden. Dazu wird eine Datei erstellt webpack.config.js, die das Objekt exportiert. Dieses Objekt enthält Webpack-Einstellungen.



module.exports = {}


Die Hauptaufgabe eines Webpacks besteht darin, Module zu analysieren, sie optional zu transformieren und sie intelligent zu einem oder mehreren Bundles zu kombinieren. Das Webpack muss also drei Dinge wissen:



  1. Anwendungseinstiegspunkt
  2. Durchzuführende Konvertierungen
  3. Wo soll das generierte Bundle platziert werden?


Eingangspunkt



Unabhängig davon, wie viele Module eine Anwendung enthält, gibt es immer einen einzigen Einstiegspunkt. Dieses Modul enthält den Rest. In der Regel lautet diese Datei index.js. Es könnte so aussehen:



index.js
  imports about.js
  imports dashboard.js
    imports graph.js
    imports auth.js
      imports api.js


Wenn wir dem Webpack den Pfad zu dieser Datei mitteilen, wird es verwendet, um das Abhängigkeitsdiagramm der Anwendung zu erstellen. Dazu müssen Sie entryden Webpack-Einstellungen eine Eigenschaft mit dem Wert des Pfads zur Hauptdatei hinzufügen :



module.exports = {
    entry: './app/index.js'
}


Umbau mit Ladern



Nach dem Hinzufügen des Einstiegspunkts müssen Sie das Webpack über die Transformationen informieren, die ausgeführt werden müssen, bevor Sie das Bundle generieren. Hierzu werden Lader eingesetzt.



Standardmäßig import / require()kann das Webpack beim Generieren von bedienerbasierten Abhängigkeitsdiagrammen nur JavaScript- und JSON-Dateien verarbeiten.



import auth from './api/auth' // 
import config from './utils/config.json' // 
import './styles.css' // ️
import logo from './assets/logo.svg' // ️


Sie werden es kaum wagen, sich auf JS- und JSON-Dateien in Ihrer Anwendung zu beschränken. Höchstwahrscheinlich benötigen Sie auch Stile, SVGs, Bilder usw. Hier kommen die Lader ins Spiel. Die Hauptaufgabe von Loadern besteht, wie der Name schon sagt, darin, das Webpack in die Lage zu versetzen, mit mehr als nur JS- und JSON-Dateien zu arbeiten.



Der erste Schritt ist die Installation des Laders. Da wir SVG laden möchten, verwenden Sie npm, um svg-loader zu installieren.



npm i svg-inline-loader -D 


Fügen Sie es als Nächstes zu den Webpack-Einstellungen hinzu. Alle Lader sind in einer Reihe von Objekten enthalten module.rules:



module.exports = {
    entry: './app/index.js',
    module: {
        rules: []
    }
}


Die Ladeinformationen bestehen aus zwei Teilen. Der erste ist die Art der Dateien, die verarbeitet werden ( .svgin unserem Fall). Der zweite ist der Loader, mit dem dieser Dateityp verarbeitet wird ( svg-inline-loaderin unserem Fall).



module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' }
    ]
  }
}


Wir können jetzt SVG-Dateien importieren. Aber was ist mit unseren CSS-Dateien? Für verwendete Stile css-loader.



npm i css-loader -D 


module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: 'css-loader' }
    ]
  }
}


Wir können jetzt sowohl SVG- als auch CSS-Dateien importieren. Damit unsere Stile jedoch ordnungsgemäß funktionieren, müssen wir einen weiteren Loader hinzufügen. Dank css-loaderuns können wir CSS-Dateien importieren. Das heißt aber nicht, dass sie in das DOM aufgenommen werden. Wir möchten solche Dateien nicht nur importieren, sondern auch in ein Tag <style>einfügen, damit sie auf DOM-Elemente angewendet werden. Dafür brauchst du style-loader.



npm i style-loader -D 


module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }
    ]
  }
}


Beachten Sie, dass der Eigenschaftswert useein Array ist , da zwei Loader zum Verarbeiten von CSS-Dateien verwendet werden . Beachten Sie auch die Reihenfolge der Lader, zuerst style-loader, dann css-loader. Es ist wichtig. Das Webpack wendet sie in umgekehrter Reihenfolge an. Es wird zuerst css-loaderfür Importe './styles.css'und dann style-loaderzum Einfügen von Stilen in das DOM verwendet.



Loader können nicht nur zum Importieren, sondern auch zum Konvertieren von Dateien verwendet werden. Am beliebtesten ist die Konvertierung von JavaScript der nächsten Generation in modernes JavaScript mit Babel. Es wird dafür verwendet babel-loader.



npm i babel-loader -D 


module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  }
}


Es gibt Lader für fast alle Dateitypen.



Ausstiegspunkt



Jetzt kennt das Webpack den Einstiegspunkt und die Lader. Der nächste Schritt besteht darin, das Verzeichnis für das Bundle anzugeben. Dazu müssen Sie outputden Webpack-Einstellungen eine Eigenschaft hinzufügen.



const path = require('path')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  }
}


Der gesamte Prozess sieht folgendermaßen aus:



  1. Das Webpack erhält einen Einstiegspunkt bei ./app/index.js
  2. Es analysiert Anweisungen import / requireund erstellt ein Abhängigkeitsdiagramm
  3. Das Webpack beginnt mit dem Erstellen des Bundles, indem der Code mit den entsprechenden Loadern konvertiert wird
  4. Er sammelt ein Bündel und legt es hinein dist/index_bundle.js


Plugins



Wir haben gesehen, wie Loader verwendet werden, um einzelne Dateien vor oder während der Generierung eines Bundles zu verarbeiten. Im Gegensatz zu Loadern können Sie mit Plugins Aufgaben ausführen, nachdem Sie ein Bundle erstellt haben. Diese Aufgaben können sowohl das Bundle selbst als auch anderen Code betreffen. Sie können sich Plugins als leistungsstärkere, weniger eingeschränkte Loader vorstellen.



Nehmen wir ein Beispiel.



HtmlWebpackPlugin



Die Hauptaufgabe des Webpacks besteht darin, ein Bundle zu generieren, auf das verwiesen werden kann index.html.



HtmlWebpackPluginErstellt index.htmlim Verzeichnis mit dem Bundle und fügt automatisch einen Link zu dem darin enthaltenen Bundle hinzu.



Wir haben das Bundle benannt index_bundle.jsund eingelegt dist. HtmlWebpackPluginerstellt eine neue Datei index.htmlim Verzeichnis distund fügt einen Link zu dem darin enthaltenen Bundle hinzu - <script src='index_bundle.js'></script>. Großartig, nicht wahr? Da es index.htmlgeneriert wird, erhält es diese Informationen und ändert den Inhalt HtmlWebpackPlugin, auch wenn wir den Exit-Punkt oder den Namen des Bundles HtmlWebpackPluginändern index.html.



Wie verwenden wir dieses Plugin? Wie üblich müssen Sie es zuerst installieren.



npm i html-webpack-plugin -D 


Fügen Sie als Nächstes die Eigenschaft zu den Webpack-Einstellungen hinzu plugins.



const path = require('path')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: []
}


Wir erstellen eine Instanz HtmlWebpackPluginin einem Array plugins.




const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin()
  ]
}


EnvironmentPlugin



Wenn Sie React verwenden, sollten Sie diesen process.env.NODE_ENVWert productionvor dem Bereitstellen der Anwendung auf einen Wert festlegen . Auf diese Weise kann React die Produktion einbauen, indem Entwicklungstools wie Warnungen entfernt werden. Mit dem Webpack können Sie dies über ein Plugin tun EnvironmentPlugin. Es ist Teil des Webpacks, sodass Sie es nicht installieren müssen.



const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin(),
    new webpack.EnvironmentPlugin({
      'NODE_ENV': 'production'
    })
  ]
}


Jetzt können wir überall in unserer Anwendung den Produktionsmodus mit einstellen process.env.NODE_ENV.



HtmlWebpackPluginund EnvironmentPluginist nur ein kleiner Teil des Webpack-Plugin-Systems.



Modus



Bei der Vorbereitung eines Antrags für die Produktion sind mehrere Schritte erforderlich. Wir haben gerade eine davon behandelt - die Einstellung process.env.NODE_ENVauf Wert production. Eine weitere Aktion besteht darin, den Code zu minimieren und Kommentare zu entfernen, um die Größe des Bundles zu verringern.



Es gibt spezielle Plugins zum Lösen dieser Aufgaben, aber es gibt einen einfacheren Weg. In den Webpack-Einstellungen kann es modeauf developmentoder productionabhängig von der Entwicklungsumgebung eingestellt werden.



const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './app/index.js',
  module: {
    rules: [
      { test: /\.svg$/, use: 'svg-inline-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
      { test: /\.(js)$/, use: 'babel-loader' }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin()
  ],
  mode: 'production'
}


Bitte beachten Sie, dass wir entfernt haben EnvironmentPlugin. Tatsache ist , dass nach der Einstellung modedes Wertes, der productionwebpack automatisch den zuweist process.env.NODE_ENVWert production. Dies minimiert auch den Code und entfernt Warnungen.



Starten eines Webpacks



Im Moment wissen wir, wie das Webpack funktioniert und wie es konfiguriert wird. Es muss noch ausgeführt werden.



Wir haben eine Datei package.json, die wir scriptzum Ausführen erstellen können webpack.



"scripts": {
  "build": "webpack"
}


Wenn Sie nun den Befehl npm run buildim Terminal ausführen, wird ein Webpack gestartet, das ein optimiertes Bundle erstellt index_bundle.jsund darin ablegt dist.



Entwicklungs- und Produktionsmodi



Insgesamt sind wir mit dem Webpack fertig. Schauen wir uns zum Schluss an, wie man zwischen den Modi wechselt.



Beim Bauen für die Produktion wollen wir alles so weit wie möglich optimieren. Im Fall des Entwicklungsmodus ist das Gegenteil der Fall.



Um zwischen den Modi zu wechseln, müssen Sie zwei Skripte erstellen package.json.



npm run buildwird das Produktionsbündel bauen.



npm run startstartet den Entwicklungsserver und sucht nach Dateiänderungen.



Wenn Sie sich erinnern, setzen wir dies in den Webpack-Einstellungen modeauf einen Wert production. Wir brauchen es jetzt jedoch nicht. Wir möchten, dass die Umgebungsvariable abhängig vom ausgeführten Befehl einen geeigneten Wert hat. Lassen Sie uns das Skript ändern buildin package.json.



"scripts": {
  "build": "NODE_ENV='production' webpack",
}


Wenn Sie Windows haben, lautet der Befehl : "SET NODE_ENV='production' && webpack".



Jetzt können wir in den Webpack-Einstellungen den Wert modeabhängig von ändern process.env.NODE_ENV.



...

  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}


Um ein fertiges Bundle für unsere Anwendung zu erstellen, führen wir es einfach npm run buildim Terminal aus. Die Verzeichnisdateien distwerden erstellt index.htmlund index_bunlde.js.



Entwicklungsserver



Bei der Entwicklung einer Anwendung ist Geschwindigkeit von entscheidender Bedeutung. Wir möchten das Webpack nicht neu starten und bei jeder Änderung auf einen neuen Build warten. Hier bietet sich das Paket an webpack-dev-server.



Wie der Name schon sagt, ist dies ein Webpack-Server für die Entwicklung. Anstatt ein Verzeichnis zu erstellen dist, werden Daten im Speicher gespeichert und auf einem lokalen Server verarbeitet. Darüber hinaus wird ein Live-Neustart unterstützt. Dies bedeutet, dass bei jeder Änderung webpack-dev-serverdie Dateien neu erstellt und der Browser neu gestartet werden.



Installieren Sie das Paket.



npm i webpack-dev-server -D 


Alles , was zu tun bleibt , ist das Skript hinzufügen startzu package.json.



"scripts": {
  "build": "NODE_ENV='production' webpack",
  "start": "webpack-dev-server"
}


Wir haben jetzt zwei Befehle: einen zum Starten des Entwicklungsservers und den anderen zum Erstellen des fertigen Bundles.



Ich hoffe der Artikel war hilfreich für Sie. Danke für die Aufmerksamkeit.



All Articles