Behalten Sie die Kontrolle: Ein Leitfaden für Webpack und React, Pt. 2

Veröffentlicht: 2022-03-11

Im ersten Teil dieses React-Webpack-Tutorials haben wir besprochen, wie man Loader konfiguriert und Optimierungen durchführt. Jetzt werden wir uns mit fortgeschritteneren Techniken befassen, die sich auf bestimmte Anwendungsfälle der React/Webpack-Konfiguration beziehen.

TypeScript und React with Webpack: Geben Sie Babel ein

Es gibt mehrere Möglichkeiten, wie Sie TypeScript in Ihrem React-Projekt verwenden können. Obwohl ts-loader eine gute Option ist, möchte ich mich darauf konzentrieren, wie man TypeScript mit @babel/preset-typescript , da viele Bibliotheken Babel-Plugins veröffentlichen, um die Kompilierungszeit zu optimieren. Neben der Verarbeitung von TypeScript-Dateien ermöglicht es uns, Babel-Plug-ins zu verwenden, die von verschiedenen Bibliotheken wie styled-components oder respond-intl bereitgestellt werden.

Als erstes müssen wir TypeScript- und Babel-Abhängigkeiten installieren:

 npm install -D typescript @babel/preset-typescript @types/react @types/react-dom

Anschließend generieren wir mit dem Befehlszeilenprogramm tsc eine TypeScript-Konfigurationsdatei:

 ./node_modules/.bin/tsc -init --lib dom --jsx react --isolatedModules

Der obige Befehl generiert eine tsconfig.json , die zum Schreiben von Code für eine Browserumgebung geeignet ist. Die Option --isolatedModules erzwingt einige Einschränkungen, die sicherstellen, dass der von Ihnen geschriebene Code mit @babel/plugin-transform-typescript typescript kompatibel ist. Diese Option ist nützlich, damit Ihre IDE Sie warnt, wenn Sie Code auf eine Weise schreiben, die Babel nicht transformieren kann.

