Feldnotizen


6 Min. Lesezeit

Von Air zu Watchexec

Wie ich zu einem besseren File Watcher kam

Als Entwickler sind wir Gewohnheitstiere. Wir finden Werkzeuge, die funktionieren, und bleiben bei ihnen, manchmal weit über ihr Ablaufdatum hinaus. Jahrelang habe ich beim Hot Reloading auf Air für Go geschworen. Es war einfach, es funktionierte (meistens), und meine Go-Projekte liefen damit rund. Aber wie in vielen langen Beziehungen wurde aus Bequemlichkeit irgendwann ein Kompromiss.

Der Wendepunkt kam, als ich mehr mit Projekten aus mehreren Modulen und gemeinsamen Bibliotheken arbeitete. Plötzlich waren die Grenzen von Air keine kleinen Ärgernisse mehr, sie haben meine Produktivität aufgefressen.

Die Air, die wir geatmet haben

Versteh mich nicht falsch: Für Go-Projekte in einem einzigen Verzeichnis hat Air seinen Zweck gut erfüllt. Die Einrichtung war einfach: Konfigurationsdatei hinlegen, air starten, und jede Codeänderung löst automatisch einen Rebuild und Neustart aus. Für den typischen Webservice oder die typische CLI-Anwendung in einem Modul war das perfekt.

Moderne Entwicklung ist aber nicht immer so einfach. Heutige Projekte erstrecken sich oft über mehrere Verzeichnisse, enthalten gemeinsame Bibliotheken und verlangen, dass man verschiedene Dateitypen an verschiedenen Orten beobachtet. Genau hier zeigte Air sein Alter.

Am meisten frustriert hat mich, wie schwer sich Air mit mehreren Verzeichnissen tut. Wenn du eine Bibliothek entwickelst, die von mehreren Services genutzt wird, oder in einem Monorepo arbeitest, muss dein File Watcher Änderungen an verschiedenen Pfaden mitbekommen. Air löste das umständlich und unzuverlässig. Manchmal lösten Änderungen keinen Rebuild aus, ein andermal sorgten Fehlalarme für unnötige Neustarts.

Ich habe mehr Zeit damit verbracht, meine Entwicklungsumgebung zu debuggen, als tatsächlich zu entwickeln.

Watchexec: die Alternative in Rust

Der Wechsel zu watchexec kam nicht sofort, und ich gebe zu, er hat ein bisschen wehgetan. Da war ich, ein Go-Fan, und liess ein Go-Werkzeug für etwas in Rust fallen. Es fühlte sich wie Verrat an, aber manchmal muss man den Stolz für die Produktivität herunterschlucken.

Watchexec ist ein allgemeiner Befehlsausführer, der beliebige Befehle startet, wenn sich Dateien ändern. Das klingt simpel, aber genau diese Einfachheit macht es stark.

Was watchexec besonders macht

Das Erste, was an watchexec auffällt, ist seine Flexibilität. Es macht keine Vorgaben dazu, was du baust oder wie. Es fragt nur: «Welchen Befehl soll ich ausführen, wenn sich Dateien ändern?» Dank dieses allgemeinen Ansatzes kannst du es für Go-Projekte, Node.js-Anwendungen, Python-Skripte oder alles andere nutzen, das von automatischem Neukompilieren oder Neustarten profitiert.

Richtig gut wird es, wenn du die Konfigurationsmöglichkeiten erkundest. Watchexec kommt elegant mit mehreren Verzeichnissen zurecht. Du kannst mehrere Pfade angeben, Glob-Muster verwenden und sogar bestimmte Dateien oder Verzeichnisse mit einer verständlichen Syntax ausschliessen. Was in Air komplizierte Konfigurationsakrobatik war, sind bei watchexec einfache Kommandozeilenargumente.

Der Unterschied in der Performance fällt sofort auf. Watchexec reagiert schneller und zuverlässiger auf Dateisystem-Events. Änderungen werden rasch und genau erkannt, ohne die gelegentlich verpassten Updates, die mein Air-Setup geplagt haben. Das Rust-Fundament merkt man: Das Werkzeug fühlt sich solide und reaktionsschnell an, auch wenn es grosse Verzeichnisbäume beobachtet.

Besonders beeindruckt hat mich, wie geschickt watchexec mit verschiedenen Dateitypen umgeht. Du kannst je nach Dateiendung unterschiedliche Befehle konfigurieren oder komplexe Filterregeln aufstellen, die mit Air ein Albtraum gewesen wären. Du willst deinen Go-Service neu starten, wenn sich .go-Dateien ändern, aber das Frontend nur neu bauen, wenn sich .js- oder .css-Dateien ändern? Mit watchexec geht das ganz natürlich.

Erste Schritte mit watchexec

Die Installation ist auf allen Plattformen einfach. Auf macOS mit Homebrew:

brew install watchexec

Auf Linux nimmst du den Paketmanager deiner Distribution oder ein fertiges Binary von der Releases-Seite auf GitHub. Unter Windows geht es mit Scoop oder Chocolatey:

# Mit Scoop
scoop install watchexec

