React-Komponenten-Module mit Webpack
Webpack als Build-System ermöglicht es, React-Komponenten als eigenständige Module zu publizieren. Damit können React-Komponenten in mehreren Projekten wiederverwendet werden.
Das Ziel ist, dass die zur Verfügung gestellten Komponenten aus ES5-Code und plain CSS bestehen, damit sie einfach über import oder require Anweisungen verwendbar werden. So ist die Integration in andere Projekte mit wenig Integrationsaufwand möglich.
Als Beispiel zu diesem Artikel haben wir den react-json-syntax-highlighter zur Verfügung gestellt. Dabei kommen folgende Technologien zum Einsatz:
- React.js
- npm zur Paket-Verwaltung
- Webpack als Build-System
- Babel 6 um ES6 zu unterstützen
- Stylus (Alternative zu LESS oder SASS) als CSS-Preprocessor
Aus technischer Sicht lässt sich die Aufgabe folgendermaßen beschreiben:
- Erstellen eines npm-Moduls
- Einrichten von Webpack als Build-System
- Konfiguration von Webpack, um die gewünschten Artefakte zu erzeugen
In diesem Artikel gehen wir auf die Besonderheiten ein, die ein Modul, das React-Komponenten zur Verfügung stellen soll, beachten muss.
Babel-Loader
{ test: /\.js?/, excludes: /(node_modules)/, loader: 'babel', query: { presets: ['es2015', 'react'] } }
Durch die Verwendung des Babel-Loaders, wird ES6 in ES5 umgewandelt. Als Presets (Presets sind eine Sammlung von Babel-Plugins, die im Transpilling-Prozess verwendet werden) werden ES2015 und react verwendet, damit die entsprechenden Umwandlungen durchgeführt werden.
Loaders um CSS zu erzeugen
{ test: /\.styl$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader!autoprefixer-loader!stylus-loader') }
Durch die verschachtelte Verwendung des ExtractTextPlugins, des style-loaders, css-loader, autoprefixer-loader und stylus-loader wird von Webpack eine einzelnes ‘plain CSS’ Build-Artefakt erzeugt.
[call-to-action-react /]
Externals
externals: [{ react: { root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react' } }]
Dieser Konfigurationsabschnitt stellt den wichtigsten Unterschied zu einem normalen Projekt dar. Hier wird Webpack so konfiguriert dass es React nicht in das Javascript Build-Artefakt integriert. Dies spiegelt sich auch in der package.js wider, in der React als Peer-Depenendency angeführt wird.
"peerDependencies": { "react": "15.0.1", "react-dom": "15.0.1" }
Output
output: { filename: 'dist/ReactJsonSyntaxHighlighter.min.js', libraryTarget: 'umd', library: 'ReactJsonSyntaxHighlighter' }
Webpack wird damit angewiesen, ein importierbares Bibliotheks-Artefakt zu erzeugen.
Plugins
plugins: [ new ExtractTextPlugin('dist/ReactJsonSyntaxHighlighter.css', { allChunks: true }), new webpack.optimize.DedupePlugin(), new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin({ compress: { screw_ie8: true, warnings: false } }) ]
Die Plugins werden so aneinander gereiht, dass in einem ersten Schritt CSS in ein eigenes Artefakt extrahiert wird. Die weitere Schritte dienen dazu, das erzeugte Javascript-Artefakt möglichst klein werden zu lassen.
Export in index.js
In der index.js muss die Komponente, die an anderer Stelle importiert werden soll, exportiert werden.
Npm-Konfigurationen
In .npmignore werden alle Ressourcen angeführt, die von npm nicht publiziert (npm publish) werden sollen. Konkret wird src und playground ausgeschlossen, weil die Inhalte beider Verzeichnisse für die Verwendung der React-Komponente nicht benötigt werden.
Entwicklungsmodus
Um die Entwicklungszyklen abzukürzen, steht der Playground zur Verfügung. Er enthält eine minimale Konfiguration, die einen node.js-Server im React-Hot-Reload-Modus startet:
npm run dev
Damit kann die Komponente isoliert verwendet werden.
Integration der Komponente in ein Projekt
Nach der Installation der Komponente als npm-Dependency
npm install --save react-json-syntax-highlighter
ist die Integration über import– oder require-Anweisungen möglich:
import ReactJsonSyntaxHighlighter from 'react-json-syntax-highlighter'
Resümee
Wer bereits Erfahrung mit der Verwendung von Webpack hat, sollte mit dieser Anleitung einfach ein eigene React-Komponenten als Modul zur Verfügung stellen können. Mit unserem Projekt indoqa-react-redux zeigen wir, wie man mit npm und Webpack ein React/Redux-Projekt aufsetzt.