labuero

< frontend developer >

Grunt.js für Frontend Entwickler. Der einfache Einstieg.

Heutzutage jonglieren wir in unseren Webseiten mit etlichen CSS-Dateien, riesigen Javascripten und diversen jQuery Plugins umher. Für den Livebetrieb ist natürlich alles schön zusammengefasst, um möglichst wenige Requests an den Server zu senden. Und natürlich wird alles minifziert, um Kilobytes zu sparen. Und nach der dritten kleinen Anpassungen hat man keine Lust mehr, all diese Schritte von Hand zu machen. Hier kommt ein Build System ins Spiel, mit dem wir das alles, und sogar noch viel mehr, automatisieren können.

Für Frontend-Entwickler eignet sich meiner Meinung nach am besten grunt.js. Es basiert auf Javascript, weswegen die Einstiegshürde relativ gering ist, und wird von node.js angetrieben. Ich möchte in einem kleinen Tutorial zeigen, wie einfach es ist, grunt schon bei kleineren Projekten mit nur wenig Javscript und CSS zu verwenden. Wer nicht abtippen möchte, das beschriebene Projekt gibt es ganz am Ende auch als Download.

Grunt ist mittlerweile in einer neuen Version erschienen, womit dieses Tutorial in Teilen veraltet ist.
Hier gibt es ein neues Tutorial für die aktuelle Version.

 

Installation:

Als erstes benötigen wir node.js welches es als Installationsdatei zum Download sowohl für Windows und Mac gibt. http://nodejs.org/download/
Nach der Installation haben wir mit node nichts weiter zu tun. Es tut nun still seinen Dienst im Hintergrund.

Als zweites Installieren wir grunt.js. Diesmal nicht per Installer sondern, deutlich cooler, über die Konsole! Also, Konsole auf und folgendes rein:

npm install -g grunt

npm steht dabei für Node Packaged Modules, ein globales Archiv in dem alle node Module gehostet werden. Das -g steht für eine globale Installation, damit grunt nicht für jedes Projekt neu installiert werden muss, sondern Systemübergreifend zu Verfügung steht.

Nachdem nun viele Informationen über die Konsole geflimmert sind, ist die Installation auch schon abgeschlossen.

Projekt einrichten

Herzstück ist die grunt.js Datei im Hauptverzeichnis unseres Projekts. Eine Javascript Datei in der alle auszuführenden Schritte, also Tasks, konfiguriert werden.

Da grunt in erster Linie für Javscript Projekte entwickelt wurde, ist die Standard grunt Datei für einfache Frontend Projekte etwas überladen. Javascript Entwickler mögen mir das verzeihen.
Der typische Weg wäre eigentlich, sich per Konsolenbefehl grunt init:gruntfile eine Datei erzeugen zu lassen. :gruntfile steht dabei für das Template, welches verwendet werden soll. Daneben gibt es noch Templates für jQuery Plugins, node Module und commonjs.

Ich bin allerdings dazu übergegangen, mir meine eigene grunt Datei zu erstellen oder diese einfach aus alten Projekten zu kopieren und lediglich ein paar Anpassungen zu machen.

Als Ausgangsbasis soll diese grunt Datei dienen:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    concat: {
      dist: {
        src: 'src/js/*.js',
        dest: 'js/main.js'
      }
    },
    min: {
      dist: {
        src: ['<config:concat.dist.dest>'],
        dest: 'js/main.min.js'
      }
    }
});

  // Default task.
  grunt.registerTask('default', 'concat min');

};

Aufbau der grunt Datei

Das Javascript Objekt grunt.initConfig beinhaltet die Konfiguration der einzelnen Tasks.
In der Ausgangsversion haben wir lediglich concat: welche Dateien zusammenführt und min: womit Javascript Dateien, nun ja, minifiziert werden.
Im Unterobjekt src: wird die Quelldatei angegeben und in dest: das Ziel.

concat: {
      dist: {
        src: 'src/js/*.js',
        dest: 'js/main.js'
      }
    },

Wie man sieht, kann man auch mit Wildcards arbeiten. In diesem Fall werden alle Dateien mit der Endung .js aus dem Ordner src/js/ genommen und als js/main.js gespeichert.

Im Falle des min Task machen wir es uns sogar noch etwas einfacher und nutzen ein paar Funktionen von grunt, mit der wir automatisch aus einem anderen Task Informationen abgreifen können. Dabei ist config:concat.dist.dest der Pfad innerhalb des initConfig Objekts.

min: {
      dist: {
        src: ['<config:concat.dist.dest>'],
        dest: 'js/main.min.js'
      }
    }

Ganz am Ende werden die Tasks im grunt default Prozess registriert, die später in der angegebenen Reihenfolge ausgeführt werden.

    grunt.registerTask('default', 'concat min');

Dabei ist es nicht notwendig alle konfigurierten Task auch zu nutzen. Auch kann man verschiedene Prozesse anlegen. Beispielsweise einen develop und einen deploy Prozess.

Starten von grunt

Nun sind wir wieder in unserer Konsole und müssen uns spätestens jetzt zu unserem Projektverzeichnis tippen. Dort angekommen rufen wir den default Task auf, in dem wir einfach den Befehl grunt aufrufen. Als Windows Nutzer bitte grunt.cmd, da sonst lediglich die Datei aufgerufen wird und nicht der Prozess gestartet.

