Bei der Entwicklung von Javascript-Applikationen stehen Entwickler immer vor den gleichen Herausforderungen. Wie kann ich meinen Code skalierbar strukturieren? Was muss ich beachten, damit mein Code auch in älteren Browsern zuverlässig läuft? Wie kann ich den Workflow insgesamt optimieren?

Eine Antwort ist die Verwendung von Module Bundler wie Webpack. Mit Webpack können wir effizient skalierbaren Code schreiben, der auch noch in (fast) allen Browsern läuft. Wir müssen lediglich die Einstellungen setzen und Webpack macht den Rest. Außerdem gibt es viele Erweiterungen zum Beispiel für SCSS, ES11, Bilder und Fonts.

Wenn wir WordPress Plugins oder Themes entwickeln, nutzen wir Webpack für unsere Javascript-Applikationen. Im Folgenden zeigen wir wie wir Webpack in Plugins nutzen. Hier ein Überblick:

  • WordPress Plugin
  • Webpack
    • Entries
    • Loader/Plugins
    • Externe Libraries
    • Befehle
  • Plugin packen
  • Fazit

WordPress Plugin

In WordPress werden verschiedene Plugin-Strukturen verwendet, wie z.B. WPPB. Jeder wird hier seine eigenen Vorlieben haben. Unsere Struktur sieht wie folgt aus:

admin/
includes/
languages/
templates/
libs/
index.php

In includes/ wird nach Features sortiert. Jedes Feature kann dabei eigene JS-, CSS- und PHP-Files haben. Das bedeutet wiederum, dass wir überall Skripte liegen haben, die wir bei der Verwendung von Webpack berücksichtigen müssen.

Webpack

Um Webpack in unserem Plugin nutzen zu können, verwenden wir den Paketmanager npm. Mit npm können wir auch später Erweiterungen oder andere Libraries laden, wie jQuery, Vuejs oder React. Nachdem mit npm init der Paketmanager im Projekt eingerichtet wurde, kann Webpack direkt über npm install --save-dev webpack webpack-cli hinzugefügt werden.

Anschließend brauchen wir die Webpack Konfigurationsdatei webpack.config.js:

const path = require('path')

module.exports = env => {
  let mode = env && env.production ? 'production' : 'development'

  return {
    target: 'web',
    mode: mode,
    entry: {
      main: './main.js',
    },
    output: {
      path: path.resolve(__dirname, 'dist') 
    },
    plugins: [],
    externals: {},
    module: {
      rules: [{...}] 
    }
  }
}

Entries

Die Entry-Files sind Startpunkte für Webpack. Jede erzeugt mindestens eine kompilierte Datei. Diese können manuell eingetragen werden. Da wir allerdings überall in unserem WordPress-Plugin Entry-Files liegen haben können, suchen wir diese per Funktion automatisch. Lediglich die Dateinamen müssen angepasst werden.

const path = require('path');
const fs = require('fs');

function getAllFilesOfType(p, type, recursive = false, obj = {}); // siehe unten

let allEntries = getAllFilesOfType(path.resolve(__dirname, 'includes'), '\.entry\.js', true);
allEntries = Object.assign(allEntries, getAllFilesOfType(path.resolve(__dirname, 'admin'), '\.entry\.js', true));

module.exports = env => {
  // ...
  entry: allEntries,
  // ...
}

Jedes Skript mit der Endung .entry.js wird über diese Funktion in unserem Projekt als Entry-File festgelegt. Die kompilierten Dateien haben dann die einfache Endung .js. Das hat unter anderem den Vorteil, dass die Namen nicht auch noch in den PHP-Files angepasst werden müssen.

Loader/Plugins

Mit Loadern und Plugins können wir andere Dateien wie SCSS, Bilder, Fonts und andere Funktionalität integrieren. Als Beispiel fügen wir einmal SCSS und Babel hinzu.

// in webpack.config.js unter module
// Loader und Plugins müssen über npm nachgeladen werden

module: {
  rules: {
    { test: /s[ac]ss$/, use: ['style-loader', 'css-loader', 'sass-loader']},
    { test: /\.(js)/, use: ['babel-loader']}
  }
}

Externe Libraries

Da sich in einigen Plugins die verwendeten Bibliotheken doppeln können, sollten diese nicht immer in jedem Plugin kompiliert werden. Hierfür ist die Einstellung externals zu verwenden. Hierzu ein Beispiel:

//import in einer js-File
import Vue from 'vue';
import axios from 'axios';

//externals in webpack.config.js
externals: {
  vue: 'Vue',
  axios: 'axios'
}

Wenn zwei WordPress Plugins z.B. Vuejs verwenden, fügen wir in beiden Plugins die Library hinzu und stellen sie über das gleiche Handle wp_register_script('vuejs', ...) zur Verfügung. Somit wird Vue nur einmal geladen. In beiden Plugins muss natürlich auch dann die Einstellung in den externals entsprechend gesetzt sein, damit die Libraries nicht mitkompiliert werden. Insbesondere für WordPress Standard-Bibliotheken ist dies von großer Wichtigkeit.

Befehle

Um Webpack auszuführen verwenden wir die folgenden Befehle:

webpack --watch // für das bequeme Development
webpack --env production // als Build

Fazit

Webpack lässt sich relativ leicht in WordPress Plugins oder Themes verwenden. Falls man einmal ein gutes Template erstellt hat, kann man ohne Aufwand alle Vorteile von Webpack nutzen. Somit können wir bequem skalierbaren ES11 Code schreiben, der zuverlässiger und effizienter läuft.

Für WordPress Projekte sollte man allerdings einige Vorkehrungen treffen, damit man Webpack einfach integrieren kann. Ein automatisches Erkennen der Entry-Files ist, wie bereits gezeigt, eine gute Möglichkeit.

Es gibt noch viele Erweiterungen und Möglichkeiten um den eigenen Workfllow und Code zu verbessern. Beispielweise können wir noch ein Skript verwenden, welches das Plugin automatisch als ZIP-Archiv packt.

 

Die vollständige getAllFilesOfType-Funktion:

function getAllFilesOfType(p, type, recursive = false, obj = {}) {
  let regex = new RegExp(type, 'i');
  let allItems = fs.readdirSync(p, {withFileTypes: true});
  for (let i = 0; i < allItems.length; i++) {
    let item = allItems[i];
    if ( item.isDirectory() ) {
      getAllFilesOfType(path.resolve(p, item.name), type, recursive, obj);
    } else if ( item.isFile() && item.name.match(regex) ) {
      let entryPath = path.resolve(p, item.name).replace(__dirname, '');
      let entryName = entryPath.replace(type, '');
      entryPath = '.' + entryPath;
      obj[entryName] = entryPath;
    }
  }
  return obj;
}