Inhalt
Webpack ist ursprünglich als Paketmanager für Projekte in Javascript geschaffen worden und verwaltet auch „Zubehör” wie css- und Typescript-Files, eingebettete Bilder oder die die Rückübersetzung in ältere ECMA-Versionen mit Babel. Aber ist es auch für ein WordPress-Projekt nutzbar?
Achtung! Der Artikel ist noch in Arbeit!
Das Problem
Die native WordPress-Unterstützung für Javascript ist schon etwas in die Jahre gekommen. Für den gelegentlichen Einsatz kleiner Skripte ohne viele Abhängigkeiten mögen wp_enqueue_script und wp_enqueue_style, ihre register-Schwestern und die Übergabe von Daten mittels wp_localize_script ausreichen.
Schwierig wird es, wenn man mit umfangreichen Scripts und vielen Abhängigkeiten arbeitet. Da geht oft nicht nur die Übersicht darüber verloren, welche Bibliotheken in welcher Version zu welchem Zeitpunkt im Projekt geladen werden müssen. Auch die Größe und Anzahl der nachzuladenden Dateien nimmt ständig zu, was die Webseite nicht gerade schneller macht.
Für reine Javascript-Projekte gibt es für solche Probleme Abhilfe. Der Package-Manager npm von node.js sorgt dafür, dass die nötigen Bibliotheken vorhanden und aktuell sind. Modul-Packer wie Webpack stellen Anwendungspakete zusammen, die nur genau die Scripts und Libraries enthalten, die wirklich nötig sind. Zudem kümmern sie sich auch um css, Images, Komprimierung und viele weitere Dinge, die dem Programmierer das Leben leichter machen.
Aber wie kann man die Vorteile von node.js und webpack in einem typischen WordPress-Projekt nutzen, wo neben dem Client-seitigen Javascript auf der Server-Seite Unmangen von PHP-Scripts werkeln?
Genau das soll dieser Artikel klären. Zunächst kümmern wir uns um die Grundlagen, nämlich die Installation der Plattform.
Installation von node.js und npm
Grundvoraussetzung für Webpack ist ein funktionierendes node.js und npm. Falls dies nicht ohnehin schon für das Projekt installiert war, holen wir das jetzt nach.
Für Debian gibt es ein fertiges Paket, das sowohl node.js als auch npm enthält. Ein Setup-Script von nodesource trägt die Paketquelle ein:
$ sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
Danach kann das Paket installiert werden:
$ sudo apt install nodejs
Nach erfolgreicher Installation sollte node.js und npm seine jeweilige Version ausgeben können:
$ node --version
v12.13.0
$ npm --version
6.13.1
Webpack installieren
Die Installation von Webpack übernimmt der node package manager npm:
$ npm install --save-dev webpack webpack-cli webpack-merge
So installiert wird webpack als Entwicklungs-Abhängigkeit in die package.json-Datei des lokalen Projekts eingetragen. Das Kommandozeilen-Paket webpack-cli muss seit Version 4 separat installiert werden. Das webpack-merge-Modul brauchen wir später, um mehrere Konfigurationen miteinander kombinieren zu können.
Verzeichnisstruktur erstellen
Zunächst erzeugen wir in der Entwicklungsumgebung ein build-Verzeichnis, in das später alle nur zur Erzeugung des Projektdateien nötigen Teile gespeichert werden. So bleibt das eigentliche Projektverzeichnis „sauber”. In diesem Verzeichnis werden die nötigen Konfigurationsdateien für Entwicklung und Produktion angelegt:
$ mkdir build
Webpack-Konfiguration
Die Webpack-Konfiguration wird in einen gemeinsamen und je einen Teil für Entwicklung und Produktion aufgespalten. Die gemeinsame Konfiguration erzeugen wir in build/config.base.js
:
module.exports = {
// gemeinsame webpack Konfiguration
}
Die Produktions-Konfiguration wird in build/config.production.js
eingetragen:
const merge = require('webpack-merge')
module.exports = merge(require('./config.base.js'), {
mode: 'production'
// webpack Konfiguration für die Produktions-Umgebung
})
Schließlich erzeugen wir build/config.development.js
für die Entwicklungs-Umgebung:
const merge = require('webpack-merge')
module.exports = merge(require('./config.base.js'), {
mode: 'development',
watch: true
// webpack Konfiguration für die Entwicklungs-Umgebung
})
Die eigentlichen Konfigurationsanweisungen fügen wir später hinzu.
Die Entwicklungs- und Produktions-Konfiguration lädt jeweils die gemeinsame Konfiguration config.base.js und fügt ihre speziellen Definitionen hinzu. Die jeweilige Konfigurationsdatei teilt man webpack mit dem --config Schalter mit, z.B.
npx webpack --config build/config.development.js
Zur Arbeitserleichterung kann man sich Abkürzungen für diese Kommandos in package.json definieren:
...
{
"scripts": {
"dev": "webpack --config build/config.development.js",
"prod": "webpack --config build/config.production.js"
}
}
...
Damit ruft man Webpack mit der jeweiligen Konfiguration einfach mit npm run build
bzw. npm run dev
auf.
Pfade definieren
Ebenfalls zur Arbeitserleichterung kann man in build/paths.js
Pfade definieren, die dann in anderen Konfigurationen genutzt werden können:
const path = require('path')
module.exports = {
// Pfad zu den Quelldateien, insbesondere index.js
SRC: path.resolve(__dirname, '..', 'public'),
// Der Pfad zu den Anwendungspaketen
DIST: path.resolve(__dirname, '..', 'public', 'dist'),
// öffentlicher Pfad
ASSETS: '/dist'
}
Einen Einstiegspunkt definieren
In der gemeinsamen Konfigurationsdatei build/config.base.js
definieren wir den Einstiegspunkt der Applikation als entry point im exports-Block. Das ist das Script, das wir später im PHP des WordPress-Servers per wp_enqueue_script einbinden.
const path = require('path')
const { SRC, DIST, ASSETS } = require('./paths')
module.exports = {
entry: {
scripts: path.resolve(SRC, 'js', 'index.js')
},
output: {
// Das dist-Verzeichnis enthält die Anwendungespakete
path: DIST,
// Der Startpunkt heißt "scripts.js"
filename: '[name].js',
// Die URL zum Aufruf des Anwendungspakets
publicPath: ASSETS
}
}
Gibt es mehrere solcher eingebundener Scripts, müssen auch mehrere Einstiegspunkte definiert werden. Sämtliche Abhängigkeiten dieser Scripts, die ansonsten Stück für Stück im PHP des WordPress geladen werden müssten, stecken aber schon im jeweiligen Anwendungspaket, so dass wir uns darum nicht mehr kümmern müssen.
Die initiale Javascript-Datei
Das „Hauptprogramm” js/index.js importiert die nötigen node.js-Module, zum Beispiel:
import './jquery.min.js'
import './jquery.migrate.js'
import './bootstrap.js'
Das Kommando npm run prod
erzeugt dann in DIST eine Datei script.js, die im html des Projekts mit einem <script> Tag eingebunden wird. Sie kümmert sich um alle eingebundenen Importe.
Quellen:
- Using webpack with an existing PHP and JS project
https://stackoverflow.com/questions/43436754/using-webpack-with-an-existing-php-and-js-project - A Beginner’s Guide to Webpack 4 and Module Bundling
https://www.sitepoint.com/beginners-guide-webpack-module-bundling/ - The Webpack Book
https://survivejs.com/webpack/introduction/ - Configuring Webpack in WordPress for the First Time
https://www.ibenic.com/configuring-webpack-wordpress/ - Compile JavaScript with Webpack in a WordPress Plugin
https://webdevstudios.com/2019/01/15/compile-javascript-with-webpack-in-a-wordpress-plugin/