Es passiert das, was wir oben beschrieben haben. Alle Dateien mit der Endung .js werden zusammengefasst, als main.js gespeichert, danach minifiziert und als main.min.js abgelegt. Fertig.

Grunt.js in der Konsole

grunt für CSS erweitern

In der Basisversion verwendet grunt zum minifizieren UglifyJS, welches aber mit CSS nicht umgehen kann. Das nachrüsten stellt aber kein Problem dar. Mittlerweile gibt es eine Vielzahl an nützlichen Erweiterungen, die man alle auf http://gruntjs.com findet. Um auch CSS Datein minifizieren zu können, nutzen wir folgendes Modul: https://npmjs.org/package/grunt-css

Die Installation erfolgt auch hier über die Konsole und Achtung! sie muss direkt in unserem Projekt Ordner erfolgen. Die Installation sieht folgendermaßen aus:

npm install grunt-css

Nach dem Download der Dateien, haben wir einen neuen Ordner in unserem Verzeichnis namens node_modules. Weiteren Plugins landen ebenfalls in diesem Ordner.
Um das Modul nutzen zu können, fügen wir folgende Zeile nach unserem Konfigurationsobjekt hinzu:

grunt.loadNpmTasks('grunt-css');

Zu erst wollen wir natürlich, dass auch unsere CSS Dateien zusammengefasst werden. Das Prinzip dahinter – Dateien auslesen und nacheinander in eine neue Datei schreiben – erfordert keine Unterscheidung von Javscript und CSS. Daher können wir unsere concat Task einfach erweitern.

  concat: {
      jsdist: {
        src: 'src/js/*.js',
        dest: 'js/main.js'
      },
      cssdist: {
        src: 'src/css/*.css',
        dest: 'css/style.css'
      }
    },

Jetzt haben wir zwei Unterobjekte. jsdist für unser Javascript Dateien und cssdist für CSS.

Den min Task müssen wir noch anpassen, damit dieser weiterhin die korrekte js Datei auslesen kann.
Aus ['<config:concat.dist.dest>'] wird ['<config:concat.jsdist.dest>']

 min: {
      dist: {
        src: ['<config:concat.jsdist.dest>'],
        dest: 'js/main.min.js'
      }
    },

Jetzt fügen wir unseren cssmin Task hinzu, welcher fast identisch zum min Task ist. Nur Namen und Pfade anpassen.

 cssmin: {
      dist: {
        src: ['<config:concat.cssdist.dest>'],
        dest: 'css/style.min.css'
      }
    },

Damit cssmin auch aufgerufen wird, muss er jetzt noch in den default Prozess aufgenommen werden

  grunt.registerTask('default', 'concat min cssmin');

Nach dem Start von grunt werden jetzt neben den Javascript Dateien auch alle CSS Dateien zusammengefasst und anschließend minifiziert.
grunt mit js und css task

Was kann grunt noch

Seinen Ursprung hat grunt in der Entwicklung von Javascript Projekten. Deswegen ist zum Beispiel in der Standard Installation Lint und QUnit mit an Board, um Scripte zu validieren und zu testen.
Es ist möglich sich einen Watch Task einzurichten, der Dateien überwacht und bei Änderung vorkonfigurierte Schritte ausführt. Somit spart man sich das händische Starten des grunt Prozesses.
Compass und SASS lassen sich ebenfalls einbinden sowie auf RequireJS basierende Projekte. Sogar einem SVG zu Webfont Konverter oder ein Modul zum zippen von Dateien und Ordnern findet man in der Modulliste. Ach ja, und da alles in Javascript geschrieben wurde, ist man mit entsprechenden Kenntnissen sogar in der Lage, sich seine eigenen Erweiterungen zu schreiben.
Die Tatsache, dass grunt noch in einer sehr frühen Phase der Entwicklung steckt, lässt schon erahnen, dass daraus mal etwas richtig Großes wird!

Hier gibt es das beschriebene Demoprojekt zum runterladen: Gruntdemo

5 Kommentare

  1. Wolfgang Drescher

    Nun sind wir wieder in unserer Konsole und müssen uns spätestens jetzt zu unserem Projektverzeichnis tippen
    … nein muß man nicht: einfach im Explorer oben in der Adresszeile cmd eintippen und ENTER drücken. Voilà …da ist man an Ort und Stelle ohne sich durchhangeln zu müssen. Coole Sache …

  2. akel

    Wow, danke! Ewig hab ich mich um das Thema rumgedrückt und keinen Einstieg gefunden. Aber hiermit gelingt das jetzt 🙂 Will nämlich endlich mal mit Bootstrap arbeiten und nicht die ganzen riesigen Standardscripts verwenden sondern etwas abspecken.

  3. akel

    Die Syntax und alles andere auch hat sich ganz schön verändert.
    1. Alle Module müssen jeweils in den Projektordner installiert werden.
    2. Die Beispieldatei würde jetzt ungefähr so aussehen:
    module.exports = function(grunt) {
    grunt.initConfig({
    concat: {
    dist: {
    src: ['js/src/*.js'],
    dest: 'js/main.js'
    }
    },
    uglify: {
    dist: {
    src: [''],
    dest: 'js/main.min.js'
    }
    }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');

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

  4. Mohi

    Hi zusammen,
    Danke für dies Tutorial. war echt sehr hilfreich!.
    wie binde ich bitte mein Browser in dem Gruntfile ein?
    Danke&Gruß

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.