Laravel Tools für WordPress: Webpack in elegant mit Laravel Mix

In der kleinen Serie zu Laravel Tools für WordPress, habe ich euch bereits Laravel Valet für die lokale Entwicklungsumgebung vorgestellt. Heute geht es wieder um ein Tool, was euch bei der Entwicklung von Themes & Plugins helfen kann. Besonders, wenn ihr an Block Editor (Gutenberg) Blöcken schraubt.

Laravel Mix vereinfacht euch die Arbeit mit Webpack enorm und spätestens, wenn ihr euren ersten Block in JavaScript programmiert, kommt ihr nicht mehr an Webpack (oder einem anderen JavaScript-Modul-Packer) vorbei. Die Konfiguration von Webpack empfinde ich aber als sehr kompliziert. Vor allem, wenn man noch nie mit React gearbeitet hat. Laravel Mix nimmt euch die Konfiguration in 80% der Fälle ab und reduziert den Konfigurationsaufwand extrem.

Beispiel: Die webpack.config.js vom Gutenberg Plugin umfasst 157 Zeilen. Mit Laravel Mix reichen euch die folgenden zwei Zeilen in der webpack.mix.js:

let mix = require('laravel-mix'); mix.react('blocks/myblock.js', 'dist/');

Installation

Laravel Mix könnt ihr genau wie Webpack und alle anderen Module/Abhängigkeiten über NPM installieren. Solltet ihr NPM noch nicht in eurem Plugin/Theme initialisiert haben, müsst ihr das zuerst erledigen.

Wechselt dazu im Terminal/Konsole in euer Plugin/Theme Verzeichnis und führt npm init -y aus. Anschließend habt ihr eine package.json Datei in eurem Verzeichnis.

Als nächstes installiert ihr Laravel Mix als Abhängigkeit: npm install laravel-mix --save-dev

Jetzt kopiert ihr noch die Standard-webpack.mix.js in euer Plugin/Theme-Verzeichnis: cp node_modules/laravel-mix/setup/webpack.mix.js ./

In der webpack.mix.js ist eine Beispielkonfiguration und die gesamte API für verschiedene JavaScript Frameworks wie React, Vue.js… sowie CSS-Frameworks wie SASS, LESS und PostCSS enthalten:

let mix = require('laravel-mix'); /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel application. By default, we are compiling the Sass | file for your application, as well as bundling up your JS files. | */ mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/'); // Full API // mix.js(src, output); // mix.react(src, output); <-- Identical to mix.js(), but registers React Babel compilation. // mix.preact(src, output); <-- Identical to mix.js(), but registers Preact compilation. // mix.coffee(src, output); <-- Identical to mix.js(), but registers CoffeeScript compilation. // mix.ts(src, output); <-- TypeScript support. Requires tsconfig.json to exist in the same folder as webpack.mix.js // mix.extract(vendorLibs); // mix.sass(src, output); // mix.less(src, output); // mix.stylus(src, output); // mix.postCss(src, output, [require('postcss-some-plugin')()]); // mix.browserSync('my-site.test'); // mix.combine(files, destination); // mix.babel(files, destination); <-- Identical to mix.combine(), but also includes Babel compilation. // mix.copy(from, to); // mix.copyDirectory(fromDir, toDir); // mix.minify(file); // mix.sourceMaps(); // Enable sourcemaps // mix.version(); // Enable versioning. // mix.disableNotifications(); // mix.setPublicPath('path/to/public'); // mix.setResourceRoot('prefix/for/resource/locators'); // mix.autoload({}); <-- Will be passed to Webpack's ProvidePlugin. // mix.webpackConfig({}); <-- Override webpack.config.js, without editing the file directly. // mix.babelConfig({}); <-- Merge extra Babel configuration (plugins, etc.) with Mix's default. // mix.then(function () {}) <-- Will be triggered each time Webpack finishes building. // mix.override(function (webpackConfig) {}) <-- Will be triggered once the webpack config object has been fully generated by Mix. // mix.dump(); <-- Dump the generated webpack config object to the console. // mix.extend(name, handler) <-- Extend Mix's API with your own components. // mix.options({ // extractVueStyles: false, // Extract .vue component styling to file, rather than inline. // globalVueStyles: file, // Variables file to be imported in every component. // processCssUrls: true, // Process/optimize relative stylesheet url()'s. Set to false, if you don't want them touched. // purifyCss: false, // Remove unused CSS selectors. // terser: {}, // Terser-specific options. https://github.com/webpack-contrib/terser-webpack-plugin#options // postCss: [] // Post-CSS options: https://github.com/postcss/postcss/blob/master/docs/plugins.md // });

