Grunt, Less, Automate, Mean, Lean – Découvrir le potentiel de Grunt


En fait l’origine de ce billet était de tirer profit de MEAN.JS ou de MEAN.IO bref de toutes des facilités et nouveautés offertes par cet “attelage” designé sous l’acronyme “MEAN” pour “MongoDB Express.js AngularJS Node.js”. En effet, cet ensemble permet “en deux deux” de forger une application, cross-platform.

Néanmoins, en cours de route, on a finalement décidé de s’arrêter sur Grunt. Un puissant outil de gestion de tâches. C’est surtout un bon moyen d’assurer un excellent niveau de qualité de livraison de code tout en industrialisant cette même livraison. Son exécution garantie l’excellence sur des taches répétitives mais indispensables à chaque livraison comme : la minification, la compilation, l’optimisation.

Au-de-là de cette pure visée pratique, il faut tout de même parler dans quoi s’inscrit l’émergence de tels outils, un peu de modernité dans le management et l’exécution.

Des applications modernes pour des navigateurs modernes

Une petite parenthèse sur l’assortiment MEAN qui contient à lui seul de quoi rebattre les cartes d’un univers encore dominé aujourd’hui dominé par LAMP.

La fait de choisir Node émancipe totalement cette technologie de la notion de plate-forme et même de la notion de serveur. En effet, Node tourne sur n’importe quelle plateforme et remplace littéralement apache. Le javascript s’exécute côté serveur et côté client.

En fait c’est le tout en un, déployer votre application sur un serveur, c’est aussi déployé un application avec le serveur.

La voie ouverte par MEAN donne aussi à découvrir un ensemble encore plus vaste de technologies dont notamment Grunt.

  • Yeoman qui est une combinaisons de 3 outils pour le scaffolding (Yo), la gestion scripts (Grunt) ou la gestion de dépendances (Bower).
  • Bootstrap: le célébrissime ensemble de CSS, prêt à l’emploi, qui fait de votre projet, un projet immédiatement responsive.
  • Les BDD NoSQL type MongoDB : le basculement d’une BDD traditionnelle à une base NoSQL peut représenter un gain de temps considérable : moins de temps à écrire des requêtes SQL et plus de temps à écrire des fonctions map/reduce en JavaScript. Moins de problème dans la logique de transformation des données en effet MongoDB produit nativement et directement du JSON par conséquent vous ne concevez plus seulement une base mais directement des services web d’une RESTful API.

Basculer de LAMP à MEAN c’est changer d’orientation dans le développement. De la traditionnelle création de page côté serveur, on passe à la création de page unique côté client (connu sous le nom de SPA, Single-Page Application). C’est aussi un double changement de perspective dans le développement : (i) D’un mode synchrone, on passe essentiellement à un mode “event-driven” et asynchrone ; (ii) D’une conception axée autour d’un écran ou d’une page, on passe à une conception axée autour de composants.

MEAN rime avec LEAN

Ces avantages techniques ont d’ailleurs des répercussions sur le mode de gestion des projets. Cela va de pair avec l’adoption d’une gestion de projet de manière itérative, articulé autour d’un concept de minimum viable product (MVP). En effet, l’un des bénéfices immédiat de MEAN, c’est l’extrême rapidité dans la réalisation d’un prototype en plus du fait que vous pouvez immédiatement prototypé pour être cross-plaform : laptops, smartphones et tablettes même télé connectées.

En outre, le fait d’utiliser MongoDB appartienne au technologie NoSQL permet de changer rapidement et de modifier la couche de données sans avoir à se soucier des migrations. Un avantage très utile lorsque on tache de construire un produit sans spécifications claires, c’est qui est le cas de nombreux.

Tous ces technologies résonnent avec insistance autour des termes suivants : prototype, souplesse, agilité, incertitude, retour d’usage. MEAN est clairement en phase avec la boucle vertueuse de LEAN : learn, build, mesure.

Utiliser Grunt

On va faire un survol rapide de Grunt. Ce qui suppose au préalable de créer un répertoire pour notre projet, répertoire que l’on nomme TestForGrunt.

