Coffeescript nur nach Änderung kompilieren

Bash-Build-Script für Node

Mein Build- und Entwicklungshilfe-Script für Node-Projekte kann bereits das Wesentliche: Coffeescript kompilieren, Tests ausführen, einen Server starten und beenden sowie das Dateisystem überwachen, um die anderen Aufgaben nach jedem Speichern automatisch auszuführen. Die schnell geschriebene Build-Task kompilierte bisher jede Coffeescript-Datei, die sie finden konnte. Um nach dem Speichern möglichst schnell Testergebnisse zu erhalten, sollte nur neu gebaut werden, was sich auch geändert hat.

Um dies möglichst einfach zu erreichen, schlage ich ein Source- (z.B. project/src) und ein Zielverzeichnis (z.B. project/build) vor. In src kann man weitere Grobstrukturen wie main und tests festlegen. So fließen meine zuvor definierten Tasks build_project und build_tests zu einem einzigen build zusammen.

Unterschiede erkennen? Rsync!

Um möglichst effizient etablierte Technologien verwenden zu können, werden vor dem Kompilieren alle Quelldateien ins Buildverzeichnis kopiert. Dank dieser Vereinfachung lässt sich Rsync verwenden, welches nur wirklich geänderte Dateien synchronisiert und ihren Pfad ausgibt. Nach dem Sync muss die Liste der Änderungen nur noch nach Coffee-Dateien durchsucht und diese kompiliert werden. Der gesamte Vorgang sieht dann folgendermaßen aus:

build() {
    changes=( "$(rsync -av "$source_directory/" "$build_directory")" )
    for filepath in $changes; do
      if [[ $filepath == *.coffee ]]; then
        $compiler --compile "$build_directory/$filepath"
      fi
    done
}

Einziger Schönheitsfehler: Im Buildverzeichnis liegen auch die Coffeescript-Dateien neben ihren Javascript-Äquivalenten, obwohl sie nicht gebraucht werden. Diese dürfen im Buildprozess nicht entfernt werden, da ihre Löschung den Rsync-Ansatz ad absurdum führt. Während der Entwicklung stören sie auch nicht. Für das produktive Deployment empfiehlt sich jedoch eine zusätzliche Task, die das Buildverzeichnis zuvor bereinigt.

Implementierte Build-Tasks

Das Script ist mittlerweile vollständig genug, um die Node-Entwicklung zu begleiten. Folgende Tasks stehen zur Verfügung:

Task Beschreibung
build Build project and tests.
test Build project and run all tests.
Equivalent to „build.sh build run-tests“.
run-tests Run all tests.
server Stop running server (if existing), build project and start server.
Equivalent to „build.sh stop-server build start-server“.
restart-server Stop running server (if existing) and start server.
Equivalent to „build.sh stop-server start-server“.
start-server Start server.
stop-server Stop running server (if existing).
watch Start infinite loop triggering succeeding tasks whenever a file changes
in project directory. Use only once.
dev Build everything, restart server, run tests and repeat whenever a file
changes. Equivalent to „build.sh test watch test“.

Node-Build-Script auf Github