Webentwicklung, viel JavaScript. Da benötigt man recht bald eine saubere Validierung. JSLint von Douglas Crockford hat sich hier durchgesetzt und wird weitläufig verwendet. Es gibt zahlreiche Add-Ins für Visual Studio, Web-Validatoren usw. Meine Anforderung bestand nun darin, alle JavaScripts einer Solution bei einem Build zu validieren und gefundene Fehler in der Error-Liste zu haben. Zusätzlich sollte dies ohne Installation in einer Team-Umgebung funktionieren, wodurch sämtliche Add-Ins nicht von Relevanz sind. Dieser Beitrag zeigt, wie dieser Task innerhalb einiger Minuten erledigt werden kann.
Voraussetzungen
Wie der Titel schon besagt, werden sowohl Node.js, als auch JSLint benutzt. In meinem Fall kommt Node.js für Windows zum Zuge. Dieses wird als MSI-Paket ausgeliefert und kann direkt installiert werden. Damit nun aber nicht jedes Team-Mitglied dieses ebenfalls zu installieren hat, empfiehlt es sich, alles aus
%ProgramFiles(x86)%\nodejs
in ein Verzeichnis, welches im Source Control liegt, zu kopieren. Dazu sollte entsprechend auch die Struktur vorhanden sein. Hier meine Struktur als Beispiel:
Kurze Erklärung, soweit nicht selbstsprechend: 3rdPartyLibraries beinhält alles von externen Anbietern (Node.js wäre in diesem Fall so jemand), Build alle Dateien, die für das Build (sowohl Client als auch Server) notwendig sind. Unter Sources ist die tatsächliche Solution zu finden.
In meinem Falle würde also Node.js für Windows in ein Unterverzeichnis von 3rdPartyLibraries kopiert werden. In Node.js inkludiert ist der Package-Manager npm. Darüber muss nun JSLint installiert werden:
npm install jslint
Damit ist das Modul vorhanden und kann adaptiert bzw. verwendet werden.
Hinweis: Es stehen weitere Module zur Verfügung, in unterschiedlichen Ausprägungen, teilweise angepasst an das gewünschte Verhalten des jeweiligen Entwicklers. Hier muss man mitunter ein wenig experimentieren, um herauszufinden, welches Modul die eigenen Anforderungen am besten abdeckt.
Wenn nun auch noch PowerShell zur Verfügung steht, sind alle Grundvoraussetzungen erfüllt.
Anpassungen für Visual Studio
Eine der Anforderungen für mich ist die Anzeige der gefundenen Fehler in der Error-Liste von Visual Studio, schließlich möchte ich diese auf einen Blick sehen. Im normalen Output-Fenster (der Build-Ergebnisse) würden diese mitunter untergehen bzw. nicht berücksichtigt werden. Dafür muss eine kleine Änderung im installierten Modul vorgenommen werden. Die Datei reporter.js für vom jslint-Modul für die Ausgabe der Fehler verwendet. Damit die Ausgabe jedoch von Visual Studio erkannt und in die Error-Liste eingetragen wird, muss diese speziell formatiert werden. Nachfolgend meine aktualisierte Variante.
/*jslint forin: true */
var color = require("./color");
var log = console.log;
exports.report = function (file, lint, colorize) {
'use strict';
var options = [], key, value, line,
i, len, pad, e, fileMessage;
for (key in lint.options) {
value = lint.options[key];
options.push(key + ": " + value);
}
fileMessage = "\n" + ((colorize) ? color.bold(file) : file);
if (!lint.ok) {
len = lint.errors.length;
for (i = 0; i < len; i += 1) {
e = lint.errors[i];
if (e) {
log(file + '(' + e.line + ',' + e.character + '): warning: ' + e.reason);
}
}
} else {
log(fileMessage + " is " + ((colorize) ? color.green('OK') : 'OK') + ".");
}
return lint.ok;
};
Von spezieller Bedeutung ist diese Zeile:
log(file + ‘(‘ + e.line + ‘,’ + e.character + ‘): warning: ‘ + e.reason);
Hier wird die Ausgabe genau so formiert, dass Visual Studio die Meldung als Warning erkennt und in der Error-Liste zur Anzeige bringt. Zusätzlich wurden einige Zeilen entfernt, die für diesen Anwendungsfall nicht benötigt werden. Bei einer Aktualisierung des Modules ist jedoch darauf zu achten, dass die Änderungen wieder nachgezogen werden.
Tipp: Wer die JSLint-Meldungen lieber als tatsächlichen Fehler erhalten möchte, muss lediglich warning gegen error tauschen.
Nun fehlt noch die Einbindung ins Build.
Einbindung Build
Auch diese Aufgabe lässt sich einfach bewältigen. Im einfachsten Fall wird ein kleines Powershell-Script geschrieben, welches ins Pre-build Event des Hauptprojektes eingebunden wird. Das Script kann in etwa so aussehen:
$node_js_path = ($args[0]).Trim()
$js_files_path = ($args[1]).Trim()
$jslintmodule = "$node_win_dir" + "\node_modules\jslint\bin\jslint.js"
$js_files = get-childitem $js_files_path -include *.js -recurse -force
Set-Location $node_win_dir
foreach ($file in $js_files)
{
.\node.exe $jslintmodule "--sloppy" "--white" "--undef" $file
}
popd
Das Script enthält zwei Parameter. Der erste Parameter legt fest, wo sich Node befindet, der zweite Parameter beschreibt, in welchem Pfad sämtliche JavaScripts zu finden sind. Das PowerShell-Script durchsucht diesen Pfad rekursiv und übergibt alle Files an Node unter Aufruf des entsprechenden Moduls.
Fertig. Natürlich ist dieser Schritt an die Gegebenheiten der jeweiligen Umgebung anzupassen und stellt daher nur die Minimalumsetzung dar.
Fazit
Mit ein paar wenigen Handgriffen lässt sich JSLint mit Hilfe von Node.js und einen Schuss Powershell ins Visual Studio Client-Build einbinden. Läuft dies über ein Source Control funktioniert diese Variante für alle Team-Mitglieder ohne Installation und Konfiguration. Zusätzlich finden sich alle Meldungen übersichtlich in der Error-Liste von Visual Studio und sind dadurch mit Sprungmarken versehen, um direkt an die jeweilige Stelle springen zu können.