Als nächstes werden wir babel.config.js aktualisieren, indem wir eine neue Voreinstellung einführen:

 @@ -6,7 +6,8 @@ module.exports = { modules: false } ], - "@babel/preset-react" + "@babel/preset-react", + "@babel/preset-typescript" ], plugins: [ "@babel/plugin-transform-runtime",

Und aktivieren Sie die Dateierweiterung .ts in webpack.config.js :

 @@ -11,7 +11,7 @@ module.exports = function(_env, argv) { return { devtool: isDevelopment && "cheap-module-source-map", - entry: "./src/index.js", + entry: "./src/index.tsx", output: { path: path.resolve(__dirname, "dist"), filename: "assets/js/[name].[contenthash:8].js", @@ -20,7 +20,7 @@ module.exports = function(_env, argv) { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", @@ -61,6 +61,9 @@ module.exports = function(_env, argv) { } ] }, + resolve: { + extensions: [".js", ".jsx", ".ts", ".tsx"] + }, plugins: [ isProduction && new MiniCssExtractPlugin({

Die obige Konfiguration reicht aus, um unseren Code transpilieren zu können, validiert ihn jedoch nicht wirklich. Wir müssen die Typüberprüfung in einem separaten, parallelen Prozess mit fork-ts-checker-webpack-plugin .

Zuerst müssen wir es installieren:

 npm install -D fork-ts-checker-webpack-plugin

Dann fügen wir es dem plugins -Abschnitt in webpack.config.js :

 @@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); module.exports = function(_env, argv) { const isProduction = argv.mode === "production"; @@ -78,6 +79,9 @@ module.exports = function(_env, argv) { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development" ) + }), + new ForkTsCheckerWebpackPlugin({ + async: false }) ].filter(Boolean), optimization: {

Die Angabe von async: false verhindert, dass Webpack ungültigen Code ausgibt und Kompilierungsfehler in einem Overlay anzeigt, wenn ein Entwicklungsserver ausgeführt wird.

Hinweis: Sie könnten auch an Babel-Makros interessiert sein, die an Zugkraft gewinnen.

CSS, erweitert über Webpack

Im vorherigen Artikel haben wir das grundlegende Styling mit css-loader behandelt. Es gibt mehrere Möglichkeiten, wie wir diese Konfiguration verbessern können.

Die vorgeschlagene Konfiguration nutzt CSS-Module, Sass- und PostCSS-Technologien. Obwohl sie sich in gewisser Weise ergänzen, müssen Sie nicht alle gleichzeitig verwenden. Bei der endgültigen Einrichtung werden alle oben genannten Plugins aktiviert sein, und wir überlassen es Ihnen, etwas wegzulassen, wenn Sie sicher sind, „dass Sie es nicht brauchen werden“.

CSS-Module

CSS-Module lösen das Problem des globalen Bereichs in CSS-Dateien, indem sie einen zufälligen, eindeutigen Namen für jede CSS-Klasse generieren. Aus Sicht einer JavaScript-Datei, die ein CSS-Modul verwendet, wird eine Zuordnung zwischen dem ursprünglichen Klassennamen und dem zufälligen Namen durch ein vom Ladeprogramm exportiertes Objekt dargestellt. Damit können Sie Klassen, die in einer CSS-Datei angegeben sind, auf eine Weise finden und verwenden, die versehentliche Kollisionen fast unmöglich macht.

Unterstützung für CSS-Module ist bereits in css-loader enthalten. Jetzt müssen wir eine neue Regel hinzufügen, um deutlich zu machen, wann CSS-Module verwendet werden:

 @@ -33,11 +33,25 @@ module.exports = function(_env, argv) { }, { test: /\.css$/, use: [ isProduction ? MiniCssExtractPlugin.loader : "style-loader", "css-loader" ] }, + { + test: /\.module.css$/, + use: [ + isProduction ? MiniCssExtractPlugin.loader : "style-loader", + { + loader: "css-loader", + options: { + modules: true + } + } + ] + }, { test: /\.(png|jpg|gif)$/i, use: {

Damit wird jede Datei, die auf .module.css endet, mit aktivierten CSS-Modulen verarbeitet.

PostCSS

PostCSS ist ein erweiterbares CSS-Verarbeitungsframework mit einer riesigen Bibliothek von Plugins, die Sie verwenden können, um die CSS-Syntax zu erweitern, Optimierungen durchzuführen oder Fallbacks für ältere Browser bereitzustellen.

Zuerst werden wir die notwendigen Abhängigkeiten installieren:

 npm install -D postcss-loader postcss-import postcss-preset-env

Und aktualisieren Sie unsere CSS-Konfiguration:

 @@ -47,9 +47,11 @@ module.exports = function(_env, argv) { { loader: "css-loader", options: { - modules: true + modules: true, + importLoaders: 1 } - } + }, + "postcss-loader" ] }, {

Wir werden PostCSS mit den folgenden Plugins konfigurieren:

  • postcss-import : Ermöglicht PostCSS die Verarbeitung @import -Anweisungen
  • postcss-preset-env : Wendet Polyfills an, um moderne CSS-Funktionen in den meisten Browsern zu unterstützen

Erstellen Sie eine Datei namens postcss.config.js und füllen Sie sie mit Folgendem:

 module.exports = { plugins: { "postcss-import": {}, "postcss-preset-env": {} } };

Sie können das PostCSS-Plugin-Verzeichnis nach anderen Erweiterungen durchsuchen, die Sie möglicherweise nützlich finden, und sie Ihrer Konfiguration hinzufügen.

Sass/SCSS

Sass ist ein weiteres beliebtes CSS-Verarbeitungsframework. Im Gegensatz zu PostCSS wird Sass mit „Batterien inklusive“ geliefert. Standardmäßig bietet Sass Unterstützung für verschachtelte Regeln, Mixins und das Umschreiben von Regeln für die Abwärtskompatibilität. Während PostCSS darauf abzielt, die CSS-Standardsyntax beizubehalten, kann die Sass-Syntax von der CSS-Spezifikation abweichen. Trotzdem ist Sass eine so allgegenwärtige Lösung, dass die Verwendung zum Erstellen von CSS möglicherweise eine einfachere Option ist – aber eine, die von Ihren Anforderungen abhängt.

Zuerst werden wir die notwendigen Abhängigkeiten installieren:

 npm install -D sass-loader node-sass resolve-url-loader

Fügen Sie dann einen neuen Loader zu unserer Webpack-Konfiguration hinzu:

 @@ -38,6 +38,25 @@ module.exports = function(_env, argv) { "css-loader" ] }, + { + test: /\.s[ac]ss$/, + use: [ + isProduction ? MiniCssExtractPlugin.loader : "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 2 + } + }, + "resolve-url-loader", + { + loader: "sass-loader", + options: { + sourceMap: true + } + } + ] + }, { test: /\.(png|jpg|gif)$/i, use: {

Wir haben einige Probleme mit dem obigen Snippet präventiv angegangen:

  1. Wir haben den resolve-url-loader nach sass-loader eingeführt, damit relative Importe aus @import Sass-Dateien funktionieren.

  2. Wir haben die importLoaders -Option für css-loader angegeben, um @import -ed-Dateien mit den darauf folgenden Loadern zu verarbeiten.

Mit der obigen Konfiguration können wir damit beginnen, unsere Stile zusätzlich zu den zuvor beschriebenen PostCSS- und CSS-Modulen mit Sass/SCSS zu erstellen. Obwohl alle diese Optionen gleichzeitig aktiviert werden können, müssen Sie sie nicht alle innerhalb desselben Projekts verwenden, sodass Sie das Tool auswählen können, das Ihren Anforderungen am besten entspricht.

Web-Arbeiter

Web Worker ist ein mächtiges Konzept des modernen Webs. Damit können Sie teure Berechnungen aus dem Haupt-Thread auslagern. Web Worker sollten sparsam eingesetzt und für Dinge reserviert werden, die nicht anderweitig durch intelligente Planung innerhalb einer Ereignisschleife optimiert werden können. Der Einsatz von Web Workern ist ein guter Kandidat für die Optimierung langer, synchroner Vorgänge.

Webpack erleichtert die Verwendung von Web Workern mit worker-loader , das Worker-Dateien in das Ausgabeverzeichnis bündelt und eine Worker-Klasse für die Consumer-Datei bereitstellt.

Zuerst müssen wir worker-loader installieren:

 npm install -D worker-loader

Dann fügen Sie es unserer Konfigurationsdatei hinzu:

 @@ -31,6 +31,10 @@ module.exports = function(_env, argv) { } } }, + { + test: /\.worker\.js$/, + loader: "worker-loader" + }, { test: /\.css$/, use: [

Jetzt müssen Sie nur noch eine Klasse instanziieren, die aus einer Datei mit der Endung .worker.js importiert wurde, die die gewöhnliche Worker-API implementiert, um mit der Verwendung von Web Workern zu beginnen.

Servicemitarbeiter

Servicemitarbeiter ermöglichen fortschrittliche Optimierungstechniken und Verbesserungen der Benutzererfahrung. Sie lassen Ihre App offline arbeiten, wenn ein Benutzer seine Netzwerkverbindung verliert. Sie lassen Ihre App auch nach dem Pushen eines Updates sofort laden.

Webpack erleichtert die Konfiguration von Servicemitarbeitern für Ihre App mit dem Modul workbox-webpack-plugin. Zuerst müssen wir es installieren:

 npm install -D workbox-webpack-plugin

Dann fügen wir das Plugin dem plugins -Bereich unserer Webpack-Konfiguration hinzu:

 @@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const WorkboxPlugin = require("workbox-webpack-plugin"); module.exports = function(_env, argv) { const isProduction = argv.mode === "production"; @@ -75,6 +76,11 @@ module.exports = function(_env, argv) { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development" ) + }), + new WorkboxPlugin.GenerateSW({ + swDest: "service-worker.js", + clientsClaim: true, + skipWaiting: true }) ].filter(Boolean), optimization: {

Die obige Konfiguration verwendet die folgenden Optionen:

  • swDest gibt den Ausgabedateinamen für die generierte Worker-Datei an.
  • clientsClaim weist den Dienstmitarbeiter an, unmittelbar nach der Registrierung die Kontrolle über die Seite zu übernehmen und mit der Bereitstellung zwischengespeicherter Ressourcen zu beginnen, anstatt auf das Neuladen der nächsten Seite zu warten.
  • skipWaiting , dass Aktualisierungen des Service Workers sofort wirksam werden, anstatt darauf zu warten, dass alle aktiven Instanzen zerstört werden.

Es gibt einen guten Grund, warum die beiden letzteren Optionen nicht die Standardeinstellung sind. Bei gleichzeitiger Aktivierung besteht die Möglichkeit, dass in zeitkritischen Situationen Störungen auftreten. Es liegt also an Ihnen, eine bewusste Entscheidung zu treffen, ob Sie diese Optionen in Ihrer Konfiguration aktiviert lassen.

Schließlich müssen wir den Servicemitarbeiter registrieren, wenn ein Benutzer unsere App öffnet:

 @@ -2,3 +2,9 @@ import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(<h3>React App</h3>, document.getElementById("root")); + +if ("serviceWorker" in navigator) { + window.addEventListener("load", () => { + navigator.serviceWorker.register("/service-worker.js"); + }); +}

Servicemitarbeiter können viel mehr, als unserer App Offline-Funktionen hinzuzufügen. Wenn Sie ein größeres Maß an Kontrolle über das Verhalten von Dienstmitarbeitern benötigen, können Sie stattdessen das InjectManifest Plugin verwenden. Indem Sie Ihre eigene Service-Worker-Datei schreiben, können Sie auch das Caching für API-Anforderungen aktivieren und andere von Service-Workern aktivierte Funktionen wie Push-Benachrichtigungen verwenden. Weitere Informationen zu den Funktionen von Workbox finden Sie im Abschnitt „Advanced Recipes“ der offiziellen Dokumentation.

Advanced React Webpack Config: Geben Sie Ihrem Projekt einen Vorteil

Dieser zweite Teil unserer Webpack-Tutorial-Serie sollte Sie mit dem notwendigen Wissen ausgestattet haben, um Ihre Webpack-Konfiguration über die allgemeinsten React-Anwendungsfälle hinaus zu erweitern. Ich hoffe, dass Sie diese Informationen nützlich fanden und dass Sie Ihre personalisierte Konfiguration getrost erweitern können, um die spezifischen Ziele Ihres Projekts zu erreichen.

Wie immer finden Sie die vollständigen Konfigurationsdateien auf GitHub und in der Webpack-Dokumentation und im Abschnitt mit den Plugins finden Sie weitere Rezepte, die für Ihre Ziele geeignet sind. Vielen Dank fürs Lesen!