Zur Übersicht

Grunt.js - und das hat nichts mit Grunzen zu tun.

Erfan Ebrahimnia Aktualisiert am 17. Aug. 2020
GRUNT.JS - UND DAS HAT NICHTS MIT GRUNZEN ZU TUN.

Meine aktuellen Projekte sind sehr frontend-lastig. Grunt.js hilft mir, redundante Aufgaben zu automatisieren und so meinen Workflow zu verbessern. Jedoch hatte ich am Anfang die eine oder andere Schwierigkeit das Konzept hinter Grunt.js zu verstehen. Und genau das ist der Grund, warum ich diesen Step-by-Step Guide schreibe - und hoffentlich manchem unter euch ein paar Stunden Kopfzerbrechen erspare. Also: Packen wir es gemeinsam an!

Basics: Was ist Grunt.js?

Grunt.js ist ein sogenannter Taskrunner, d.h. es übernimmt Aufgaben wie das Kompilieren von SASS und LESS Files in CSS, checkt JavaScript auf Fehler ab und optimiert alle Assets für das Web.

Das Schöne daran ist, dass - bei richtiger Konfiguration - Grunt.js die Daten selbst überwacht und bei Änderungen die oben genannten Tasks automatisch ausführt.

Step I: Getting started - Grunt.js richtig aufsetzen.

Ich könnte meine Lobeshymne über Grunt.js zwar noch über viele Zeilen fortsetzen, doch irgendwann sollte jede Schwärmerei ein Ende haben. Denn schlussendlich zählen doch die Fakten. Und die bekommt ihr jetzt: brühwarm und auf den Punkt gebracht.

Im folgenden Praxisbeispiel werden wir gemeinsam Grunt.js aufsetzen und konfigurieren. Unser Ziel? Das automatische Kompilieren von LESS-Files in einem Projekt - und zwar bei jeder Änderung!

Grunt.js basiert auf dem Framework Node. Ob das Programm bereits auf dem Server installiert wurde, das kann man einfach und schnell über das Terminal feststellen - indem man “node -v” eingibt. Falls eine Fehlermeldung erscheint, ist es nicht der Fall und man muss das Programm von der offiziellen Website herunterladen.

Anschließend können wir mithilfe des Node Package Managers (npm), Grunt.js downloaden und verwenden. Wie auf der Grunt.js Website beschrieben müssen wir die Grunt-CLI global installieren. Das geschieht mit folgendem Befehl im Terminal:

$ npm install -g grunt-cli

Step II: Und Kontrolle ist doch besser.

Ob Grunt richtig installiert wurde, das können wir ganz einfach testen, indem wir über das Terminal in unser Projektverzeichnis navigieren und den Befehl “grunt” eingeben. Nun sollte folgende Nachricht erscheinen:

Fatal error: Unable to find local grunt. If you're seeing this message, either a Gruntfile wasn't found or grunt hasn't been installed locally to your project. For more information about installing and configuring grunt, please see the Getting Started guide: http://gruntjs.com/getting-started

Auch wenn die Nachricht mit “Fatal error” beginnt, dürfen wir uns freuen: Grunt CLI wurde richtig installiert.

Aber: Die Fehlermeldung sagt, dass weder ein sogenanntes “Gruntfile”, noch Grunt selbst lokal als Node.js Modul im Projektverzeichnis gefunden wurde. Das muss nachgeholt werden!

Step II-I: FATAL ERROR. Die Lösung? Node.js

Fangen wir zuerst mit dem Grunt Node Modul an. Der einfachste Weg Node.js Module zu installieren geht über den Package Manager (npm). Dazu müssen wir in unserem Projektverzeichnis ein “package.json” File anlegen und Folgendes einfügen:

{
   "name": "Grunt-Projekt",
   "version": "1.0.0",
   "devDependencies": {
       "grunt": "~0.4.1",
       "grunt-contrib-less": "~0.6.4",
       "grunt-contrib-watch": "~0.4.3"
   }
}

Die erste Eigenschaft ist der Projektname, die zweite ist die Versionsnummer und in “devDependencies” geben wir die Module an, die unser Projekt benötigt. In diesem Fall sind es:

  • ”grunt”
  • “grunt-contrib-less” - welches wir zum Kompilieren der LESS Files benötigen
  • “grunt-contrib-watch” - um unsere LESS Files zu überwachen und bei Änderungen neu zu kompilieren

Wenn das “package.json” angelegt ist, führen wir es mit dem Befehl “npm install” im Projektordner aus. Nun sollte sich in unserem Projekt ein Ordner namens “node_modules” mit den oben angegebenen Modulen befinden.

Step III: Jetzt geht´s zur Sache!

Wenn ihr es bis hier hin geschafft habt: Herzlichen Glückwunsch! Und ich kann euch versprechen, jetzt wird das Ganze auch spannender. Nun fangen wir richtig an! Naja, fast. Grunt.js ist zwar korrekt aufgesetzt und alle benötigten Module sind installiert, doch fehlt uns zum vollendeten Grunt-Glück noch ein allerletzter Task.

Wir erinnern uns an die Fehlermeldung im letzten Schritt. Diese sagte aus, dass wir Grunt lokal im Projektordner als Node.js Modul installieren müssen und wir ein sogenanntes Gruntfile benötigen. Den ersten Punkt haben wir schon erledigt, aber wir haben immernoch kein Gruntfile angelegt. Das muss nun nachgeholt werden um Grunt.js auch für unsere Projekte verwenden zu können.

Das Gruntfile ist einfach eine JavaScript Datei, welche die Konfigurationen für Grunt.js beinhaltet. Zum Beispiel geben wir im Gruntfile an, wo sich unsere LESS Dateien befinden und wohin sie kompiliert werden sollen - oder auch welche Files Grunt.js auf Änderungen überwachen sollte.

