Grunt-lagen, Teil 1

Regelmäßig wiederkehrende Aufgaben von Hand zu erledigen, ist aufwändig und fehleranfällig. Grunt ermöglicht die automatisierte Ausführung dieser Aufgaben. Die Konfiguration von Grunt erfolgt anwendungsspezifisch in der Datei Gruntfile.js.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 5 Min.
Von
  • Golo Roden
Inhaltsverzeichnis

Jeder Entwickler führt gewisse Aufgaben regelmäßig aus. Dies umfasst unter anderem das Ausführen der Codeanalyse und der Unittests, aber auch das Vorbereiten des Deployments. All dies fällt leichter, wenn man die Aufgaben nicht wieder und wieder von Hand ausführen muss: Abgesehen von der Zeitersparnis führt eine automatisierte Ausführung auch zu einer geringeren Fehleranfälligkeit.

Ausgesprochen hilfreich hierfür ist Grunt, ein JavaScript-basierter Taskrunner, der zuvor konfigurierte Aufgaben automatisiert ausführt.

Um Grunt für die Entwicklung einer Anwendung verwenden zu können, muss man zunächst das Modul grunt in den lokalen Kontext dieser Anwendung installieren. Dies erfolgt auf dem üblichen Weg mit Hilfe von npm:

$ npm install grunt

Außerdem empfiehlt es sich, Grunt als eine der devDependencies in der Datei package.json zu hinterlegen, so dass Grunt automatisch installiert wird, wenn ein anderer Entwickler die Anwendung aus der Versionsverwaltung abruft und initialisiert.

Die Installation von Grunt in den lokalen Kontext einer Anwendung weist einen wesentlichen Vor-, aber auch einen essenziellen Nachteil auf:

  • Der Vorteil ist, dass jede Anwendung eine individuelle Version von Grunt verwenden kann.
  • Der Nachteil ist, dass Grunt nicht systemweit als direkt ausführbare Anwendung aufgerufen werden kann.

Eine potenzielle Lösung bestünde in der globalen Installation von Grunt - damit behebt man jedoch nicht nur den Nachteil, sondern verspielt zugleich auch den Vorteil der individuellen Version.

Als Ausweg verwendet Grunt ein zweites Modul, das global installiert wird: grunt-cli. Dessen Aufgabe besteht lediglich darin, die in den lokalen Kontext der Anwendung installierte Version von Grunt zu suchen und diese anschließend zu starten.

$ sudo npm install -g grunt-cli

Auf diesem Weg bleibt der zuvor genannte Vorteil einer individuellen Version pro Anwendung erhalten, zugleich kann Grunt aber auf einfache Art durch Eingabe von

$ grunt

aufgerufen werden. Seit Version 0.4.0 von Grunt wird empfohlen, Grunt an sich niemals global zu installieren, sondern stets auf grunt-cli zurückzugreifen:

"Starting with grunt v0.4, you should never install grunt itself globally."

Bevor Grunt sinnvoll aufgerufen werden kann, muss man es zunächst noch konfigurieren. Hierzu bedarf es einer Datei namens Gruntfile.js, die man dem Wurzelverzeichnis der Anwendung hinzufügt. Ruft man Grunt auf, durchsucht es das aktuelle und bei Bedarf auch alle übergeordneten Verzeichnissen nach dieser Datei.

Die Datei Gruntfile.js weist dabei stets die gleiche Basisstruktur auf:

'use strict';

module.exports = function (grunt) {
grunt.initConfig({
// ...
});

grunt.loadNpmTasks('...');

grunt.registerTask('default', [ '...' ]);
};

Das wichtigste Element dieser Datei ist die exportierte anonyme Funktion, welche die Konfiguration der auszuführenden Aufgaben vornimmt.

Die tatsächliche Ausführung der Aufgaben übernimmt Grunt in der Regel nicht selbst, sondern greift hierbei auf zusätzliche Module zurück. Diese Module werden durch den Aufruf der loadNpmTasks-Funktion importiert. Diese Funktion entspricht daher sinngemäß der require-Funktion von Node.js.

Zu guter letzt ermöglicht Grunt auch die Definition eigener Aufgaben, was mit Hilfe der Funktion registerTask erfolgt. Aufgaben können dabei andere Aufgaben als Abhängigkeiten aufweisen, so dass Grunt zuvor diese ausführen muss.

Um eine Aufgabe auszuführen, muss man deren Namen beim Aufruf von Grunt als Kommandozeilenparameter übergeben. Um also beispielsweise die Aufgabe foo auszuführen, lautet die entsprechende Anweisung:

$ grunt foo

Da man in der Regel einen Standardsatz von Aufgaben ausführen will, ohne diesen bei jedem Aufruf explizit spezifizieren zu müssen, kennt Grunt die Standardaufgabe default. Diese wird aufgerufen, wenn die explizite Angabe einer Aufgabe beim Aufruf entfällt.

Als erste Aufgabe bietet sich das Ausführen von JSHint an, um eine Codeanalyse durchzuführen. Dazu muss man zunächst das Modul grunt-contrib-jshint in den lokalen Kontext der Anwendung installieren:

$ npm install grunt-contrib-jshint

Die Konfiguration dieses Moduls besteht im einfachsten Fall aus der Angabe aller zu analysierenden Dateien und den zu verwendenden Regeln. Alternativ können die Regeln auch in eine dedizierte Konfigurationsdatei für JSHint ausgelagert werden.

Außer der Konfiguration muss Grunt das Modul grunt-contrib-jshint laden und als Bestandteil der default-Aufgabe registrieren:

'use strict';

module.exports = function (grunt) {
grunt.initConfig({
jshint: {
files: [ '**/*.js', '!node_modules/**/*.js' ],
options: {
jshintrc: 'jshint.json'
}
}

});

grunt.loadNpmTasks('grunt-contrib-jshint');

grunt.registerTask('default', [ 'jshint' ]);
};

Wird Grunt nun aufgerufen, werden alle .js-Dateien gemäß den in der Datei jshint.json hinterlegten Regeln analysiert. Dateien, die sich innerhalb des Verzeichnisses node_modules oder einem Unterverzeichnis davon befinden, werden von dieser Analyse jedoch ausgeschlossen.

tl;dr: Regelmäßig wiederkehrende Aufgaben von Hand zu erledigen, ist aufwändig und fehleranfällig. Grunt ermöglicht die automatisierte Ausführung dieser Aufgaben. Die Konfiguration von Grunt erfolgt anwendungsspezifisch in der Datei Gruntfile.js. ()