GRUNT FÜR PROFIS

PROZESSE AUTOMATISIEREN, TEAM-ARBEIT VERBESSERN
GRUNT FÜR PROFIS
Während der Entwicklung einer Web-Applikation fallen in der Regel die immer
gleichen Prozesse an: SASS kompilieren, JavaScript minimieren, Bilder optimieren.
Warum also nicht diese Aufgaben automatisieren? Grunt kann FrontendEntwicklern einiges an Arbeit abnehmen und erleichtert zudem die
Zusammenarbeit im Team. Ein Showcase der Münchner Digitalagentur Format D.
TEXT SABRINA SAUTER
Vermutlich stand jeder Entwickler schon mal vor dem Problem
unterschiedlich strukturierten Codes. Oder musste sich erst in die
Struktur eines Projekts einarbeiten, die jemand anderes angelegt
hat. Grunt schafft Abhilfe: Einer der größten Vorteile des TaskRunners ist die Einheitlichkeit in der Code-Struktur und der Arbeitsweise innerhalb eines Teams. Grunt ermöglicht es einem
Team von Entwicklern, über konfigurierte Tasks Strukturen zu etablieren und diese ohne viel Aufwand einzuhalten. Mit knapp 4.500
Plugins und einer aktiven Community, deren Mitglieder diese in
regelmäßigen Abständen aktualisieren, gibt es für sehr viele Anforderungen bereits die passende Lösung.
Raum für Verbesserungen zulässt. Beim Konfigurieren von
Gruntfile.js fiel beispielsweise auf, dass es durchaus Sinn ergibt,
den Source-Code vom optimierten und aufgeräumten Code zu trennen, der im Produktivsystem letztlich zum Einsatz kommt.
Die Flexibilität der Grunt-Konfiguration lässt das sehr einfach
zu und schafft so einen guten Überblick über die gesamte Applikation, die sich gerade in Entwicklung befindet. Beispielhaft kann
eine Ordnerstruktur für eine Webseite (vereinfacht) so aussehen –
wir gehen für das weitere Vorgehen immer von der hier gezeigten
Struktur aus:
BEISPIEL FÜR ORDNERSTUKTUR
Praktisch: Mit dem Plugin grunt-browser-sync lassen sich die Auswirkung von Codeänderungen auf allen synchronisierten Geräten mit einen Blick kontrollieren.
grunt-webseite/
|
| - public_html/
| | - css/
|
| - main.css // mit Grunt kompliliertes CSS
| | - images/
|
| - ...
// mit Grunt optimierte Bilder
| | - js/
|
| - main.min.js // mit Grunt konkateniert und uglified
| | - index.html
|
| - resources/
| | - images/
| | - js/
|
| - lib/
|
| - jquery-1.11.2.min.js
|
| - main.js
| | - scss/
|
| - _variables.scss
|
| - main.scss
| | - config.rb
// bei Nutzung von compass
| | - Gruntfile.js
| | - package.json
Listing 1
PROJEKT ZUM ARTIKEL
Das gesamte Projekt des Artikels befindet sich unter folgendem Link als ZIP-Archiv:
http://t3n.me/grunt-webseite-t3n40.
PROJEKTSTRUKTURIERUNG MIT GRUNT
Mit der Einführung von Grunt in unsere internen Entwicklungsprozesse haben wir festgestellt, dass unsere Projektstruktur noch
1
Wie zu sehen ist, werden die Dateien, an denen wir aktiv entwickeln, im Ordner „resources“ abgelegt.
Im Folgenden konfigurieren wir Grunt so, dass unsere Dateien
fertig aufbereitet für den Produktiveinsatz im Webroot, in diesem
Fall dem Ordner „public_html“, liegen. Mit dem Paketmanager Homebrew [1] können Mac-OS-Anwender kinderleicht Packages installieren, beispielsweise „wget“ oder „imagemagick“ (welches
später noch zum Einsatz kommt).
© yeebase media 2015. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GmbH. http://t3n.de
INSTALLATION HOMEBREW
COMPASS-EINSTELLUNGEN
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/
master/install)"
# Paths relative to Gruntfile.js
http_path = "/"
css_dir = "../source/css"
sass_dir = "scss"
images_dir = "../source/images"
Listing 2
INSTALLIERTE PLUGINS REGISTRIEREN
# relative Pfade auf Assets
relative_assets = true #relative Pfade auf Assets
Wir gehen von der package.json [2] aus, in der wir Tasks für das
Kompilieren von SCSS mit Compass, das Optimieren von JavaScript-Dateien, das Optimieren von Bildern und einen sogenannten
Watch-Task hinzugefügt haben, der diese Prozesse automatisiert.
Vor der Nutzung müssen die Plugins geladen werden:
#Alternativen :expanded, :nested oder :compact
output_style = :compressed
LADEN DER TASKS
module.exports = function(grunt){
...
// Tasks laden, herkömmliche Weise
// grunt.loadNpmTasks(‘grunt-contrib-compass’);
// grunt.loadNpmTasks(‘grunt-contrib-concat’);
// grunt.loadNpmTasks(‘grunt-contrib-uglify’);
// grunt.loadNpmTasks(‘grunt-contrib-watch’);
// Tasks laden, mit dem Plugin load-grunt-tasks
// https://github.com/sindresorhus/load-grunt-tasks
require('load-grunt-tasks')(grunt);
};
grunt.registerTask('default', []);
Listing 3
Wie in der Konfiguration ersichtlich, gibt es die Standard-Methode,
die installierten Tasks zu registrieren. Das geschieht über Auflistung der einzelnen Namen der Plugins. Das Plugin load-grunt-tasks
lädt alle in der package.json aufgelisteten Plugins automatisch
nach einem (konfigurierbaren) Pattern und macht die Gruntfile
übersichtlicher.
GRUNT WATCH FÜR SORGENFREIE
FRONTEND-ENTWICKLUNG
Nun konfigurieren wir unsere Tasks und legen Variablen an, die
uns die spätere Anpassung der Konfiguration erleichtern.
ANLEGEN DER PFAD-VARIABLEN
module.exports = function(grunt) {
var globalConfig = {
css:
'../source/css',
scss:
'scss',
scripts:
'../source/js',
scripts_src: 'js'
};
Listing 4
Per globalConfig lassen sich Variablen definieren, die über das
Gruntfile hinweg zur Verfügung stehen. Anstatt also an jeder Stelle
den Pfad der Dateien zu schreiben, verwenden wir beispielsweise
den Pfad zur SCSS-Datei so: <%= globalConfig.scss %>. Sollte sich
an der Ordnerstruktur des Projekts etwas verändern, muss nur die
globalConfig editiert werden [3].
Da wir SCSS in Verbindung mit Compass benutzen, muss vor
dem Start des watch-Tasks noch analog zur Gruntfile-Konfiguration die config.rb angelegt werden.
#entfernt Debugging-Kommentare
line_comments = false
Listing 5
Nachdem jetzt alles konfiguriert ist, wird ein Grunt-Task gestartet.
Da der watch-Task als default registriert ist, muss in der Konsole
im resources-Ordner nur Folgendes eingegeben werden, um diesen
zu starten:
START DES DEFAULT-TASKS
$ grunt
Listing 6
Ein registrierter Task kann jeden beliebigen Namen erhalten und
es können beliebig viele Tasks angelegt werden. Die Benennung
watch-project anstatt default resultiert im selben Ergebnis, verlangt aber einen anderen Aufruf in der Konsole, nämlich:
START EINES TASKS MIT ABWEICHENDEM NAMEN
$ grunt watch-project
Listing 7
Es erscheint die Ausgabe „Running watch task, waiting“. Fügt man
nun in einer SCSS-Datei probeweise ein paar Zeilen hinzu und speichert die Datei, registriert das der laufende Task und führt den im
watch-Task eingehängten Compass-Befehl aus. Somit erhalten wir
ein kompiliertes CSS-File in unserem angegeben Ziel-Ordner
„public_html/css“. Das Gleiche gilt für Änderungen in den JavaScript-Dateien: Hier wird erst concat und dann uglify ausgeführt,
was in main.min.js im Verzeichnis „public_html/js“ resultiert, das
alle Dateien aus dem lib-Ordner enthält. In der concat-Konfiguration ist zudem unter src die Reihenfolge angegeben, in der die
JavaScript-Dateien aneinander gehängt werden sollen. An den Anfang der Datei steht die jQuery-Source, erst danach folgen alle
anderen Files, die sich im js-Ordner befinden. Diese Konfiguration
kann wichtig sein, wenn bestimmte Libraries vor anderen geladen
werden müssen.
OPTIMIERUNG VON BILDMATERIAL UND
RETINA-SUPPORT
Nachdem Grunt nun für die Basis-Anforderung eines Web-Projekts
konfiguriert ist, lassen sich nach Bedarf Stück für Stück weitere
Plugins hinzufügen.
Als nützlich hat sich die Funktion erwiesen, Bildmaterial zu
komprimieren und für responsive Websites oder Retina-Devices
verschiedene Bildgrößen zu generieren. Dazu bedient man sich der
Plugins „grunt-contrib-imagemin“ und „grunt-responsive-images“.
Die Bildbearbeitung übernehmen Tools wie ImageMagick oder Gra-
© yeebase media 2015. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GmbH. http://t3n.de
2
phicsMagick. Mit dem zuvor installierten Homebrew ist die Installation denkbar einfach.
INSTALLATION GRAPHIKSMAGICK
$ brew install GraphicsMagick
Listing 8
Das zu optimierende Bildmaterial wird unter „resources/images“
abgelegt und das Gruntfile wie folgt erweitert [4].
Anschließend erfolgt die Registrierung des neuen Tasks optimize-images, der erst responsive_images und dann imagemin ausführt. Die Reihenfolge, in der die Tasks ausgeführt werden, ist in
der eckigen Klammer festgelegt. Die dort auftauchenden Bezeichnungen entsprechen den Namen in grunt.initConfig({ ... }).
AUFRUF TASK FÜR BILDOPTIMIERUNG
$ grunt optimize-images
Listing 9
Unsere Testbilder werden mit 100 Prozent Größe mit dem Suffix
„@2x“ als Retina-Bild und mit 50 Prozent Größe für die herkömmliche Bildausgabe im Ordner „public_html/images“ gespeichert.
Dort werden sie durch den imagemin-Task in ihrer Größe reduziert.
Mit ein wenig Herumprobieren an den Qualitätseinstellungen lässt
sich die richtige Kompression herausfinden, bei der noch eine ausreichende Qualität gewährleistet ist. Vorbei sind damit die Zeiten,
in denen Bilder per Software mit Stapelverarbeitung oder – noch
schlimmer – manuell für die Bedürfnisse im Web angepasst werden mussten.
Punkt. Mit jeder Webseite, jedem Browser und Endgerät steigt die
Zeit, die zum Testen aufgebracht werden muss. BrowserSync vereinfacht diese Vorgänge insofern, als sie gleichzeitig auf verschiedenen Browsern und Geräten dieselbe Webseite anzeigt und
synchronisiert. In Zusammenspiel mit Grunt ist BrowserSync so
konfigurierbar, dass die Webseite bei Änderungen an einer HTMLoder CSS-Datei automatisch überall neu lädt und sogar das Scrollen
und Klicken in allen Browsern synchron erfolgt. Das Plugin ermöglicht es beispielsweise, am Desktop über die Seite zu navigieren und
auf einem Tablet oder Smartphone, auf welchem der Browser synchronisiert ist, die Auswirkungen zu sehen, die Webseite zu prüfen
und debuggen.
Für die Verwendung dieser praktischen Funktion wird nach der
Installation von grunt-browser-sync das Gruntfile entsprechend
erweitert [7].
Beim Start des Tasks meldet das Terminal, dass BrowserSync
und die Seite über den konfigurierten Proxy ausgeführt wird. Darauf zeigt es an, unter welcher URL die Seite lokal und von extern,
also von Endgeräten im gleichen Netzwerk, zu erreichen ist. Die
externe URL ist die lokale IP mit einer Portangabe, die standardmäßig auf 3000 gesetzt ist, sich aber anpassen lässt. Diese externe
URL geben wir auf beliebig vielen mobilen Endgeräten ein, auf denen wir die Webseite testen möchten. Das Terminal listet alle
synchronisierten Browser mit ihrer Version auf.
STRESSFREI FAVICON UND TOUCH-ICONS
ERSTELLEN
Neben dem Bereitstellen von Retina-Bildmaterial für hochauflösende Geräte fällt beim Erstellen einer Responsive oder Mobile Site
nicht nur die Aufgabe an, ein Favicon, sondern auch Home-ScreenIcons zu erstellen. Mit der Vielzahl an mobilen Geräten ist auch die
Anzahl der benötigten Icons gestiegen: iOS benötigt ein anderes
Format als Android und das Windows Phone hat wiederum eine
veränderte Optik.
Hier kommt das überaus praktische Plugin grunt-favicons zu
Hilfe. Mit nur einer Ausgangsdatei, die in ausreichender Größe hinterlegt wird (erfahrungsgemäß reicht hier ein Format von 310px x
310px aus), lassen sich die benötigten Icons erstellen [5].
Der betreffende Task wird folgendermaßen ausgeführt:
GENERIEREN DER TOUCH-ICONS
$ grunt generate-touch-icons
Listing 10
Das Plugin stellt im definierten Ziel-Ordner die generierten Icons
bereit. Per Voreinstellung erzeugt es darüberhinaus die Datei favicon-test.html, welche bereits die passenden Meta-Tags zum Einbau
in unsere Webseite enthält. Damit lassen sich per Copy & Paste und
eventueller Anpassung der Bildpfade im Handumdrehen die benötigten Icons auf den mobilen Endgeräten bereitstellen.
CROSS-DEVICE-TESTING MIT BROWSERSYNC
BrowserSync [6] beschreibt seine Funktionalität selbst mit „Timesaving synchronised browser testing“ und trifft damit genau den
3
Das Terminal listet alle über Browser-Sync synchronisierten Geräte auf – inklusive
der verwendeten Browserversion. Cross-Browser-Testing gestaltet sich so um ein
vielfaches einfacher.
Bewegt man sich nun durch Scrollen oder das Klicken eines Links
über die Seite, werden diese Aktionen auf den anderen Geräten und
Browsern ebenso ausgeführt. Sogar das Ausfüllen von Formulare
funktioniert gleichzeitig. Zusätzlich ist BrowserSync in der gezeigten Konfiguration so eingerichtet, dass die synchronisierten Browser automatisch neu laden, wenn eine Änderung in den CSS- oder
HTML-Dateien erfolgt.
Die aktuelle Version bietet ein zusätzliches UI, das grafisch
aufbereitet die Terminal-Anzeige ersetzt und weitere Aktionen und
Konfigurationen ermöglicht. BrowserSync erleichtert das Testen
auf unterschiedlichen Geräten somit ungemein und ist deswegen
für eine Webseite mit Anforderungen an unterschiedliche Endgeräte sehr zu empfehlen.
AUTOMATISIERTE SHELL-BEFEHLE
Ein letztes Beispiel, das beweist, wie flexibel Grunt einsetzbar ist:
Unsere Entwicklungsumgebung setzt sich unter anderem aus Vagrant in Verbindung mit Virtualbox und git als Versionierungssystem zusammen. Der Arbeitsbeginn an einem Projekt sieht deswegen immer gleich oder zumindest sehr ähnlich aus: Den aktuellen
© yeebase media 2015. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GmbH. http://t3n.de
Stand aus git pullen, Vagrant starten, den Browser öffnen und gegebenenfalls noch den Standard-Grunt-Task anstoßen. Diese simplen Tätigkeiten kann ausgezeichnet das Plugin grunt-shell
übernehmen [8]. So muss man vor Arbeitsbeginn nur noch in den
resources-Ordner wechseln und folgendes Kommando eingeben:
ARBEITSUMGEBUNG VORBEREITEN MIT DER GRUNT-SHELL
$ grunt start-working
Listing 11
Anschließend kann man sich zurücklehnen und dem Terminal dabei zusehen, wie es die vorgegebenen Kommandos nacheinander
ausführt.
Weiterhin lassen sich über das Shell-Plugin Installationsprozesse automatisieren. TYPO3 kann einfach als Submodule hinzugefügt und per Symlink in das eigene Projekt integriert werden
[9]. Die Anwendungsmöglichkeiten des Grunt-Shell-Plugins sind,
wie in diesen kleinen Beispielen ersichtlich, sehr vielfältig und je
nach Bedarf konfigurierbar.
FAZIT
Grunt bietet die Möglichkeit, definierte, sich wiederholende Prozesse zu automatisieren. Gerade im Team werden damit für jeden
klare Strukturen geschaffen, was zur Qualitätssicherung beiträgt.
Einmal konfiguriert, verbessert sich die Effizienz in der Entwicklung, da nicht jedes Mal aufs Neue eine Lösung für den Umgang
mit täglich auftretenden Aufgaben gefunden werden muss.
Durch die aktive Community und die vielen vorhandenen Plugins sind den Anwendungsbereichen von Grunt kaum Grenzen gesetzt. Nach diesem Überblick über einige nützliche Plugins und
Konfigurationsmöglichkeiten sollte eine Basis geschaffen sein, sich
selbst an Grunt zu versuchen und seinen Workflow massiv zu vereinfachen. ↔
LINKS
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
↗ Artikel diskutieren und alle Links auf t3n.de/3589
Homebrew: http://brew.sh/
Gruntfile package.json: http://t3n.me/grunt-package-json
Gruntfile globalConfig: http://t3n.me/grunt-gruntfile-1
Gruntfile Bildmininierung: http://t3n.me/gruntfile-imagemin
Gruntfile Favicons: http://t3n.me/gruntfile-favicons
BrowserSync: http://www.browsersync.io/
Gruntfile BrowserSync: http://t3n.me/gruntfile-browsersync
Gruntfile Shell: http://t3n.me/gruntfile-shell
Gruntfile Shell TYPO3: http://t3n.me/gruntfile-shell-typo3
SABRINA SAUTER ist Webentwicklerin bei
der Digitalagentur Format D. Seit 2011 realisiert sie dort Websites unterschiedlichster Art
mit TYPO3 oder Magento. Wenn sie gerade
nicht am Schreibtisch sitzt, legt sie auch gerne
mal eine ihrer Schallplatten im 40er-Jahre-Salon der Agentur auf.
© yeebase media 2015. Veröffentlichung und Vervielfältigung nur mit Genehmigung der yeebase media GmbH. http://t3n.de
4