Via la console, on se place en suite dans ce répertoire. cd /[path-to-your-project]/TestForGrunt. Il faut ensuite installer Grunt pour une installation globale par exemple à l’aide de cette commande.

npm install -g grunt-cli

Grunt, Less, Automate, Mean, Lean - Découvrir le potentiel de Grunt

On peut à toutes fins utiles, vérifier la version de Grunt
grunt --v

Grunt, Less, Automate, Mean, Lean - Découvrir le potentiel de Grunt

Vous pouvez passer à la création proprement dite de votre projet SampleGrunt.

Il faut pour cela préparer un fichier package.json

 
	{
	  "name": "SampleGrunt",
	  "version": "0.1.0",
	  "author": "Bruno Flaven",
	  "private": true,
	  "devDependencies": {
	    "grunt": "~0.4.0",
	    "grunt-contrib-cssmin": "*",
	    "grunt-contrib-imagemin": "^0.9.3",
	    "grunt-contrib-sass": "*",
	    "grunt-contrib-uglify": "*",
	    "grunt-contrib-watch": "*",
	    "grunt-cssc": "*",
	    "grunt-htmlhint": "*",
	    "matchdep": "*"
	  }
	}

Une fois, le fichier à la racine de votre répertoire SampleGrunt. Lancer la commande npm install. Cela indique à npm les dépendances à installer et à placer dans un dossier qui sera crée nommé node_modules.

Tous les fichiers du projet sont dans un répertoire nommé assets, il existe 3 sous-répertoire à l’intérieur de ce répertoire principal : images, js, sass.

Pour de plus amples explications, je vous invite à lire cette article ne anglais très bien fait dont je me suis inspiré 🙂 Un peu feignant je suis. http://www.smashingmagazine.com/2013/10/29/get-up-running-grunt/.

Compression des images avec Grunt
Grunt, Less, Automate, Mean, Lean - Découvrir le potentiel de Grunt

Compression des images avec Grunt
Grunt, Less, Automate, Mean, Lean - Découvrir le potentiel de Grunt

Le fichier gruntfile.js complet

	module.exports = function(grunt){
 
	require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
 
		/*
	    grunt.initConfig({
	        pkg: grunt.file.readJSON('package.json')
	    });
		*/
	grunt.initConfig({
	    pkg: grunt.file.readJSON('package.json'),
	    htmlhint: {
	        build: {
	            options: {
	                'tag-pair': true,
	                'tagname-lowercase': true,
	                'attr-lowercase': true,
	                'attr-value-double-quotes': true,
	                'doctype-first': true,
	                'spec-char-escape': true,
	                'id-unique': true,
	                'head-script-disabled': true,
	                'style-disabled': true
	            },
	            src: ['index.html']
	        }
	    },
		/* watch task */
		watch: {
		    html: {
		        files: ['index.html'],
		        tasks: ['htmlhint']
		    }
		},
		uglify: {
		    build: {
		        files: {
		            'build/js/base.min.js': ['assets/js/base.js']
		        }
		    }
		},
		watch: {
		    js: {
		        files: ['assets/js/base.js'],
		        tasks: ['uglify']
		    }
		},
		/* scss */
 
		cssc: {
		    build: {
		        options: {
		            consolidateViaDeclarations: true,
		            consolidateViaSelectors:    true,
		            consolidateMediaQueries:    true
		        },
		        files: {
		            'build/css/master.css': 'build/css/master.css'
		        }
		    }
		},
 
		cssmin: {
		    build: {
		        src: 'build/css/master.css',
		        dest: 'build/css/master.css'
		    }
		},
 
		sass: {
		    build: {
		        files: {
		            'build/css/master.css': 'assets/sass/master.scss'
		        }
		    }
		},
 
		imagemin: {
		    dynamic: {
		        files: [{
		            expand: true,
		            cwd: 'assets/images/',
		            src: ['**/*.{png,jpg,gif,JPG}'],
		            dest: 'build/images'
		        }]
		    }
		}
 
	}); /* grunt init */
 
 
		grunt.loadNpmTasks('grunt-contrib-imagemin');
	    grunt.registerTask('default', ['imagemin']);
		grunt.registerTask('buildcss',  ['sass', 'cssc', 'cssmin']);
 
	};

En savoir plus