Grunt Einstieg

Was ist Grunt?

Grunt ist ein Taskrunner, in Form eines JavaScript Programms. Über das Anlegen einer Datei (Gruntfile.js) können Task definiert werden und anschließend via Console oder IDE ausgeführt werden.

Wozu kann Grunt benutzt werden?

Grunt ist ein universelles Tool, unzählige Plugins erlauben dem kreativen Entwickler eine Vielzahl von nützlichen und unnützlichen Tasks.

Wie wird Grunt installiert?

Installieren lässt sich Grunt über den normalen npm install Befehl:

npm install -g grunt-cli

Ziel der Einführung:

Es soll mittels Grunt ein Http-Server gestartet werden, der bei Änderungen von Web-Dateien im Projekt reagiert und ein livereload in allen anzeigenden Browsern auslöst. Zudem sollen spezifische URL-Requests an einen anderen Server auf Port 8080 weitergeleitet werden.

Erste Schritte im Projekt

1. Anlegen einer package.json Datei und einer Gruntfile.js Datei

package.json
{}

package.json dient npm als Installationsanleitung. So können über npm install alle benötigten in der package.json hinterlegten Module installiert werden.

Gruntfile.js
module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json')
    });

    // Load the plugins
    // Default task(s).
    grunt.registerTask('default', []);

};

2. Das Installieren bzw. Hinzufügen in die package.json Datei von Grunt geht via

//Hinzufügen eines Modules in die package.json
npm install <module> --save-dev

//in diesem Fall für Grunt:
npm install grunt --save-dev

3. Nun kann das eigentliche Konfigurieren beginnen. Zunächst soll ein einfacher HTTP-Server als Task definiert werden, dazu wird das Modul grunt-contrib-connect benutzt.

Dieses lässt sich wie folgt installieren:

npm install grunt-contrib-connect --save-dev

Zudem muss noch das Modul grunt bekannt gegeben werden. Anshcließend definieren wir den ersten Task, dazu erweitern wir die Konfiguration:

module.exports = function(grunt) {
    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        //#Konfiguration des Connect Modules
        connect:{
            server: {} //#server ist ein beliebiger Konfigurationsname
        }
    });

    // Load the plugins
    grunt.loadNpmTasks('grunt-contrib-connect'); //# Diese Zeile läd das Plugin

    // Default task(s).
    grunt.registerTask('default', []);

    grunt.registerTask('servertask', ['connect:server']);
	//# hier wird der neue Task "servertask" definier, welcher den Http-Server startet, diesen jedoch direkt wieder beendet

};

Das connect Plugin startet den Server und beendet diesen jedoch direkt wieder. Um dies zu verhindern, könnte der Parameter keepalive: true eingesetzt werden. Dies werden wir jedoch gleich auf eine andere Weise erledigen

4. Um den Server ein wenig an unsere bedürfnisse anzupassen werden wir den Hostnamen, Port und das Webverzeichnis anpassen:

module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        connect:{
		//# Hier werden die neuen Einstellungen eingetragen
            server: {
                options:{
                    hostname:'localhost',
                    port: 9001,
                    base: 'src/main/webapp/'
                }
            }
        }
    });

    // Load the plugins
    grunt.loadNpmTasks('grunt-contrib-connect');

    // Default task(s).
    grunt.registerTask('default', []);

    grunt.registerTask('servertask', ['connect:server']);

};

5. Nachem nun anhand des Servers gezeigt wurde, wie ein Modul hinzugefügt und eingestellt wird, fügen wir schnell die Plugins grunt-connect-proxy und grunt-connect-watch ein… ..das Ergebnis sieht dann folgend aus [nicht vergessen, dies Plugins werden auch via npm install installiert, siehe Schritt 2:

Fertige Grunt Beispiel Konfiguration
module.exports = function(grunt) {

    // Project configuration.
grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    connect:{
        servertask:{
            options:{
                //Bekannte Servereinstellungen
                hostname:'localhost',
                port: 9001,
                base: 'src/main/webapp/',

                //# Aktiviert das einbinden eines livereload Script
                //# in die ausgelieferten Dateien
                //# (Alternativ kann auch ein Browserplugin
                //# verwendet werden)
                livereload: true,

                //# Benötigter Filter für das Proxy Plugin
                middleware: function (connect, options) {
                    if (!Array.isArray(options.base)) {
                        options.base = [options.base];
                    }

                    // Setup the proxy
                    var middlewares = [require('grunt-connect-proxy/lib/utils').proxyRequest];

                    // Serve static files.
                    options.base.forEach(function(base) {
                        middlewares.push(connect.static(base));
                    });

                    // Make directory browse-able.
                    var directory = options.directory || options.base[options.base.length - 1];
                    middlewares.push(connect.directory(directory));

                    return middlewares;
                }
            },
            //# Konfiguration der Proxies, die passenden URL-Requests
            //# werden durch den Connect-Server geschleift und an
            //# einen Server auf Port 8080 weitergeleitet
            //# (zum Beispiel ein Tomcat)
            proxies: [
                {
                    context: '/api',
                    host: 'localhost',
                    port: 8080
                },
                {
                    context: '/webjars',
                    host: 'localhost',
                    port: 8080
                }
            ]
        }
    },

    //# Modul zur überwachung von Dateien auf dem Filesystem
    watch: {
        //# livereload Trigger: die angegebenen Dateien werden
        //# überwacht und bei einer Änderung wird der Livereload
        //# im Browser getriggert
        default:{
            files: ['**/*.html', '**/*.js', '**/*.css'],
            options: {
                livereload: true
            }
        }
    }

});


    // Load the plugins
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-connect-proxy');
    // Default task(s).
    grunt.registerTask('default', []);

    //# neue Definition des auszuführenden Task
    grunt.registerTask(
	'server',
	['configureProxies:servertask','connect:servertask','watch']
    );

};

Ziel erreicht

Ein angelegtes Web Projekt kann mit einem Grunt Http-Server (+ Livereloading) und Schnittstellen auf einem weiteren Server verwendet werden.

Beispiel Projekt

Das Projekt beinhaltet die gezeigte Beispielkonfiguration für Livereloading in Kombination mit Proxies, um Anfragen auf Webjars an einen Tomcat weiterzuleiten. Zudem kommt als Rest-Schnittstelle eine Spring MVC basierte WebApp zum Einsatz. GruntExample.zip