Das Beispiel mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/'); kompiliert die app.js Datei im Ordner src und gibt sie im Ordner dist als app.js wieder aus und macht das gleiche mit der SASS-Datei app.scss, die als Stylesheet app.css ausgegeben wird.

Um euch lange webpack-Befehle in der Konsole zu sparen, solltet ihr in eurer package.json noch folgende scripts ergänzen:

"scripts": { "dev": "npm run development", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "watch": "npm run development -- --watch", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" }

Anschließend könnt ihr einfach npm run watch starten und Webpack kompiliert euer JavaScript/CSS sofort neu, wenn ihr beim Entwickeln etwas an einer Datei ändert und speichert. Zum Schluss kompiliert euch Webpack mit npm run prod eurer fertiges JavaScript/CSS, was ihr an eure Nutzer ausliefern könnt.

Block kompilieren

Entscheidend ist immer, was ihr als Funktion verwendet. Da Gutenberg auf React basiert, können wir unseren Block mit der mix.react Funktion kompilieren:

let mix = require('laravel-mix'); mix.react('blocks/myblock.js', 'dist/');

Zwar benötigt ihr nicht zwingend für die Entwicklung eines (einfachen) Blocks Webpack bzw. React, es macht aber einfach viel mehr Spaß mit import zu arbeiten und dank JSX statt …

return wp.element.createElement('p', { class: 'welcome' }, 'Hallo World')

… einfach …

return <p className="welcome">Hallo World</p>

… zu schreiben.

Übrigens installiert Laravel Mix die benötigten Abhängigkeiten wirklich erst, wenn man eine entsprechende Funktion z.B. mix.react verwendet. So wird der node_modules Ordner nicht unnötig aufgebläht.

Abhängigkeiten für euren Block könnt ihr entweder aus dem window.wp Objekt beziehen:

const { RichText } = wp.blockEditor;

Oder installiert die einzelnen Module via npm z.B. npm install @wordpress/block-editor --save und importiert sie in eurer JavaScript-Datei:

import { RichText } from '@wordpress/block-editor'

CSS Preprocessor verwenden

Larvel Mix hilft euch auch mit eurem CSS z.B., wenn ihr einen CSS-Transformator wie PostCSS, Sass oder LESS verwenden wollt.

Auch hier reicht (jeweils) nur eine Zeile:

mix.sass(src, output); mix.less(src, output); mix.postCss(src, output, [require('postcss-some-plugin')()]);

Und vieles mehr…

Laravel Mix kann euch noch bei vielen weiteren sonst nervigen Webpack-Konfigurationen helfen, zum Beispiel:

  • BrowserSync: Jedes Mal, wenn ihr eine Änderung an einer Datei vornehmt und speichert, lädt bzw. synchronisiert BrowserSync eure Testumgebung in eurem Browser.
  • Versioning: Jedes Mal, wenn ihr sich euer Output ändert, speichert Laravel Mix den Datei-Hash in der mix-manifest.json. Mit einer Hilfsfunktion, könnt ihr die mix-manifest.json in eurem WordPress Theme/Plugin auslesen und als Version für wp_register_style bzw. wp_register_script verwenden.
  • Minifizieren & Kombinieren: Ihr könnt Laravel Mix bzw. Webpack auch einfach einzelne CSS/JS-Datein kombinieren oder minifizieren lassen.

Mehr Details findet ihr in der Dokumentation zu Laravel Mix.

Fazit

Ich finde die Lernkurve bei Webpack einfach viel zu steil und bin sehr froh, dass man mit Laravel Mix alle wichtigen Features mit ein paar Zeilen verständlichen Codes lösen kann. Sicherlich holt man sich so eine zusätzliche Abhängigkeit ins Projekt, aber durch die Einfachheit von Laravel Mix sehe ich da auch in der Zukunft keine großen Probleme. Zur Not kann man sehr einfach über mix.dump() auf eine eigene Webpack-Konfiguration umsteigen.

Alternativen

Speziell für Blöcke gibt es das Toolkit create-guten-block von Ahmad Awais. Es konfiguriert ebenfalls Webpack perfekt für diesen Einsatz.

Eure Erfahrung?

Konfiguriert ihr Webpack selber? Nutzt ihr ein anderes Build Tool? Habt ihr bereits Laravel Mix ausprobiert? Hinterlasst gerne ein Kommentar!

Cover Picture: Foto von Vinicius "amnx" Amano bei Unsplash

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.