Grunt: Lästige Webworker-Aufgaben automatisieren
Was ist Grunt?
Wie viele Webworker bist auch du bestimmt schon mal an dem Punkt gewesen, an dem du merkst, dass du stumpfsinnige Arbeiten immer und immer wieder wiederholen musst. „Das ist eigentlich Arbeit, die eine Maschine erledigen sollte“, wirst du dir denken, spätestens wenn du beim zehnten Debug-Versuch deine LESS-Dateien kompilieren oder mehrere JavaScript-Dateien in einer zusammenfassen und minifien musst.
Grunt ist eines der Tools, die dir helfen, diese Probleme anzugehen. Grunt ist ein so genannter „Task Runner“. Das Tool basiert auf Node.js und kann mit entsprechenden Modulen so ziemlich alles machen, was ein Webworker braucht und im Alleingang ziemlich viel Zeit kostet: Minifizierung, Kompilierung und vieles mehr wird mit der Eingabe von nur einer Codezeile in Sekundenschnelle durchgeführt. Für Grunt stehen Plugins zur Verarbeitung von CoffeScript, Handlebars, Jade, LESS, Sass und vielen anderen Aufgaben zur Verfügung.
Wir schauen uns in diesem Beispiel an, wie wir Grunt installieren und unseren ersten Job – das Zusammenfügen von mehreren LESS-Dateien zu einer kompilierten und minifizierten CSS-Datei – realisieren können.
Grunt Installieren
Um Grunt benutzen zu können, brauchen wir erst mal Node.js. Auf der offiziellen Webseite von Node.js kannst du das nötige Installationspaket runterladen. Der Installationsassistent führt dich durch alle nötigen Schritte, wir springen an dieser Stelle also direkt zur Installation von Grunt. Um den Grunt Client global auf deinem System verfügbar zu machen, musst du nur noch folgenden Befehl in die Kommandozeile deines Macs oder Windows PC eingeben:
npm install -g grunt-cli
Es ist möglich, dass du dich für die Installation als Administrator authentifizieren musst. Gib dafür sudo (OSX, *nix, BSD) vor die Kommandozeile ein oder logge dich als Administrator (Windows) ein. Jetzt kannst du mehrere Instanzen von Grunt für deine jeweiligen Projekte installieren und durchlaufen lassen.
Grunt konfigurieren
Um Grunt für dein Projekt einzurichten benötigst du zwei Dateien. Die package.json und die gruntfile.js. Die package.json enthält alle Informationen zu deinem Projekt. Wichtige Pfade, Versionsinfos und eine Liste der Node-Module, die für die Automatisierung mit Grunt benötigt werden.
package.json
In diesem Beispiel wollen wir mehrere LESS-Dateien zu einer einzigen CSS-Datei zusammenfügen und diese minifizieren. Die package.json im Hauptordner unseres Projektes könnte also folgendermaßen aussehen:
{"src_folder": "devel",
"build_folder":"build",
"target_folder":"dist",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-concat": "~0.1.3",
"grunt-contrib-cssmin": "~0.5.0",
"grunt-contrib-less":"~0.5.0"
}
}
In diesem Beispiel setzen wir uns einige Variablen: den Quellordner (devel), in dem unsere LESS-Dateien liegen werden, den Build-Ordner (build), in dem wir Zwischenergebnisse erzeugen werden und den Zielordner (dist), in dem wir im Anschluss das kompilierte Ergebnis finden. Für die Verarbeitung benötigen wir Grunt, die Grunt Contribution Concat (grunt-contrib-concat), um mehrere Dateien zusammenzufügen, Grunt Contribution Less (grunt-contrib-less), um LESS-Dateien zu parsen und Grunt Contribution Cssmin (grunt-contrib-cssmin), um das Endergebnis minifizieren zu können.
gruntfile.js
Die gruntfile.js beinhaltet die Anweisungen und Informationen, die Grunt für das Verarbeiten deines Projekts benötigt. Die gruntfile im Hauptordner unseres Projektes unterteilt sich in mehrere Abschnitte. Die Wrapper-Funktion beinhaltet alle Aufrufe für Grunt und Grunt-Plugins. Alles, was Grunt mit deinen Dateien anstellen soll, muss in diese Funktion rein.
module.exports = function(grunt) { // Do grunt-related things in here };
Viele Aufgaben beziehen sich auf Werte, die in der package.json definiert werden. Deswegen sollte man die Werte der Datei direkt beim Start von Grunt importieren.
grunt.initConfig({
grunt.file.readJSON('package.json');
});
Als nächstes können die einzelnen Module konfiguriert werden. Jedes Modul hat seine Eigenarten, was die Konfiguration angeht. In unserem Fall genügt es das Modul zu definieren, eine Aufgabe zu erstellen und Quell- und Zieldateien zu definieren. Die Aufgabe zum Zusammenführen von zwei LESS-Dateien würde zum Beispiel so aussehen:
concat: {
css: {
src: [
'<%= pkg.src_folder %>/stylesheet1.less',
'<%= pkg.src_folder %>/stylesheet2.less'],
dest: '<%= pkg.build_folder %>/master.less'
}
}
Mit dem Platzhalter <%= pkg.src_folder %> greifen wir auf den jeweiligen Wert aus der package.json zu und weisen das Programm an, stylesheet1.less und stylesheet2.less zu einem einzigen Stylesheet master.less in unserem Buildfolder zusammenzuführen. Die Einstellungen für das LESS-Modul und das CSSMIN-Modul funktionieren ähnlich.
less: {
main_style: {
src:"<%= concat.css.dest %>",
dest:"<%= pkg.target_folder %>/master.css"
}
}
Wir greifen auf das Zielobjekt des Concat-Moduls zu und kompilieren die LESS-Informationen in klassisches CSS. Das Ergebnis speichern wir im Zielordner als master.css.
cssmin: {
master: {
src:"<%= less.main_style.dest %>",
dest:"<%= pkg.target_folder %>/master.min.css"
}
}
Das CSSmin-Modul wird angewiesen die Zieldatei des LESS-Moduls einzulesen, zu minifizieren und anschließend als master.min.css im Zielordner zu speichern. Jetzt haben wir es fast geschafft und müssen nur noch die benötigten Module und Aufgaben registrieren.
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['concat','less','cssmin']);
Mit diesen Zeilen stellen wir sicher, dass alle Module für die Verarbeitung geladen werden und beim Ausführen von Grunt in der Konsole standardmäßig die Module Concat, LESS und CSSMIN aufgerufen werden. Zugegeben: Die Konfiguration von Grunt nimmt einige Zeit in Anspruch. Du musst selbst entscheiden, ob sich die Einrichtung für das jeweilige Projekt rentiert – in den meisten Fällen dürfte sich die Arbeit aber lohnen.
Grunt starten
Der schwierigste Part ist überstanden. Jetzt müssten alle Automatismen eingerichtet sein und Grunt mit nur einem Kommandozeilenaufruf alles erledigen, was in der Gruntfile vorgegeben wurde. Um Grunt zu starten, musst du mit dem Kommandozeilentool deiner Wahl in den Hauptordner des Projektes navigieren und folgenden Befehl ausführen.
grunt
Dein erstes Grunt-Projekt
Grunt mag auf den ersten Blick kompliziert klingen – Kommandozeile ist oft ein K.o.-Kriterium für den Einsatz vieler Tools. Bei Grunt sollte man aber definitiv eine Ausnahme machen. Nicht nur ist die Bedienung des Tools mit Hilfe der Konfigurationsdateien vergleichsweise einfach. Auch die potentielle Verbesserung des Workflows, die mit der Nutzung von Grunt einhergeht, ist ein Faktor der definitiv mit berücksichtigt werden sollte. Weitere Infos zu Grunt erhältst du auf der offiziellen Webseite von Grunt. Für einen einfacheren Einstieg, kannst du dir die Projektdaten zu diesem Grunt-Beispiel downloaden.
Hey, wirklich klasse Artikel. Ich würde das ganze noch um folgenden Link ergänzen: http://yeoman.io/
Das ist quasi die „All-in-One“-Lösung :-)
Grüße
Andreas Becker
„`
npm install-g grunt-cli
„`
Da fehlt ein leerzeichen!
Vielen Dank! Haben wir korrigiert.
meine Top Grunt-Module:
======================
grunt-contrib-clean
grunt-coffeelint
grunt-contrib-jshint
grunt-concat-css
grunt-contrib-coffee
grunt-contrib-concat
grunt-contrib-cssmin
grunt-contrib-jasmine
grunt-contrib-less
grunt-contrib-requirejs
grunt-contrib-uglify
grunt-contrib-watch
Ich finde, das ist ein tolles Tool. Ab heute habe ich es im Einsatz. Hab das Beispiel des Autors für mein Projekt übernommen.
Vielen Dank für das Beispiel!
Die Komprimierung der CSS- und JavaScript-Dateien funktioniert wunderbar. Um JavaScript zu komprimieren, habe ich das Beispiel des Autors um diesen Schnipsel erweitert: https://github.com/gruntjs/grunt-contrib-uglify#no-mangling und die uglify-Komponente analog zu anderen grunt-contrib-xxx eingefügt.
Eine Kleinigkeit fehlt aber: in jedem Projekt muss ich diesen Shell-Script ausführen, um grunt lokal im Projekt-Verzeichnis zu installieren:
npm install grunt –save-dev;
npm install grunt-contrib-uglify;
npm install grunt-contrib-less;
npm install grunt-contrib-concat;
npm install grunt-contrib-cssmin;
Hat es jemand von euch hinbekommen, grunt aus der globalen Installation aus (sprich das aus dem Verzeichnis /usr/lib/node_modules in Linux) grunt zu verwenden?
Hi, einfache Erklärung, mir fehlen aber noch einige Praxisbeispiele. wo finde ich welche?
Grüße
K. J.