TL;DR - für alle mit wenig Leselust Zeit, geht´s hier weiter:

Als Erstes legen wir in unserem Projektordner eine Datei mit dem Namen “Gruntfile.js” an und öffnen die Datei in einem beliebigen Editor. Jedes Gruntfile besitzt eine sogenannte Wrapper­Funktion, welche sowohl die Konfigurationen der einzelnen Module als auch die Tasks, die Grunt ausführen soll, beinhaltet.

module.exports = function (grunt) {
    // Hier geht die Action ab 
};

In dieser Wrapper­Funktion rufen wir die Grunt­Methode “initConfig” auf und übergeben ihr ein JavaScript Objekt mit unseren Konfigurationen.

module.exports = function (grunt) {

    grunt.initConfig({ less: {
        development: { options: {
        paths: ["less/"] },
        files: {
           "css/main.css": "less/main.less"
        } 
    }
}

}); };

Nicht erschrecken, dieser Code hat mehr Angst vor euch als ihr vor ihm. Die Konfiguration und alle vorhandenen Funktionen eines Moduls sind auf der jeweiligen Website meist gut dokumentiert.

In diesem Fall haben wir die Konfiguration des LESS Compilers nach folgender Dokumentation erstellt: In unserem Projektverzeichnis erstellen wir noch einen “LESS” und einen  “CSS” Ordner und fügen im “LESS”-Ordner ein LESS-File mit dem Namen “main.less” hinzu. Darin können wir nun das Styling unserer Website definieren. Als Beispiel lasse ich folgenden Code im LESS-File kompilieren:

@red: ‘#f00’;

body {
    background: @red;
} 

Das LESS­Modul ist nun fertig konfiguriert. Abschließend müssen wir noch einen Task im Gruntfile anlegen, welcher nach unseren Konfigurationen die LESS Dateien kompiliert. Zwar kann man im Gruntfile eigene Tasks anlegen und spezifisch benennen, aber für unser Beispiel nutzen wir den Grunt “default”­Task. Im Task selbst geben wir die Aufgaben, die beim Aufruf ausgeführt werden sollen, als Array an.

module.exports = function (grunt) {

    grunt.loadNpmTasks('grunt­contrib­less');

        grunt.initConfig({
            less: { development: {
            options: {
                paths: ["less/"]
            }, 
            files: {
                "css/main.css": "less/main.less" }
            } 
       }
    });

    // less­compiler Modul wird geladen
    grunt.loadNpmTasks('grunt­contrib­less');

    // Task wird registriert und Aufgaben werden angegeben 
    grunt.registerTask('default', [
        'less' 
    ]);

};

Wenn wir nun im Terminal - wie im ersten Schritt - den Befehl “grunt” eingeben, sollte keine Fehlermeldung mehr erscheinen, sondern Folgendes:

Running "less:development" (less) task File css/main.css created.
Done, without errors.

Wird diese Nachricht angezeigt, habt ihr bisher alles erfolgreich gemeistert. Nun könnt ihr Grunt erfolgreich in euren Projekten einsetzen um LESS Files zu kompilieren.

Tipp: Mit der Zeit kann es etwas nervig werden, dauernd den Befehl zum Kompilieren der LESS Files manuell eingeben zu müssen. Mit Grunt können wir das automatisieren, indem wir das “watch”­Modul einsetzen, welches wir im ersten Schritt heruntergeladen und installiert haben. 

Step IV: Grunt is watching you.

Die Konfigurationen für das “watch”­-Modul sind ebenfalls auf der Github-­Seite gut dokumentiert.

module.exports = function (grunt) {
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.initConfig({
        watch: {
            less: {
                files: ['less/{,*/}*.less'],
                tasks: ['less']
            }
        },
        less: {
            development: {
                options: {
                    paths: ["less/"]
                },
                files: {
                    "css/main.css": "less/main.less"
                }
            }
        }
    });

   // less-compiler Modul wird geladen
    grunt.loadNpmTasks('grunt-contrib-less');
    
   // Task  wird registriert und Aufgaben werden angegeben
    grunt.registerTask('default', [
        'watch'
    ]);
};
Als Erstes laden wir das “watch”-Modul herunter, dann erstellen wir die benötigte Konfiguration:
// ...

watch: {
    less: {
        files: ['less/{,*/}*.less'],
        tasks: ['less']
    }
}

// ...
    

Wir geben an welche Files überwacht werden und welche Aufgabe bei einer Änderung ausgeführt werden soll. Abschließend definieren wir im registrierten “default”­Task, dass anstatt des LESS­Compilers, die “watch”­Aufgabe ausgeführt werden soll - da diese bei Änderungen sowieso den LESS­Compiler aufruft. 

Mein Fazit.

Ich hoffe, ich konnte euch anhand meines Beispiels Grunt.js etwas näher bringen. Doch kann man mit diesem Tool noch viel mehr erreichen:

  • Scaffolding,
  • optimieren von Bildern und anderen Files
  • Aufsetzen eines einfachen Servers

All dies lässt sich mit Grunt.js in kurzer Zeit leicht realisieren und das Schöne ist: 1x konfiguriert, x-beliebig oft verwenden - und zwar bei jedem zukünftigen Projekt. Meinen Workflow hat Grunt.js sehr verbessert und ich möchte es nicht mehr missen.

Alle, die ich nicht überzeugen konnten und noch kein glühender Grunt-Verehrer sind, sollten sich Yeoman ansehen ;).

Mein Link-Tipp:

http://weblog.bocoup.com/introducing-grunt/

-----

Bild- & Textquelle: http://alphahydrae.com/images/contents/gruntjs/logo.png, http://gruntjs.com

Erfan Ebrahimnia
Web Developer