Node.js installieren: Button-Funktion ohne Browser auf dem Server prüfen

Um JavaScript auf einem Server auszuführen, muss man zuerst Node.js installieren. Ich habe Node.js 24.21.0 auf einem WordPress-Server mit Nginx und Apache installiert und mit jsdom 30.1.3 das Button-Skript einer Webseite ohne Browser geprüft.
Das nodejs im Standard-Repository ist 16.20.2, jsdom 30.1.3 für die Skriptprüfung verlangt aber Node.js 22.22.2 oder neuer. Deshalb habe ich über den dnf-Modul-Stream 24 installiert.
1️⃣ Wozu Node.js und jsdom auf dem Server installieren
Um Button-Skripte auf einem Server zu prüfen, braucht man zwei Dinge: Node.js und jsdom.
🔲 Node.js
JavaScript läuft normalerweise im Browser, doch mit Node.js kann auch der Server JavaScript lesen und ausführen.
Node.js zu installieren heißt, die JavaScript-Laufzeit, die es bisher nur im Browser gab, auch auf den Server zu bringen. Deshalb nutzt man Node.js, um Webserver zu bauen, Befehle zu schreiben, die viele Dateien auf einmal verarbeiten, oder Pakete wie jsdom zu laden und Seiten zu prüfen. Auch Ghost ist ein CMS, das auf Node.js läuft.
🔲 jsdom
jsdom ist ein Paket für Node.js, das HTML einliest und daraus ein Dokument macht, in dem man wie im Browser Buttons drücken kann. Es baut die Dokumentstruktur (DOM), die ein Browser beim Öffnen einer Seite erzeugt, ohne Bildschirm direkt im Server nach, sodass Skripte Buttons finden und Text ändern, als liefen sie in einem echten Browser. Da kein Fenster geöffnet wird, lässt es sich auf dem Server mit einem einzigen Befehl ausführen.
Das heißt: Was ein Mensch früher prüfte, indem er den Browser öffnete und alles einzeln anklickte, erledigt nun der Server per Befehl. Deshalb wird jsdom auch genutzt, um das Verhalten von Buttons nach jeder Änderung automatisch zu testen, nur Inhalte wie Titel und Links aus einer Seite herauszuziehen oder das HTML von Beiträgen in einem Rutsch zu bearbeiten.
Ruft man eine Seite mit PHP oder curl ab, sieht man nur das zuerst gelieferte HTML. Text, der sich nach einem Klick ändert, erscheint erst, wenn das Skript läuft.
Ein Browser durchläuft vier Schritte: Seite abrufen, Seite lesen, Button drücken und auf dem Bildschirm zeigen. jsdom führt bis auf das Anzeigen alle Schritte auf dem Server aus, deshalb prüft man Position und Größe eines Buttons im Browser.
2️⃣ Vor der Installation: Standard-Repository und Modul-Streams
Bevor man [dnf install nodejs] ausführt, prüft man zuerst, welche Version installiert würde. Das nodejs im Standard-Repository von AlmaLinux 9.8 ist 16.20.2.
dnf list --available nodejsAvailable Packages
nodejs.x86_64 1:16.20.2-8.el9_4 appstreamIm Modul-Repository gibt es vier Streams: 18, 20, 22 und 24. Am Prüfdatum stand der Stream 22 bei 22.23.2 und der Stream 24 bei 24.21.0.
dnf module list nodejsnodejs 18 common [d], development, minimal, s2i Javascript runtime
nodejs 20 common [d], development, minimal, s2i Javascript runtime
nodejs 22 common [d], development, minimal, s2i Javascript runtime
nodejs 24 common [d], development, minimal, s2i Javascript runtimeLaut npm-Registry verlangt jsdom 30.1.3 in der 22er-Reihe 22.22.2 oder neuer, in der 24er-Reihe 24.15.0 oder neuer oder ab 26. Sowohl der Stream 22 als auch der Stream 24 erfüllen diese Bedingung.
3️⃣ Node.js installieren: dnf module
Diesmal habe ich den Stream 24 installiert und vorher mit der Option [--assumeno] die Liste der zu installierenden Pakete geprüft.
dnf module install nodejs:24 --assumenoDie Liste enthielt nur fünf Pakete: nodejs, npm, nodejs-libs, nodejs-docs und nodejs-full-i18n. Pakete für Webserver, PHP oder Kernel waren nicht dabei. Nach der Prüfung installiert man mit der Option [-y].
dnf module install -y nodejs:24Dependencies resolved.
==============================================================================================
Package Architecture Version Repository Size
==============================================================================================
Installing group/module packages:
nodejs x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 70 k
npm noarch 1:11.19.0-1.24.21.0.1.module_el9.8.0+321+1555b6a2 appstream 2.1 M
Installing dependencies:
nodejs-libs x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 24 M
Installing weak dependencies:
nodejs-docs noarch 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 5.3 M
nodejs-full-i18n x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 8.9 M
Installing module profiles:
nodejs/common
Enabling module streams:
nodejs 24
Transaction Summary
==============================================================================================
Install 5 Packages
Total download size: 40 M
Installed size: 185 M[Installing weak dependencies] führt die schwachen Abhängigkeiten (weak dependencies) auf, also Pakete, die man sinnvollerweise mitinstalliert. Der Download umfasst 40M, die Installation 185M.
node -vv24.21.0npm -v11.19.0cat /etc/dnf/modules.d/nodejs.module[nodejs]
name=nodejs
stream=24
profiles=common
state=enablednode wurde als 24.21.0 und npm als 11.19.0 installiert. Die einzige durch die Installation geänderte Konfigurationsdatei ist [/etc/dnf/modules.d/nodejs.module]; darin sind der Stream 24 und das Profil common als aktiv eingetragen.
4️⃣ jsdom installieren und ein Button-Skript prüfen
jsdom wird mit npm in einen Arbeitsordner installiert, und den Arbeitsordner legt man außerhalb des Web-Roots an.
mkdir ~/jsdom-test && cd ~/jsdom-test
npm init -y[npm init -y] legt package.json mit Standardwerten an; danach wird jsdom in denselben Ordner installiert.
npm install jsdomadded 36 packages, and audited 37 packages in 2s
8 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesnpm ls jsdomjsdom-test@1.0.0 /root/jsdom-test
└── jsdom@30.1.3Es wurden 36 Pakete einschließlich jsdom 30.1.3 installiert, mit 0 bekannten Schwachstellen. Der Ordner node_modules im Arbeitsordner ist 26M groß.
node -e 'const { JSDOM } = require(`jsdom`); console.log(new JSDOM(`<h1>Hallo</h1>`).window.document.querySelector(`h1`).textContent)'HalloLiest jsdom ein HTML aus einem einzigen h1-Tag als Dokument ein und gibt den Text darin, [Hallo], aus, ist der Funktionstest abgeschlossen.
Ein Button-Skript zu prüfen heißt, auf dem Server zu kontrollieren, ob sich der Text nach dem Klick richtig ändert. Als Beispiel habe ich im Arbeitsordner eine HTML-Datei angelegt, in der ein Klick auf den Button [Kopieren] den Text zu [Kopiert] ändert.
cat btn.html<button id="copy">Kopieren</button>
<script>
document.getElementById('copy').addEventListener('click', function () {
this.textContent = 'Kopiert';
});
</script>Das Prüfskript liest die HTML-Datei mit jsdom ein, führt die Skripte aus und gibt den Text vor und nach dem Klick aus. Skriptfehler erscheinen als Zeilen, die mit [Fehler:] beginnen.
cat check.jsconst fs = require('fs');
const { JSDOM, VirtualConsole } = require('jsdom');
const vc = new VirtualConsole();
vc.on('jsdomError', (e) => console.log('Fehler:', e.message));
const dom = new JSDOM(fs.readFileSync(process.argv[2], 'utf8'), {
runScripts: 'dangerously',
virtualConsole: vc,
});
const btn = dom.window.document.querySelector('#copy');
console.log('Vor dem Klick:', btn.textContent);
btn.click();
console.log('Nach dem Klick:', btn.textContent);node check.js btn.htmlVor dem Klick: Kopieren
Nach dem Klick: KopiertNach dem Klick wechselt der Text zu [Kopiert] – das Button-Skript funktioniert also.
Ein einziger Tippfehler im Skript ändert das Ergebnis. Ich habe denselben Test mit einer Datei ausgeführt, in der das große I in getElementById durch ein kleines l ersetzt wurde.
sed 's/getElementById/getElementByld/' btn.html > btn-broken.html
node check.js btn-broken.htmlFehler: Uncaught [TypeError: document.getElementByld is not a function]
Vor dem Klick: Kopieren
Nach dem Klick: KopierenIn der ersten Zeile erscheint ein Fehler und das Skript bricht ab, sodass der Text auch nach dem Klick [Kopieren] bleibt.
Ich habe dem Button per CSS eine Breite von 120px und eine Höhe von 40px gegeben und dann seine Größe ausgegeben.
cat size.jsconst { JSDOM } = require('jsdom');
const dom = new JSDOM('<button id="copy" style="width:120px;height:40px">Kopieren</button>');
const btn = dom.window.document.querySelector('#copy');
console.log('Höhe:', btn.offsetHeight, '/ Breite:', btn.getBoundingClientRect().width);node size.jsHöhe: 0 / Breite: 0jsdom hat keinen Schritt, der auf den Bildschirm zeichnet, deshalb werden Höhe und Breite als 0 ausgegeben.
🔢 FAQ & empfohlene Inhalte







ℹ️ Affiliate-Hinweis
Die Inhalte dieser Website enthalten Affiliate-Links. Kauft ein Besucher über einen dieser Links ein Produkt oder eine Dienstleistung, erhält die Website vom Verkäufer eine Provision. Der Betrag, den der Käufer zahlt(bei Aktionsrabatten sinkt er ↓), steigt dadurch nicht. Angegebene Preise, Rabatte und Lagerbestände entsprechen dem Stand bei Erstellung und können abweichen; prüfe sie daher vor dem Kauf beim Verkäufer. Produkte werden nach eigenen Kriterien ausgewählt und bewertet, und Provisionen beeinflussen weder die Reihenfolge noch den Inhalt der Bewertungen.