Gerade im Bereich Cross-Platform und dem neuen Build-System des kommenden TFS 2015 kommt man als Entwickler mittlerweile kaum um Node.js herum. Microsoft bietet als Unterstützung zur Entwicklung die Node Tools für Visual Studio an. Jedoch ist Node.js eine recht junge Technologie und stetig im Wandel. So gab es bis vor kurzem Probleme beim Debugging mit den Node Tools: statt eines Breakpoints wurde die Fehlermeldung “Code not running” angezeigt. Der Fehler wird durch ein externes Modul verursacht. Doch durch die Flexibilität von Node.js war schnell ein Workaround gefunden, ohne das externe Modul verändern zu müssen.
Der Fehler ließ sich zu einem bestimmten Modul zurückverfolgen: graceful-fs (diese Modul ersetzt das native fs-Modul von Node.js für den Dateisystemzugriff). Bis zur Version 3.0.8 führt folgender Code zu dem Fehler:
1: var fs = require("graceful-fs");
2: console.log('Hello world'); // breakpoint is hit
3: fs.mkdir("C:/Test", 511, function (err) {
4: console.log("hello"); // debugging is paused, but "Code not running" message is shown
5: });
Der Breakpoint beim ersten Konsolenaufruf wird normal getroffen. Der Breakpoint beim zweiten Konsolenaufruf wird jedoch nicht. Zwar wird die Ausführung angehalten, doch der Call Stack und Werte der Variablen im Code können nicht angezeigt werden, stattdessen erscheint die Meldung “The current thread is not currently running code or the call stack could not be obtained.”.
Sobald die Ausführung im Callback der “mkdir”-Funktion ankommt, werden alle weiteren Breakpoints nicht mehr korrekt getroffen. Für die Entwicklung ein Desaster, ist doch Debugging ein essentielles Mittel.
Was nun? Die Ursache ist unklar. Ein weiteres Problem ist, dass das Modul graceful-fs selbst gar nicht im Projekt benutzt wurde, sondern es wurde fs-extra (ein weiteres Modul für erweiterte Funktionen mit dem Dateisystem) benutzt, welches widerrum graceful-fs referenziert. Die Referenz zu graceful-fs konnte also nicht einfach aus dem Projekt gestrichen werden.
Schnell fand sich folgender Workaround: Anstatt fs-extra direkt zu verwenden, wird ein Wrapper-Modul erstellt, welches die Referenz zu graceful-fs mit einer Referenz zum nativen Modul “fs” ersetzt, da hier das Problem nicht auftritt. Mit Node.js und dem Modul mockery, welches normalerweise in Unit Tests verwendet wird, ist der Wrapper mit ein paar Zeilen Code erstellt:
1: var mockery = require("mockery");
2: var fs = require("fs");
3: mockery.enable({
4: warnOnReplace: false,
5: warnOnUnregistered: false,
6: useCleanCache: true
7: });
8: mockery.registerMock("graceful-fs", fs);
9: var fixedfsextra = require("fs-extra");
10: mockery.disable();
11: module.exports = fixedfsextra;
Mit dem Aufruf “mockery.registerMock(“graceful-fs”, fs);” in Zeile 8 werden alle zukünftigen Referenzen zum Modul “graceful-fs” durch das native Modul “fs” ersetzt. Also wird im nächsten Schritt einfach das Modul “fs-extra” geladen, welches die ersetzte Referenz benutzt. Dieses Objekt “fixedfsextra” wird wie üblich als Modul exportiert. Grundsätzlich verhält es sich wie das originale Modul “fs-extra” und hat dieselbe API, jedoch ohne die Vorteile von “graceful-fs”. Wird nun im Projekt statt dem originalen “fs-extra” das obige Wrapper-Modul referenziert, so gibt es beim Debugging keinerlei Probleme mehr. Dafür verzichtet man gern auf die Funktionalität von “graceful-fs”. Schließlich war dies nur ein Workaround bis der Fehler in den offiziellen Modulen bzw. den Node Tools behoben wurde. In der aktuellen Version von “fs-extra” und “graceful-fs” wurde der Fehler behoben. Doch auch in der Übergangszeit konnte die Entwicklung mit korrektem Debugging fortgesetzt werden, dank der Flexibilität von Node.js.