Eine Session fuer Backend-Logik und Build-Pipeline
Bei Hyva-Theme-Projekten liegt der Fehler oft nicht klar auf einer Seite: Ist die Tailwind-Klasse falsch generiert oder wird sie vom Watcher gar nicht erst erkannt? PhpStorm kann Xdebug-Sitzung und Node-Prozess in einer einzigen Compound-Konfiguration buendeln, sodass beide Seiten synchron pausieren.
Inhaltsverzeichnis
- 1. Warum getrenntes Debugging bei Hyva-Projekten an seine Grenzen stoesst
- 2. Das Grundprinzip: Compound-Konfigurationen buendeln Sessions
- 3. Xdebug-Startpunkt im Docker-Container korrekt setzen
- 4. Node-Prozess des Watchers mit Inspector-Flag starten
- 5. Compound-Konfiguration in der PhpStorm-Oberflaeche anlegen
- 6. Breakpoints ueber Sprachgrenzen hinweg koordinieren
- 7. Praxisbeispiel: Verschwundene Tailwind-Klasse aufspueren
- 8. Performance-Fallstricke bei parallelem Debugging
- 9. Wann sich der Aufwand nicht lohnt und welche Alternativen es gibt
- 10. Zusammenfassung
- 11. FAQ
1. Warum getrenntes Debugging bei Hyva-Projekten an seine Grenzen stoesst
Ein typisches Hyva-Setup besteht aus zwei parallel laufenden Prozessen: dem Magento-PHP-Backend, das ViewModels und phtml-Templates rendert, und einem Node-basierten Tailwind-Watcher, der bei jeder Aenderung die CSS-Klassen neu generiert. Taucht ein Layout-Fehler auf, ist oft unklar, welcher der beiden Prozesse verantwortlich ist: Erzeugt die PHP-Seite eine falsche Klasse, oder erkennt der Tailwind-Scanner das Pattern gar nicht erst und purged die Klasse weg.
Wer beide Seiten getrennt debuggt, wechselt staendig zwischen zwei Xdebug-Sessions und einer separaten Node-Inspector-Verbindung im Chrome DevTools Fenster. Der zeitliche Zusammenhang zwischen PHP-Ausgabe und Node-Verarbeitung geht dabei verloren, weil man nie beide Haltepunkte im gleichen Moment beobachten kann. Genau hier setzt eine gemeinsame Debug-Session in PhpStorm an, die beide Welten in einem Fenster zusammenfuehrt. Gerade bei Teams, die neu in ein bestehendes Hyva-Projekt einsteigen, spart dieser Ansatz erhebliche Einarbeitungszeit, weil der Zusammenhang zwischen Backend und Build-Pipeline direkt sichtbar wird, statt muehsam aus zwei getrennten Werkzeugen rekonstruiert werden zu muessen.
2. Das Grundprinzip: Compound-Konfigurationen buendeln Sessions
PhpStorm kennt neben einzelnen Run/Debug-Konfigurationen den Typ Compound. Eine Compound-Konfiguration startet mehrere hinterlegte Konfigurationen mit einem einzigen Klick und haelt sie waehrend der gesamten Sitzung aktiv. Fuer unseren Fall werden zwei Kind-Konfigurationen kombiniert: eine PHP Remote Debug Konfiguration fuer den Docker-Container und eine Attach to Node.js/Chrome Konfiguration fuer den laufenden Watcher-Prozess.
Jede Kind-Konfiguration behaelt ihre eigenen Breakpoints, Watches und Variablenansichten, wird aber im selben Debug-Tool-Fenster als eigener Tab angezeigt. Pausiert eine Seite an einem Breakpoint, laeuft die andere unbeeintraechtigt weiter, bis sie selbst auf einen Haltepunkt trifft. Dadurch entsteht eine gemeinsame Zeitleiste, ohne dass man Fenster wechseln oder Tools synchronisieren muss. Ein weiterer Vorteil zeigt sich beim Team-Onboarding: Die Compound-Konfiguration laesst sich als Projektdatei versionieren und mit ins Repository aufnehmen, sodass neue Kolleginnen und Kollegen dieselbe Debug-Umgebung mit einem Klick uebernehmen koennen, ohne jede Einzelkonfiguration selbst nachzubauen.
<!-- .idea/runConfigurations/Compound_PHP_Node.xml -->
<component name="ProjectRunConfigurationManager">
<configuration name="PHP + Node Watcher" type="CompoundRunConfigurationType">
<toRun name="Listen for PHP Debug Connections" type="PHP Remote Debug" />
<toRun name="Attach Tailwind Watcher" type="NodeJSRemoteDebugRunConfigurationType" />
<method v="2" />
</configuration>
</component>
3. Xdebug-Startpunkt im Docker-Container korrekt setzen
Damit PhpStorm ueberhaupt Breakpoints im PHP-Code treffen kann, muss Xdebug im Container aktiv sein und der richtige client_host konfiguriert werden. Im Mark-Shust-Setup aktiviert man Xdebug ueber den Wrapper bin/xdebug enable, der die passende ini-Datei einbindet und den Container neu startet. Wichtig ist die Path-Mapping-Konfiguration in PhpStorm, damit der Container-Pfad /var/www/html/app/code korrekt auf das lokale src/app/code Verzeichnis abgebildet wird.
Ein haeufiger Stolperstein ist ein falsch gesetzter xdebug.client_host, wenn der Container in einem eigenen Docker-Netzwerk laeuft. Auf Linux funktioniert meist die Docker-Bridge-IP, auf macOS und Windows ist host.docker.internal die zuverlaessigere Wahl. Ohne korrektes Mapping verbindet sich Xdebug zwar, aber PhpStorm zeigt die Breakpoints als nicht erreichbar an, was oft faelschlich als Xdebug-Fehler statt als Netzwerkproblem interpretiert wird. Ein schneller Test besteht darin, den Xdebug-Log-Modus temporaer auf einen hoeheren Detailgrad zu stellen und im Container-Log nachzuvollziehen, ob ueberhaupt ein Verbindungsversuch beim konfigurierten Host ankommt, bevor man an der PhpStorm-Konfiguration selbst weitersucht.
; docker/php/xdebug.ini
zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.idekey=PHPSTORM
4. Node-Prozess des Watchers mit Inspector-Flag starten
Der Tailwind-Watcher laeuft normalerweise ueber ein npm-Skript, das den Build-Prozess im Watch-Modus haelt. Damit PhpStorm sich per Attach to Node.js/Chrome anhaengen kann, braucht der Node-Prozess das Flag --inspect oder --inspect-brk, das einen Debug-Port oeffnet. In einem docker-npm-Setup wird dieses Flag direkt im package.json-Skript hinterlegt, damit es bei jedem Start automatisch aktiv ist.
Laeuft der Node-Prozess ebenfalls im Container, gilt dieselbe Netzwerk-Ueberlegung wie bei Xdebug: Der Inspector-Port muss aus dem Container heraus exponiert und in PhpStorm unter der Node.js-Remote-Konfiguration mit der richtigen Host-Adresse hinterlegt werden. Ein haeufiger Fehler ist, den Port nur intern zu binden, sodass PhpStorm von aussen keine Verbindung aufbauen kann, obwohl der Prozess selbst fehlerfrei startet. In der docker-compose.yml des Projekts muss der gewaehlte Inspector-Port zusaetzlich explizit als Port-Mapping eingetragen werden, sonst bleibt er selbst bei korrekter Bindung innerhalb des Containers von aussen unerreichbar.
{
"scripts": {
"watch:tailwind": "node --inspect=0.0.0.0:9229 ./node_modules/.bin/tailwindcss -i ./web/tailwind/tailwind-source.css -o ./web/css/styles.css --watch"
}
}
5. Compound-Konfiguration in der PhpStorm-Oberflaeche anlegen
In der Praxis geht man ueber Run, Edit Configurations und legt zunaechst die beiden Einzelkonfigurationen an: eine PHP Remote Debug fuer den Docker-Server und eine Attach to Node.js/Chrome mit Host und Port des Inspector-Sockets. Erst danach erstellt man ueber das Plus-Symbol eine neue Compound-Konfiguration und waehlt beide vorhandenen Eintraege als Kinder aus.
Ein sprechender Name wie PHP + Node Watcher und ein zugewiesenes Tastaturkuerzel machen die Konfiguration im Alltag praktikabel. Wichtig zu wissen: Beendet man die Compound-Session ueber den Stop-Button, werden beide Kind-Sessions sauber getrennt, der Docker-Container selbst laeuft aber unbeeinflusst weiter, sodass kein erneuter Neustart der Umgebung noetig ist.
6. Breakpoints ueber Sprachgrenzen hinweg koordinieren
Der eigentliche Mehrwert zeigt sich, wenn man in der ViewModel-Klasse einen PHP-Breakpoint setzt, der eine dynamische Klassenliste zusammenbaut, und gleichzeitig im Node-Watcher einen Breakpoint in der Transformationsfunktion, die die CSS-Ausgabe schreibt. Beim Laden der Seite greift zuerst der PHP-Breakpoint, weil das Rendering vor jedem CSS-Rebuild passiert.
Erst wenn man eine Template-Datei speichert, die der Tailwind-Scanner beobachtet, greift der Node-Breakpoint erneut. Wer diese Reihenfolge kennt, vermeidet falsche Schluesse, etwa die Annahme, eine Klasse fehle im CSS, obwohl sie schlicht noch nicht neu gebaut wurde, weil der Watcher den betroffenen Dateipfad gar nicht ueberwacht.
// app/code/Mironsoft/Theme/ViewModel/HeroBanner.php
public function getWrapperClasses(): string
{
$classes = ['flex', 'items-center'];
if ($this->isFullWidth()) {
$classes[] = 'w-full'; // <- Breakpoint hier setzen
}
return implode(' ', $classes);
}
7. Praxisbeispiel: Verschwundene Tailwind-Klasse aufspueren
Ein konkreter Fall aus der Praxis: Eine bedingte Klasse wird per String-Konkatenation im phtml-Template gebaut, zum Beispiel 'bg-' . $color . '-500'. Der Tailwind-JIT-Scanner kann dieses Muster nicht statisch erkennen, weil er nur vollstaendige Klassennamen im Quelltext findet, keine zur Laufzeit zusammengesetzten Strings. Die Debug-Session zeigt im PHP-Teil, dass der korrekte Klassenname erzeugt wird. Ohne die kombinierte Session waere man vermutlich zunaechst davon ausgegangen, der Fehler liege im PHP-Code selbst, und haette wertvolle Zeit mit der Fehlersuche an der falschen Stelle verbracht.
Im Node-Teil bestaetigt ein Log-Statement im Watcher, dass die Klasse im finalen CSS fehlt, weil sie beim Scan-Vorgang nie als vollstaendiger String auftaucht. Die Loesung besteht darin, alle moeglichen Klassenkombinationen entweder explizit auszuschreiben oder sie in die Safelist der Tailwind-Konfiguration aufzunehmen, damit der Purge-Vorgang sie nicht entfernt.
// tailwind.config.js
module.exports = {
content: ['../**/*.phtml'],
safelist: [
'bg-red-500', 'bg-green-500', 'bg-blue-500',
],
};
8. Performance-Fallstricke bei parallelem Debugging
Zwei aktive Debug-Engines gegen einen Docker-Container erhoehen spuerbar die Latenz jeder Step-Aktion, besonders wenn viele Watch-Ausdruecke gleichzeitig ausgewertet werden. Jede Watch, die ein komplexes Objekt oder ein grosses Array beobachtet, wird bei jedem Breakpoint neu berechnet, was die Reaktionszeit der IDE merklich verlangsamt.
In der Praxis hilft es, Watches auf das Noetigste zu beschraenken und die maximale Anzahl angezeigter Array-Elemente in den Debugger-Einstellungen zu reduzieren. Auch die Option Force step into sollte global deaktiviert bleiben, da sie bei aktiver Compound-Session sonst versucht, in Framework- und node_modules-Code hineinzuspringen, was die Sitzung spuerbar traege macht. Wer regelmaessig mit grossen Produktdatenmengen arbeitet, sollte zusaetzlich die Anzeige von Objektreferenzen im PHP-Debugger auf eine geringere Tiefe begrenzen, da tief verschachtelte ViewModel-Objekte sonst bei jedem Halt vollstaendig aufgeloest werden und die Reaktionszeit weiter verschlechtern.
9. Wann sich der Aufwand nicht lohnt und welche Alternativen es gibt
Fuer einfache, klar lokalisierte Bugs ist eine einzelne Debug-Session weiterhin schneller aufgesetzt als eine Compound-Konfiguration. Der Mehraufwand lohnt sich vor allem bei schwer reproduzierbaren Problemen, die genau an der Schnittstelle zwischen serverseitigem Rendering und clientseitigem Build entstehen, etwa bei Timing-Problemen zwischen Cache-Invalidierung und Watcher-Trigger.
Als leichtgewichtige Alternative bieten sich korrelierte Log-Ausgaben an: Beide Prozesse schreiben Zeitstempel in ein gemeinsames Log-Format, sodass man den Ablauf nachtraeglich rekonstruieren kann, ohne live debuggen zu muessen. Fuer wiederkehrende Analysen ist das oft praktikabler als jedes Mal eine vollstaendige Compound-Session neu zu starten.
| Ansatz | Setup-Aufwand | Staerke | Grenze |
|---|---|---|---|
| Getrennte Sessions | Gering | Schnell fuer isolierte Bugs | Kein zeitlicher Zusammenhang sichtbar |
| Compound-Konfiguration | Mittel, einmalig | Synchrone Zeitleiste beider Prozesse | Hoeherer IDE-Overhead |
| Korrelierte Logs | Gering, dauerhaft | Nachtraegliche Analyse ohne Live-Session | Kein interaktives Stepping |
| Manueller Fensterwechsel | Keins | Kein zusaetzliches Setup | Zeitfenster leicht verpasst |
Mironsoft
PhpStorm-Setup, Docker-Integration und Team-Produktivität
PhpStorm, das für Magento- und PHP-Projekte wirklich optimal läuft?
Wir prüfen bestehende PhpStorm-Setups auf langsame Indizierung, ungenutzte Docker-Integration und fehlende Team-Konventionen und richten eine Konfiguration ein, die von der ersten Sekunde an produktiv ist.
Setup-Review
Indexing, Interpreter und Speicher-Einstellungen für große Magento-Projekte optimieren.
Docker-Integration
Xdebug, PHPUnit und Datenbank-Tools sauber mit dem Docker-Setup verbinden.
Team-Konventionen
Inspection-Profile, Code-Style und Live-Templates projektweit vereinheitlichen.
10. Zusammenfassung
Full-Stack-Debugging in PhpStorm: Das Wichtigste auf einen Blick
Kernwerkzeug
Compound Run/Debug Configuration verbindet PHP Remote Debug und Attach to Node.js/Chrome.
Voraussetzung
Xdebug mit korrektem client_host und Node-Prozess mit --inspect-Flag.
Typischer Fall
Bugs an der Schnittstelle zwischen PHP-Rendering und Tailwind-Watcher-Build.
Grenze
Fuer einfache Bugs bleibt eine einzelne Session schneller aufgesetzt.