# Mit Chocolatey
choco install watchexec

Wenn Rust installiert ist, kannst du es auch direkt von crates.io installieren:

cargo install watchexec-cli

Praktische Beispiele für Go

Schauen wir uns ein paar Anwendungsfälle aus der Praxis an, die zeigen, wo watchexec bei Go-Projekten stark ist.

Für eine einfache Go-Webanwendung ersetzt du den Air-Befehl durch:

watchexec -r -e go -- go run ./cmd/server

Das Flag -r sorgt dafür, dass der vorherige Prozess beendet wird, bevor ein neuer startet, und -e go beschränkt die Beobachtung auf Go-Dateien.

Für ein komplexeres Setup, bei dem du mehrere Verzeichnisse beobachten willst (zum Beispiel wegen gemeinsamer Bibliotheken oder Konfigurationsdateien):

watchexec -w src/ -w internal/ -w config/ -e go,yaml,json --restart -- go run ./cmd/server

Das beobachtet die Verzeichnisse src/, internal/ und config/ auf Änderungen an Go-, YAML- und JSON-Dateien.

Wenn dein Go-Modul generierten Code enthält, willst du vielleicht bestimmte Verzeichnisse ausschliessen:

watchexec -w . -i '*_test.go' -i '*/vendor/*' -i '*/node_modules/*' -e go --restart -- go run ./cmd/server

Das Flag -i ignoriert bestimmte Muster, hier Testdateien und Vendor-Verzeichnisse.

Für Projekte, die vor dem Start gebaut werden müssen, kannst du Befehle verketten:

watchexec -e go --restart -- sh -c 'go build ./cmd/server && ./server'

Oder, wenn du die Build-Ausgabe lieber deutlicher siehst:

watchexec -e go --restart -- sh -c 'echo "Building..." && go build -o ./tmp/server ./cmd/server && echo "Starting server..." && ./tmp/server'

Wie die Migration lief

Die Migration von Air zu watchexec ging überraschend glatt. Statt meine .air.toml durch eine andere komplizierte Konfigurationsdatei zu ersetzen, nutzte ich plötzlich einfache Shell-Befehle, die leichter zu verstehen und zu ändern waren.

Die Lernkurve war flach. Die Kommandozeile ist intuitiv und die Dokumentation ausgezeichnet. Nach einem Tag hatte ich alle meine Entwicklungsabläufe umgestellt und merkte die Vorteile schon.

Mehr als Technik: ein anderes Denken

Am meisten hat mich an diesem Wechsel nicht die technische Verbesserung beeindruckt, sondern das andere Denken. Der allgemeine Ansatz von watchexec hat meinen Blick auf Entwicklungswerkzeuge verändert. Statt nach sprachspezifischen Lösungen zu suchen, schaue ich jetzt nach flexibleren, kombinierbaren Werkzeugen, die sich an verschiedene Abläufe anpassen.

Diese Haltung geht über File Watching hinaus. Die besten Entwicklungswerkzeuge sind oft die, die eine Sache aussergewöhnlich gut machen und sich nahtlos mit anderen Werkzeugen verbinden, statt umfassende Lösungen für bestimmte Sprachen oder Frameworks sein zu wollen.

Lohnt sich der Wechsel?

Wenn du Air nutzt und es für deine Zwecke perfekt funktioniert, gibt es keinen dringenden Grund zu wechseln. Bist du aber auf eine der Grenzen gestossen, die ich beschrieben habe, besonders bei mehreren Verzeichnissen oder komplexen Projektstrukturen, dann lohnt es sich unbedingt, watchexec anzuschauen.

Die Installation ist einfach (es ist in den meisten Paketmanagern verfügbar), die Migration ist risikoarm (du kannst jederzeit zurückwechseln), und der mögliche Gewinn an Produktivität ist gross. Selbst wenn du mit deinem jetzigen Setup keine Probleme hast, könnten dich die bessere Performance und die Flexibilität überraschen.

Zum Schluss

Werkzeuge entwickeln sich weiter, und unsere Bereitschaft, mitzugehen, sollte das auch. Manchmal kommen die besten Lösungen von unerwarteter Seite, in diesem Fall ein allgemeiner File Watcher in Rust, der sich für Go-Entwicklung als besser erweist als ein Go-spezifisches Werkzeug.

Der Wechsel von Air zu watchexec hat mir gezeigt, dass Treue zu einer Sprache zwar ehrenwert ist, aber den praktischen Nutzen nicht übertrumpfen sollte. Das beste Werkzeug für die Aufgabe ist nicht immer das in deiner Lieblingssprache, und das ist völlig in Ordnung.

Wenn du über einen ähnlichen Wechsel nachdenkst, ist mein Rat einfach: Probier watchexec an einem kleinen Projekt aus. Ein neues Werkzeug zu lernen kostet wenig, aber die bessere Entwicklungserfahrung kann sich deutlich auszahlen. Manchmal ist das Produktivste, was du tun kannst, deine Komfortzone zu verlassen, auch wenn das heisst, ein bisschen Rust in deine Go-Welt zu lassen.

Mehr in Feldnotizen

Teilen