React & Co.: Unterschied zwischen den Versionen

Aus Jonas Notizen Webseite
Zur Navigation springen Zur Suche springen
(Texte verbessert)
Zeile 34: Zeile 34:
 
<br />
 
<br />
  
=== Kritik am Komponenten-zentrierten Modell von React ===
+
===Kritik am Komponenten-zentrierten Modell von React===
 
Anders als bei strikten MVC-Modellen wird in React ein komponentenzentriertes Modell vorgeschlagen, welches Logik für Interaktion und Darstellung innerhalb eines Objekts bündelt ([[wikipedia:Separation_of_concerns|Seperation of Concerns]]). Dies wird insbesondere aufgrund der weitverbreiteten strikten Trennung zwischen Markup und Logik in Form von Templating-Systemen oft kritisch gesehen. <ref name=":1">[https://de.wikipedia.org/wiki/React#Kritik Deutscher Wikipedia-Eintrag zu "React": Kritik]</ref>
 
Anders als bei strikten MVC-Modellen wird in React ein komponentenzentriertes Modell vorgeschlagen, welches Logik für Interaktion und Darstellung innerhalb eines Objekts bündelt ([[wikipedia:Separation_of_concerns|Seperation of Concerns]]). Dies wird insbesondere aufgrund der weitverbreiteten strikten Trennung zwischen Markup und Logik in Form von Templating-Systemen oft kritisch gesehen. <ref name=":1">[https://de.wikipedia.org/wiki/React#Kritik Deutscher Wikipedia-Eintrag zu "React": Kritik]</ref>
 
<br />
 
<br />
Zeile 123: Zeile 123:
 
Im folgenden Beispiel bekommt die h1-Komponente 2 props übergeben:  
 
Im folgenden Beispiel bekommt die h1-Komponente 2 props übergeben:  
  
* <code>className</code> mit dem Wert "greeting" (String-Literal)  
+
*<code>className</code> mit dem Wert "greeting" (String-Literal)
* <code>children</code> mit dem Wert "Hallo Welt!" (String-Literal)  
+
*<code>children</code> mit dem Wert "Hallo Welt!" (String-Literal)
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
 
const element = (
 
const element = (
Zeile 161: Zeile 161:
 
<br />
 
<br />
  
= React Einführung - Weiteres =
+
=React Einführung - Weiteres=
  
  
Zeile 198: Zeile 198:
  
 
*Einem '''Paket Manager''' wie [https://yarnpkg.com/ Yarn] oder [https://www.npmjs.com/ npm], der einem Zugriff auf ein breites Ökosystem von Drittbibliotheken zur Verfügung stellt die man einfach installieren oder aktualisieren kann.
 
*Einem '''Paket Manager''' wie [https://yarnpkg.com/ Yarn] oder [https://www.npmjs.com/ npm], der einem Zugriff auf ein breites Ökosystem von Drittbibliotheken zur Verfügung stellt die man einfach installieren oder aktualisieren kann.
*Einem '''Bundler''' wie [https://webpack.js.org/ webpack] oder [https://parceljs.org/ Parcel], der es einem erlaubt, modularen Code zu schreiben und ihn in kleine Pakete zu packen um die Ladezeit zu optimieren.
+
*Einem '''Bundler''' wie [https://webpack.js.org/ webpack] oder [https://parceljs.org/ Parcel], der es einem erlaubt, modularen Code zu schreiben und ihn in kleine Pakete (Bundles) zu packen, unter anderem um die Ladezeit zu optimieren.
*Einem '''Compiler/Transpiler''' wie [https://babeljs.io/ Babel] erlaubt es einem modernen JavaScript Code zu schreiben, der trotzdem in alten Browsern funktioniert.
+
*Einem '''Compiler/Transpiler''' wie [https://babeljs.io/ Babel] erlaubt es einem, Modernen JavaScript Code zu schreiben und ihn in Code umzuwandeln ("polyfill"en), den auch ältere Browser verstehen können.
  
 
<br />
 
<br />
Zeile 216: Zeile 216:
 
   +-- index.html
 
   +-- index.html
 
  +-- src
 
  +-- src
Unser <code>public</code>-Verzeichnis verwaltet alle statischen Assets und beherbergt vor allem unsere <code>index.html</code>-Datei, die als Einstiegspunkt unserer Anwendung für den Browser dient. Sie können das folgende HTML-Markup in eine neue Datei <code>index.html</code> innerhalb des <code>public</code>-Verzeichnisses kopieren.<syntaxhighlight lang="html" line="1">
+
Unser <code>public</code>-Verzeichnis verwaltet alle statischen Assets und beherbergt vor allem unsere <code>index.html</code>-Datei, die als Einstiegspunkt unserer Anwendung für den Browser dient. Sie können das folgende HTML-Markup in eine neue Datei <code>index.html</code> innerhalb des <code>public</code>-Verzeichnisses kopieren:<syntaxhighlight lang="html" line="1">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<html>
 
<html>
Zeile 278: Zeile 278:
 
   ]
 
   ]
 
}
 
}
</syntaxhighlight>Wenn wir unseren Code durch einen Transpiler laufen lassen wollen, bedeutet das natürlich, dass wir einen "Build"-Schritt brauchen, um die Arbeit zu erledigen:
+
</syntaxhighlight>Wenn wir unseren Code durch einen Transpiler laufen lassen wollen, bedeutet das, dass wir einen "Build"-Schritt brauchen, um die Arbeit zu erledigen:
  
 
===Webpack===
 
===Webpack===
Zeile 309: Zeile 309:
 
|}
 
|}
 
Webpack ist ein sehr mächtiges, hoch-modulares Werkzeug um solche Bündel zu erstellen. '''Loader''' kümmern sich um die Kompilierung bestimmter Dateitypen für webpack. <code>babel-loader</code> ist zum Beispiel ein loader für JavaScript-Dateien.
 
Webpack ist ein sehr mächtiges, hoch-modulares Werkzeug um solche Bündel zu erstellen. '''Loader''' kümmern sich um die Kompilierung bestimmter Dateitypen für webpack. <code>babel-loader</code> ist zum Beispiel ein loader für JavaScript-Dateien.
 +
  
  

Version vom 3. Oktober 2020, 16:20 Uhr

Offizielles ReactJS-Icon

React ist die JavaScript-Bibliothek von Facebook, die sich zu einer sehr beliebten Technologie zur Erstellung dynamischer, testbarer und performanter Benutzeroberflächen entwickelt hat. Obwohl es kein vollwertiges Framework wie Angular oder Ember ist, ist React aufgrund seiner Konzentration auf funktionale komponentenbasierte Ansichten ohne (oder minimalen) internen Zustand eine gute Wahl für die Erstellung von Einzelseitenanwendungen (SPA) oder sogar dynamischen Unterkomponenten innerhalb einer seitenbasierten Anwendung.

React Einführung - Kernkonzepte

Das Modell von React verspricht durch die Konzepte des unidirektionalen Datenflusses und des „Virtual DOM“ den einfachen, aber trotzdem hochperformanten Aufbau auch komplexer Anwendungen.

Keine vollständige Anwendungsbibliothek

Da sich React nur mit dem Rendern von Daten an das DOM befasst, erfordert die Erstellung von React-Anwendungen in der Regel die Verwendung zusätzlicher Bibliotheken, wie z.B. für die (globale) Zustandsverwaltung (State-Management) und das Routing. Redux und React Router sind entsprechende Beispiele für solche Bibliotheken. [1]


Unidirektionaler Datenfluss

Anders als UI-Frameworks wie Angular verzichtet React bewusst auf eine bidirektionale Datenbindung. An deren Stelle tritt der unidirektionale Datenfluss, bei dem Daten stets nur in einer Richtung übergeben werden.

Was zunächst nach einer gravierenden Einschränkung klingt, stellt sich tatsächlich als Bereicherung dar. Der unidirektionale Datenfluss erhöht nämlich die Nachvollziehbarkeit, wie Daten innerhalb der Anwendung verteilt und verarbeitet werden. Das erleichtert die Analyse und bei Bedarf die Fehlersuche.


Komponenten

React-Komponenten sind kleine, wiederverwendebare Codestücke, die ein zu renderndes React-Element an die Seite zurückgeben. [2] Komponenten werden in React hierarchisch aufgebaut und können in dessen Syntax als selbst definierte HTML-Tags repräsentiert werden.

Vom Konzept her sind Komponenten wie JavaScript-Funktionen. Sie akzeptieren beliebige Eingaben (readonly “props” genannnt) und geben React-Elemente zurück, welche beschreiben was auf dem Bildschirm angezeigt werden soll. Der einfachste Weg eine Komponente zu definieren, ist eine JavaScript-Funktion zu schreiben:

function Welcome(props) {
  return <h1>Hallo, {props.name}</h1>;
}

Komponenten können ebenso als ES6-Klassen definiert werden:

class Welcome extends React.Component {
  render() {
    return <h1>Hallo, {this.props.name}</h1>;
  }
}

Komponenten können in mehrere kleinere Teile zerlegt und deren Funktionialität in anderen Komponenten wiederverwendet werden. Komponenten können andere Komponenten, Arrays, Strings und Nummern zurückgeben.


Kritik am Komponenten-zentrierten Modell von React

Anders als bei strikten MVC-Modellen wird in React ein komponentenzentriertes Modell vorgeschlagen, welches Logik für Interaktion und Darstellung innerhalb eines Objekts bündelt (Seperation of Concerns). Dies wird insbesondere aufgrund der weitverbreiteten strikten Trennung zwischen Markup und Logik in Form von Templating-Systemen oft kritisch gesehen. [3]

Darstellungselemente (!= Komponenten)

React-Elemente sind die Bausteine von React-Anwendungen. Elemente könnten mit dem allgemein bekannteren Konzept der “Komponenten” verwechselt werden. Ein Element beschreibt was man auf dem Bildschirm sehen möchtest. React-Elemente sind unveränderbar.

Normalerweise werden Elemente nicht direkt verwendet, sondern von Komponenten zurückgegeben. [2]

const element = <h1>Hallo, Welt</h1>;

Anders als die DOM Elemente eines Browsers, sind React Elemente schlichte kosten-effektive Objekte. React DOM kümmert sich um das Aktualisieren des DOMs und den dazugehörigen React Elementen.

Virtual DOM und DOM-Diffing

Offizielles React-Beispiel zum Thema DOM-Diffing

Die Kernidee von React besteht in der Annahme, dass der komplette, der betroffenen Komponente untergeordnete Anwendungsbaum bei jeder Änderung einer Eigenschaft der Komponente neu aufgebaut wird. Da es in der Praxis rechenintensiv sein kann, dies z. B. im Webbrowser innerhalb des DOM durchzuführen, wurde das Konzept des „Virtual DOM“ geschaffen. [3]

Die damit verbundene Technik des „DOM-Diffing“ beschreibt das selektive Aktualisieren des DOM auf Basis eines Vergleichs zwischen ursprünglichem und geändertem Virtual DOM.

JavaScript Syntax Extension (JSX)

JSX ist eine Syntaxerweiterung für JavaScript. Es ist ähnlich einer Template-Sprache, hat aber den vollen Leistungsumfang von JavaScript. [2]

React benötigt kein JSX, aber die Meisten empfinden es als hilfreiches Werkzeug, wenn sie in JavaScript-Code an der UI arbeiten. Zusätzlich bietet es React die Möglichkeit, bessere Fehlermeldungen und Warnungen anzuzeigen.


JSX ist auch ein Ausdruck

Jedes JSX Element ist eigentlich nur “syntactic sugar” für den Aufruf von React.createElement(component, props, ...children). Dementsprechend kannst du alles, was mit JSX möglich ist, auch in einfachem Javascript umsetzen. Siehe folgende Tabelle als Beispiel:

Originaler JSX-Code Mit Babel kompilierter JavaScript-Code (Siehe den offiziellen & interaktiven Online Babel-Compiler um "eigene Beispiele zu testen")
 1 class Hello extends React.Component {
 2   render() {
 3     return <div>Hello {this.props.toWhat}</div>;
 4   }
 5 }
 6 
 7 ReactDOM.render
 8   <Hello toWhat="World" />,
 9   document.getElementById('root')
10 );
1 class Hello extends React.Component {
2   render() {
3     return /*#__PURE__*/React.createElement("div", null, "Hello ", this.props.toWhat);
4   }
5 }
6 
7 ReactDOM.render( /*#__PURE__*/React.createElement(Hello, {
8   toWhat: "World"
9 }), document.getElementById('root'));

Nach dem Kompilieren werden JSX Ausdrücke als normale JavaScript-Funktionssaufrufe und als JavaScript-Objekte ausgewertet.

Das bedeutet, dass man JSX innerhalb von if-Blöcken und for-Schleifen verwenden, Variablen zuweisen, als Argument entgegennehmen oder aus einer Funktion zurückgeben kann.

JavaScript-Ausdrücke in JSX

Jeder valide JavaScript Ausdruck ist zwischen den geschweiften Klammern in JSX erlaubt. Zum Beispiel, 2 + 2, user.firstName, oder formatName(user) sind völlig valide JavaScript Ausdrücke.

Attribute in JSX festlegen

Attribute eines Tags/Elements werden wie in HTML/XML definiert, mit der Ausnahme dass man entweder String-Literale als Wert oder auch jeden validen JavaScript-Ausdruck mithilfe von den genannten Schweiften Klammern angeben kann:

// prop-Angabe mit einem String-Literal
const element = <div tabIndex="0"></div>;
// prop-Angabe mit einem JavaScript-Ausdruck
const element = <img src={user.avatarUrl}></img>;

Folgende Regeln gilt es zu beachten:

  • Setze keine Anführungszeichen um geschweifte Klammern um JavaScript-Ausdrücke in ein Attribut einzubinden. Benutze entweder Anführungszeichen (für Strings) oder geschweifte Klammern (für Ausdrücke) aber nicht beides zusammen im selben Attribut.
  • Da JSX näher an JavaScript als an HTML ist, verwendet React DOM camelCase als Namenskonvention für Eigenschaften anstelle der für HTML typischen schreibweise.
    • class wird in JSX zum Beispiel zu className, und tabindex zu tabIndex.


Kind-Elemente mit JSX angeben

Ist ein Element leer, kannst du es wie in XML mit /> schließen:

const element = <img src={user.avatarUrl} />;

JSX-Tags können Kind-Elemente enthalten:

const element = (
  <div>
    <h1>Hallo!</h1>
    <h2>Schön dich hier zu sehen.</h2>
  </div>
);

children prop

In den React-Dokumenten heißt es, dass props.children für Komponenten verwendet werden können, die "allgemeine Schachteln" darstellen und die "ihre Kinder-Elemente nicht im Voraus kennen". Das heißt dass eine Komponente im Normalfall keine Annahmen darüber machen sollte, was für ein Wert in props.children gefüttert wird - sie soll es einfach nur einbauen.

Im folgenden Beispiel bekommt die h1-Komponente 2 props übergeben:

  • className mit dem Wert "greeting" (String-Literal)
  • children mit dem Wert "Hallo Welt!" (String-Literal)
const element = (
  <h1 className="greeting">
    {/* Hier kann so gut wie alles drinnen stehen. (JavaScript-Ausdrücke die React-Elemente wiedergeben, ...)*/}
    Hallo Welt!
  </h1>
);

Im Prinzip entsteht daraus das folgende Objekt:

// Hinweis: Dies ist eine vereinfachte Struktur
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hallo Welt!'
  }
};


Komponenten-State und Lifecycle


Event Handhabung


Bedingte Darstellung


Formulare


State anheben


React Einführung - Weiteres


React Einführung - React-App-Entwicklung

Erstellen einer React-Anwendung

Das React Team empfiehlt bevorzugt diese Lösungen: [4]

  • Wenn man React lernt oder eine neue Single Page Anwendung erstellen will, hilft einem Create React App.
    • Create React App ist ein Open-Source npm-Skript dass einem automatisch eine vollständig funktionsfähige Entwicklungsumgebung für neue React-SPAs aufsetzt. Die verwendeten Entwicklungs-Toolchains sind der Compiler Babel und der Bundler webpack.
  • Wenn du eine vom Server gerenderte Webseite mit Node.js baust, dann probier Next.js.
    • Next.js ist ein beliebtes und leichtgewichtiges Framework für statische und server-gerenderte Anwendungen, die mit React erstellt wurden. Es enthält sofort einsatzbereite Styling- und Routing-Lösungen und setzt voraus, dass man Node.js als Serverumgebung verwendet.
  • Wenn du eine statische auf Inhalt orientierte Webseite baust, dann probier Gatsby.
    • Gatsby ist der beste Weg, statische Websites mit React zu erstellen. Es ermöglicht die Verwendung von React-Komponenten, gibt aber vorgerendertes HTML und CSS aus, um die schnellste Ladezeit zu garantieren.
  • Wenn du eine Komponentenbibliothek baust oder mit einer existierenden Codebasis integrierst, dann probiere flexiblere Werkzeuge:


Eine simple React-App-Entwicklungsumgebung Schritt-für-Schritt selbst aufsetzen

Quellen: "Creating a React-App.. From Scratch" (Medium), "Creating a New React App" (React-Doc), "Using React with Grails" (ObjectComputing)


React funktioniert nicht "einfach so". Es verwendet Schlüsselwörter und einen Syntax mit dem Node nichts anfangen kann (z.B. die Schlüsselwörter import und export, oder der JSX-Syntax). Es erfordert eine ziemlich umständliche Einrichtung, und Facebook hat mit "Create-React-App" eine Option bereitgestellt, die das Starten einer React-Anwendung einfach macht.

Warum sich dann die Mühe machen? Die Sache ist die, dass "Create-React-App" vieles von dem abstrahiert, was eine React-App überhaupt im Browser funktionieren lässt. Es gibt eine Reihe von Gründen warum man vielleicht eine eigene Implementierung machen will, oder zu-mindestens verstehen will welche Komponente im Prozess für was eigentlich zuständig ist.


Bestandteile einer typischen JavaScript Build Werkzeugkette

Node.js Logo

Typischerweise besteht eine JavaScript Build Werkzeugkette aus:

  • Einem Paket Manager wie Yarn oder npm, der einem Zugriff auf ein breites Ökosystem von Drittbibliotheken zur Verfügung stellt die man einfach installieren oder aktualisieren kann.
  • Einem Bundler wie webpack oder Parcel, der es einem erlaubt, modularen Code zu schreiben und ihn in kleine Pakete (Bundles) zu packen, unter anderem um die Ladezeit zu optimieren.
  • Einem Compiler/Transpiler wie Babel erlaubt es einem, Modernen JavaScript Code zu schreiben und ihn in Code umzuwandeln ("polyfill"en), den auch ältere Browser verstehen können.


Setup

Um zu beginnen erstellt man ein neues Verzeichnis für die React-Anwendung.

Als erstes initialisiert man das Verzeichnis wie jedes neues Node-basiertes Projekt mit dem Befehl npm init.

  • Falls man keine aktuelle Version der Node/NPM-SDK auf seinem System installiert hat, empfehle ich dringend nvm (Es ist wie sdkman, aber für node/npm - Ein Tool zum installieren/managen von SDKs mithilfe einer einfach Kommandozeilenumgebung).


Nun erstellt man im Projektordner folgende Struktur:

.
+-- public
  +-- index.html
+-- src

Unser public-Verzeichnis verwaltet alle statischen Assets und beherbergt vor allem unsere index.html-Datei, die als Einstiegspunkt unserer Anwendung für den Browser dient. Sie können das folgende HTML-Markup in eine neue Datei index.html innerhalb des public-Verzeichnisses kopieren:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8" />
 5     <!--
 6         The X-UA-Compatible meta tag allows web authors to choose what version of Internet Explorer the page should be rendered as.
 7         According to Microsoft, when using the X-UA-Compatible tag, it should be as high as possible in your document head.
 8 
 9         "Edge" mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode.
10 
11         See https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do
12     -->
13     <meta http-equiv="X-UA-Compatible" content="IE=edge">
14     <!--
15       Advised tag as described in https://material-ui.com/getting-started/usage/#responsive-meta-tag (and many other sources)
16       to ensure proper rendering and touch zooming for all devices:
17     -->
18     <meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width"/>
19     <title>React Starter</title>
20 </head>
21 
22 <body>
23     <!-- This will serve as the top-level-entry-point/container in which our React-Elements will hook into. -->
24     <div id="root"></div>
25     <noscript>
26     You need to enable JavaScript to run this app.
27     </noscript>
28     <!-- This will load/execute our "Plain Vanilla Javascript"-File that has previously been bundled & transpiled to be able to run by an browser (built) by us. -->
29     <script src="../dist/bundle.js"></script>
30 </body>
31 </html>

Jetzt, wo wir unsere HTML-Seite eingerichtet haben, können wir anfangen, ernsthaft zu werden. Wir müssen noch ein paar weitere Dinge einrichten. Zunächst müssen wir sicherstellen, dass der Code, den wir schreiben, kompiliert werden kann.

Installieren der benötigten NPM-Pakete

npm (Node Package Manager) LOGO

Natürlich brauchen wir React, und ReactDOM um unsere Anwendung im Browser zu rendern (React kann auch nativ auf mobilen Plattformen wie iOS verwendet werden, wobei ReactNative anstelle von ReactDOM verwendet wird).

# Dependencies used by the actual code/app (--save)
npm install react react-dom \
    --save

# Dependencies used for development purposes (--save-dev)
# babel-preset-react will be responsible to transpile all react-syntax (including JSX)
# babel-preset-es2015 will be responsible for transpiling the transpiled code from the previous preset so it can work on es2015-compatible-browsers
npm install babel-core babel-preset-es2015 babel-preset-react babel-cli \
    webpack webpack-cli babel-loader style-loader css-loader \
    --save-dev

Babel

BabelJS Logo

Da wir zum Schreiben unserer Komponenten JSX verwenden werden, müssen wir außerdem einen Transpiler verwenden, um unseren React-Code in "Plain Vanilla"-Javascript umzuwandeln. Moderne Javascript-Frameworks bewegen sich viel schneller als Web-Browser, und viele der Javascript-APIs, die häufig in React-Projekten verwendet werden, sind noch nicht Standard in Browsern.

babel ist ein beliebter Transpiler mit vielen "Voreinstellungen", die verschiedene Versionen der Javascript-Syntax verstehen und transpilieren können.

Um diese Voreinstellungen zu aktivieren erstellt man im Stammverzeichnis des Node-Projekts eine .babelrc-Datei mit diesem Inhalt:

{
  "presets": [
    "react",
    "es2015"
  ]
}

Wenn wir unseren Code durch einen Transpiler laufen lassen wollen, bedeutet das, dass wir einen "Build"-Schritt brauchen, um die Arbeit zu erledigen:

Webpack

Webpack Logo

Bundling ist der Prozess, bei dem importierte Dateien verfolgt und zu einer einzigen Datei zusammengeführt werden: einem "Bündel". Dieses Bundle kann dann auf einer Webseite eingebunden werden, um eine ganze Anwendung auf einmal zu laden. Abhängigkeiten werden während der Kompilierung aufgelöst, wodurch die Laufzeitgröße reduziert wird.

Betrachte folgendes Beispiel:

Originaler Code Beispielhafte Darstellung des resultierenden Bundels
1 // app.js
2 import { add } from './math.js';
3 
4 console.log(add(16, 26)); // 42
1 // math.js
2 export function add(a, b) {
3   return a + b;
4 }
1 function add(a, b) {
2   return a + b;
3 }
4 
5 console.log(add(16, 26)); // 42

Webpack ist ein sehr mächtiges, hoch-modulares Werkzeug um solche Bündel zu erstellen. Loader kümmern sich um die Kompilierung bestimmter Dateitypen für webpack. babel-loader ist zum Beispiel ein loader für JavaScript-Dateien.


Erstelle eine neue Datei im Stammverzeichnis des Projekts mit dem Namen webpack.config.js. Diese Datei exportiert ein Objekt mit der Konfiguration von webpack.

const path = require("path");
const webpack = require("webpack");

module.exports = {
  // tells Webpack where our application starts and where to start bundling our files.
  entry: "./src/index.js",
  // The following line lets webpack know we’re working in development mode 
  // — This saves us from having to add a mode flag when we run the development server.
  mode: "development",
  
  // The module object helps define how your exported javascript modules are transformed and which ones are included according to the given array of rules.
  module: {
    rules: [
      // Our first rule is all about transforming our ES6 and JSX syntax. 
      {
        // The test and exclude properties are conditions to match file against. In this case, it’ll match anything outside of the node_modules and bower_components directories.
        test: /\.(js|jsx)$/,
        exclude: /(node_modules|bower_components)/,
        // Since we’ll be transforming our .js and .jsx files as well, we’ll need to direct Webpack to use Babel. 
        // loader is a shorthand for the use property, when only one loader is being utilized.
        loader: "babel-loader",
        // Finally, we specify that we want to use the env preset in options.
        options: { presets: ['es2015', 'react'] }
      },
      // The next rule is for processing CSS. Since we’re not pre-or-post-processing our CSS, we just need to make sure to add style-loader and css-loader to the use property. css-loader requires style-loader in order to work. 
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  },
  // The resolve property allows us to specify which extensions Webpack will resolve — this allows us to import modules without needing to add their extensions.
  resolve: { extensions: ["*", ".js", ".jsx"] },
  // The output property tells Webpack where to put our bundled code. The publicPath property specifies what directory the bundle should go in.
  output: {
    path: path.resolve(__dirname, "dist/"),
    // If this is set incorrectly, you’ll get 404’s as the server won’t be serving your assets from the correct location!
    publicPath: "/dist/",
    filename: "bundle.js"
  },
};

NPM-Skripte erstellen

Für die Zwecke der Einfachheit werden wir auch ein paar "NPM Skripte" zu unserer Node-Datei package.json hinzufügen wollen, um webpack über npm auszuführen. Fügen Sie diese beiden Zeilen im Abschnitt "scripts" hinzu:

"scripts": {
    "watch": "webpack --watch --colors --progress",
    "bundle": "webpack",

Diese Skripte können nun auf folgende Weise ausgeführt werden: npm run [name]

Beim ausführen von npm run bundle werden Sie wahrscheinlich einen Fehler wie "Entry module could not be found." von webpack kriegen, weil unserer in webpack angegebener entry-point nicht existiert. Also, fangen wir endlich an React-Code zu schreiben:

Beispiel-Code

// /src/index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";

// ReactDOM.render is the function that tells React what to render and where to render it — In this case, we’re rendering a component called App (which we’ll create soon), and it’s being rendered at the DOM element with the ID "root".
ReactDOM.render(<App />, document.getElementById("root"));
// /src/App.js
// This file just holds a React component.

import React, { Component} from "react";
import "./App.css";

class App extends Component{
  render(){
    return(
      <div className="App">
        <h1> Hello, World! </h1>
      </div>
    );
  }
}

export default App;

Während wir noch hier sind, habe ich bereits erwähnt, dass Webpack auch CSS verarbeitet (und wir importieren es in unsere Komponente). Lassen Sie uns ein wirklich einfaches Stylsheet zum src-Verzeichnis hinzufügen:

// /src/App.css
// (kein statisches Asset im direkten Sinne - wird in die Javascript-Datei gebündelt und nur von dort aus erreichbar sein.)

.App {
  margin: 1rem;
  font-family: Arial, Helvetica, sans-serif;
}

Fertig

Nun können wir mithilfe von npm run bundle unseren Quellcode in eine einzelne, für den Browser verständliche und ausführbare Datei bündeln.

Jetzt sollten wir die index.html-Datei im Browser öffnen können und unsere Anwendung sollte erfolgreich geladen und angezeigt werden.