{"id":10495,"date":"2015-02-17T13:05:14","date_gmt":"2015-02-17T12:05:14","guid":{"rendered":"http:\/\/flaven.fr\/?p=10495"},"modified":"2026-09-16T10:07:47","modified_gmt":"2026-09-16T08:07:47","slug":"grunt-less-automate-mean-lean-decouvrir-le-potentiel-de-grunt","status":"publish","type":"post","link":"https:\/\/flaven.fr\/2015\/02\/grunt-less-automate-mean-lean-decouvrir-le-potentiel-de-grunt\/","title":{"rendered":"Grunt, Less, Automate, Mean, Lean &#8211; D\u00e9couvrir le potentiel de Grunt"},"content":{"rendered":"\n<p>  <!--  Grunt, Less, Automate, Mean, Lean - D\u00e9couvrir le potentiel de Grunt --><br \/>\n  \t<!--  Grunt, Gruntfile, minifying, concatenating, CSS, JavaScript, Automate, npm, Package, Sass, Less, Mean, Lean --><\/p>\n<p>En fait l&#8217;origine de ce billet \u00e9tait de tirer profit de MEAN.JS ou de MEAN.IO bref de toutes des facilit\u00e9s et nouveaut\u00e9s offertes par cet &#8220;attelage&#8221; design\u00e9 sous l&#8217;acronyme &#8220;MEAN&#8221; pour &#8220;MongoDB Express.js AngularJS Node.js&#8221;. En effet, cet ensemble permet &#8220;en deux deux&#8221; de forger une application, cross-platform.<\/p>\n<p>N\u00e9anmoins, en cours de route, on a finalement d\u00e9cid\u00e9 de s&#8217;arr\u00eater sur <b>Grunt<\/b>. Un puissant outil de gestion de t\u00e2ches. C&#8217;est surtout un bon moyen d&#8217;assurer un excellent niveau de qualit\u00e9 de livraison de code tout en industrialisant cette m\u00eame livraison. Son ex\u00e9cution garantie l&#8217;excellence sur des taches r\u00e9p\u00e9titives mais indispensables \u00e0 chaque livraison comme : la minification, la compilation, l&#8217;optimisation.<\/p>\n<p><b>Au-de-l\u00e0 de cette pure vis\u00e9e pratique, il faut tout de m\u00eame parler dans quoi s&#8217;inscrit l&#8217;\u00e9mergence de tels outils, un peu de modernit\u00e9 dans le management et l&#8217;ex\u00e9cution.<\/b><\/p>\n<ul>\n<li>Changement des m\u00e9thodes de travail\/organisation pour une \u00e9quipe en charge de d\u00e9ploiements pour une multitude d&#8217;applications cross-platform en front.<br \/>Source : Deploying JavaScript Applications<a href=\"https:\/\/alexsexton.com\/blog\/2013\/03\/deploying-javascript-applications\/\" target=\"_blank\">https:\/\/alexsexton.com\/blog\/2013\/03\/deploying-javascript-applications\/<\/a><\/li>\n<\/ul>\n<h4>Des applications modernes pour des navigateurs modernes<\/h4>\n<p>Une petite parenth\u00e8se sur l&#8217;assortiment <b>MEAN<\/b> qui contient \u00e0 lui seul de quoi rebattre les cartes d&#8217;un univers encore domin\u00e9 aujourd&#8217;hui domin\u00e9 par LAMP.<\/p>\n<p>La fait de choisir Node \u00e9mancipe totalement cette technologie de la notion de plate-forme et m\u00eame de la notion de serveur. En effet, Node tourne sur n&#8217;importe quelle plateforme et remplace litt\u00e9ralement apache. Le javascript s&#8217;ex\u00e9cute c\u00f4t\u00e9 serveur et c\u00f4t\u00e9 client.<\/p>\n<p>En fait c&#8217;est le tout en un, d\u00e9ployer votre application sur un serveur, c&#8217;est aussi d\u00e9ploy\u00e9 un application avec le serveur.<\/p>\n<p>La voie ouverte par MEAN donne aussi \u00e0 d\u00e9couvrir un ensemble encore plus vaste de technologies dont notamment Grunt.<\/p>\n<ul>\n<li>Yeoman qui est une combinaisons de 3 outils pour le scaffolding (Yo), la gestion scripts (Grunt) ou la gestion de d\u00e9pendances (Bower).<\/li>\n<li>Bootstrap: le c\u00e9l\u00e9brissime ensemble de CSS, pr\u00eat \u00e0 l&#8217;emploi, qui fait de votre projet, un projet imm\u00e9diatement responsive.<\/li>\n<li>Les BDD NoSQL type MongoDB : le basculement d&#8217;une BDD traditionnelle \u00e0 une base NoSQL peut repr\u00e9senter un gain de temps consid\u00e9rable : moins de temps \u00e0 \u00e9crire des requ\u00eates SQL et plus de temps \u00e0 \u00e9crire des fonctions map\/reduce en JavaScript. Moins de probl\u00e8me dans la logique de transformation des donn\u00e9es en effet MongoDB produit nativement et directement du JSON par cons\u00e9quent vous ne concevez plus seulement une base mais directement des services web d&#8217;une RESTful API.<\/li>\n<\/ul>\n<p>Basculer de LAMP \u00e0 MEAN c&#8217;est changer d&#8217;orientation dans le d\u00e9veloppement. De la traditionnelle cr\u00e9ation de page c\u00f4t\u00e9 serveur, on passe \u00e0 la cr\u00e9ation de page unique c\u00f4t\u00e9 client (connu sous le nom de SPA, Single-Page Application). C&#8217;est aussi un double changement de perspective dans le d\u00e9veloppement : (i) D&#8217;un mode synchrone, on passe essentiellement \u00e0 un mode &#8220;event-driven&#8221; et asynchrone ; (ii) D&#8217;une conception ax\u00e9e autour d&#8217;un \u00e9cran ou d&#8217;une page, on passe \u00e0 une conception ax\u00e9e autour de composants.<\/p>\n<h4>MEAN rime avec LEAN<\/h4>\n<p>Ces avantages techniques ont d&#8217;ailleurs des r\u00e9percussions sur le mode de gestion des projets. Cela va de pair avec l&#8217;adoption d&#8217;une gestion de projet de mani\u00e8re it\u00e9rative, articul\u00e9 autour d&#8217;un concept de minimum viable product (MVP). En effet, l&#8217;un des b\u00e9n\u00e9fices imm\u00e9diat de MEAN, c&#8217;est l&#8217;extr\u00eame rapidit\u00e9 dans la r\u00e9alisation d&#8217;un prototype en plus du fait que vous pouvez imm\u00e9diatement prototyp\u00e9 pour \u00eatre cross-plaform :  laptops, smartphones et tablettes m\u00eame t\u00e9l\u00e9 connect\u00e9es.<\/p>\n<p>En outre, le fait d&#8217;utiliser MongoDB appartienne au technologie NoSQL permet de changer rapidement et de modifier la couche de donn\u00e9es sans avoir \u00e0 se soucier des migrations. Un avantage tr\u00e8s utile lorsque on tache de construire un produit sans sp\u00e9cifications claires, c&#8217;est qui est le cas de nombreux.<\/p>\n<p><b>Tous ces technologies r\u00e9sonnent avec insistance autour des termes suivants : prototype, souplesse, agilit\u00e9, incertitude, retour d&#8217;usage. MEAN est clairement en phase avec la boucle vertueuse de LEAN : learn, build, mesure.<\/b><\/p>\n<ul>\n<li>Une suite de 4 excellents articles, tr\u00e8s bonne entr\u00e9e en mati\u00e8re sur MEAN <a href=\"http:\/\/www.ibm.com\/developerworks\/library\/wa-mean1\/index.html\" target=\"_blank\">Mastering MEAN: Introducing the MEAN stack<\/a><\/li>\n<\/ul>\n<h4>Utiliser Grunt<\/h4>\n<p>On va faire un survol rapide de Grunt. Ce qui suppose au pr\u00e9alable de cr\u00e9er un r\u00e9pertoire pour notre projet, r\u00e9pertoire que l&#8217;on nomme <b>TestForGrunt<\/b>.<\/p>\n<p>Via la console, on se place en suite dans ce r\u00e9pertoire. <code>cd \/[path-to-your-project]\/TestForGrunt<\/code>. Il faut ensuite <b>installer Grunt pour une installation globale par exemple \u00e0 l&#8217;aide de cette commande.<\/b><\/p>\n<p><code>npm install -g grunt-cli<\/code><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2015\/02\/using_grunt_1.jpg\" width=\"640\" height=\"480\" alt=\"Grunt, Less, Automate, Mean, Lean - D\u00e9couvrir le potentiel de Grunt\"><\/p>\n<p><b>On peut \u00e0 toutes fins utiles, v\u00e9rifier la version de Grunt<\/b><br \/>\n<code>grunt --v<\/code><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2015\/02\/using_grunt_2.jpg\" width=\"640\" height=\"480\" alt=\"Grunt, Less, Automate, Mean, Lean - D\u00e9couvrir le potentiel de Grunt\"><\/p>\n<p>Vous pouvez passer \u00e0 la cr\u00e9ation proprement dite de votre projet <b>SampleGrunt<\/b>.<\/p>\n<p><b>Il faut pour cela pr\u00e9parer un fichier <code>package.json<\/code><\/b><\/p>\n<pre lang=\"json\">\r\n\t\r\n\t{\r\n\t  \"name\": \"SampleGrunt\",\r\n\t  \"version\": \"0.1.0\",\r\n\t  \"author\": \"Bruno Flaven\",\r\n\t  \"private\": true,\r\n\t  \"devDependencies\": {\r\n\t    \"grunt\": \"~0.4.0\",\r\n\t    \"grunt-contrib-cssmin\": \"*\",\r\n\t    \"grunt-contrib-imagemin\": \"^0.9.3\",\r\n\t    \"grunt-contrib-sass\": \"*\",\r\n\t    \"grunt-contrib-uglify\": \"*\",\r\n\t    \"grunt-contrib-watch\": \"*\",\r\n\t    \"grunt-cssc\": \"*\",\r\n\t    \"grunt-htmlhint\": \"*\",\r\n\t    \"matchdep\": \"*\"\r\n\t  }\r\n\t}\r\n\t\r\n<\/pre>\n<p>Une fois, le fichier \u00e0 la racine de votre r\u00e9pertoire <b>SampleGrunt<\/b>. Lancer la commande <code>npm install<\/code>. Cela indique \u00e0 npm les d\u00e9pendances \u00e0 installer et \u00e0 placer dans un dossier qui sera cr\u00e9e nomm\u00e9 <code>node_modules<\/code>.<\/p>\n<p><b>Tous les fichiers du projet sont dans un r\u00e9pertoire nomm\u00e9 <code>assets<\/code>, il existe 3 sous-r\u00e9pertoire \u00e0 l&#8217;int\u00e9rieur de ce r\u00e9pertoire principal : images, js, sass<\/b>.<\/p>\n<p>Pour de plus amples explications, je vous invite \u00e0 lire cette article ne anglais tr\u00e8s bien fait dont je me suis inspir\u00e9 \ud83d\ude42 Un peu feignant je suis. <a href=\"http:\/\/www.smashingmagazine.com\/2013\/10\/29\/get-up-running-grunt\/\" target=\"_blank\">http:\/\/www.smashingmagazine.com\/2013\/10\/29\/get-up-running-grunt\/<\/a>.<\/p>\n<p><b>Compression des images avec Grunt<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2015\/02\/using_grunt_3.jpg\" width=\"640\" height=\"480\" alt=\"Grunt, Less, Automate, Mean, Lean - D\u00e9couvrir le potentiel de Grunt\"><\/p>\n<p><b>Compression des images avec Grunt<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2015\/02\/using_grunt_4.jpg\" width=\"640\" height=\"480\" alt=\"Grunt, Less, Automate, Mean, Lean - D\u00e9couvrir le potentiel de Grunt\"><\/p>\n<p><b>Le fichier <code>gruntfile.js<\/code> complet<\/b><\/p>\n<pre lang=\"javascript\">\r\n\tmodule.exports = function(grunt){\r\n\r\n\trequire(\"matchdep\").filterDev(\"grunt-*\").forEach(grunt.loadNpmTasks);\r\n\r\n\t\t\/*\r\n\t    grunt.initConfig({\r\n\t        pkg: grunt.file.readJSON('package.json')\r\n\t    });\r\n\t\t*\/\r\n\tgrunt.initConfig({\r\n\t    pkg: grunt.file.readJSON('package.json'),\r\n\t    htmlhint: {\r\n\t        build: {\r\n\t            options: {\r\n\t                'tag-pair': true,\r\n\t                'tagname-lowercase': true,\r\n\t                'attr-lowercase': true,\r\n\t                'attr-value-double-quotes': true,\r\n\t                'doctype-first': true,\r\n\t                'spec-char-escape': true,\r\n\t                'id-unique': true,\r\n\t                'head-script-disabled': true,\r\n\t                'style-disabled': true\r\n\t            },\r\n\t            src: ['index.html']\r\n\t        }\r\n\t    },\r\n\t\t\/* watch task *\/\r\n\t\twatch: {\r\n\t\t    html: {\r\n\t\t        files: ['index.html'],\r\n\t\t        tasks: ['htmlhint']\r\n\t\t    }\r\n\t\t},\r\n\t\tuglify: {\r\n\t\t    build: {\r\n\t\t        files: {\r\n\t\t            'build\/js\/base.min.js': ['assets\/js\/base.js']\r\n\t\t        }\r\n\t\t    }\r\n\t\t},\r\n\t\twatch: {\r\n\t\t    js: {\r\n\t\t        files: ['assets\/js\/base.js'],\r\n\t\t        tasks: ['uglify']\r\n\t\t    }\r\n\t\t},\r\n\t\t\/* scss *\/\r\n\t\r\n\t\tcssc: {\r\n\t\t    build: {\r\n\t\t        options: {\r\n\t\t            consolidateViaDeclarations: true,\r\n\t\t            consolidateViaSelectors:    true,\r\n\t\t            consolidateMediaQueries:    true\r\n\t\t        },\r\n\t\t        files: {\r\n\t\t            'build\/css\/master.css': 'build\/css\/master.css'\r\n\t\t        }\r\n\t\t    }\r\n\t\t},\r\n\r\n\t\tcssmin: {\r\n\t\t    build: {\r\n\t\t        src: 'build\/css\/master.css',\r\n\t\t        dest: 'build\/css\/master.css'\r\n\t\t    }\r\n\t\t},\r\n\r\n\t\tsass: {\r\n\t\t    build: {\r\n\t\t        files: {\r\n\t\t            'build\/css\/master.css': 'assets\/sass\/master.scss'\r\n\t\t        }\r\n\t\t    }\r\n\t\t},\r\n\t\r\n\t\timagemin: {\r\n\t\t    dynamic: {\r\n\t\t        files: [{\r\n\t\t            expand: true,\r\n\t\t            cwd: 'assets\/images\/',\r\n\t\t            src: ['**\/*.{png,jpg,gif,JPG}'],\r\n\t\t            dest: 'build\/images'\r\n\t\t        }]\r\n\t\t    }\r\n\t\t}\r\n\t\r\n\t}); \/* grunt init *\/\r\n\r\n\r\n\t\tgrunt.loadNpmTasks('grunt-contrib-imagemin');\r\n\t    grunt.registerTask('default', ['imagemin']);\r\n\t\tgrunt.registerTask('buildcss',  ['sass', 'cssc', 'cssmin']);\r\n\r\n\t};\r\n<\/pre>\n<h2>En savoir plus<\/h2>\n<ul>\n<li>Install Grunt JS on a Mac \u2013 Tutorial<br \/><a href=\"http:\/\/www.codebelt.com\/javascript\/install-grunt-js-on-a-mac\/\" target=\"_blank\">http:\/\/www.codebelt.com\/javascript\/install-grunt-js-on-a-mac\/<\/a><\/li>\n<li>Grunt Tricks: Part One<br \/><a href=\"http:\/\/dontkry.com\/posts\/code\/grunt-tricks.html\" target=\"_blank\">http:\/\/dontkry.com\/posts\/code\/grunt-tricks.html<\/a><\/li>\n<li>Supercharging your Gruntfile<br \/><a href=\"http:\/\/www.html5rocks.com\/en\/tutorials\/tooling\/supercharging-your-gruntfile\/\" target=\"_blank\">http:\/\/www.html5rocks.com\/en\/tutorials\/tooling\/supercharging-your-gruntfile\/<\/a><\/li>\n<li>Optimizing Images with Grunt<br \/><a href=\"http:\/\/blog.grayghostvisuals.com\/grunt\/image-optimization\/\" target=\"_blank\">http:\/\/blog.grayghostvisuals.com\/grunt\/image-optimization\/<\/a><\/li>\n<li>Rien \u00e0 voir mais int\u00e9ressant quand m\u00eame pour les primatologues en herbe: Chimps learn new grunt for &#8216;apple&#8217;<br \/><a href=\"link\" target=\"_blank\">http:\/\/www.bbc.com\/news\/science-environment-31128237<\/a><\/li>\n<li>Getting started de gruntjs.com<br \/><a href=\"http:\/\/gruntjs.com\/getting-started\" target=\"_blank\">http:\/\/gruntjs.com\/getting-started<\/a><\/li>\n<li>Introducing Grunt<br \/><a href=\"http:\/\/bocoup.com\/weblog\/introducing-grunt\/\" target=\"_blank\">http:\/\/bocoup.com\/weblog\/introducing-grunt\/<\/a><\/li>\n<li>How to Setup Bower in Your Next Project<br \/><a href=\"http:\/\/code.tutsplus.com\/tutorials\/how-to-setup-bower-in-your-next-project--cms-20526\" target=\"_blank\">http:\/\/code.tutsplus.com\/tutorials\/how-to-setup-bower-in-your-next-project&#8211;cms-20526<\/a><\/li>\n<li>Grunt pour ceux qui pensent que Grunt est compliqu\u00e9. Version fran\u00e7aise de l&#8217;article ci-dessous<br \/><a href=\"http:\/\/la-cascade.ghost.io\/grunt-pour-ceux-qui-pensent-que-grunt-est-complique\/\" target=\"_blank\">http:\/\/la-cascade.ghost.io\/grunt-pour-ceux-qui-pensent-que-grunt-est-complique\/<\/a><\/li>\n<li>Grunt for People Who Think Things Like Grunt are Weird and Hard<br \/><a href=\"http:\/\/24ways.org\/2013\/grunt-is-not-weird-and-hard\/\" target=\"_blank\">http:\/\/24ways.org\/2013\/grunt-is-not-weird-and-hard\/<\/a><\/li>\n<li>Pour utiliser le plugin LiveReload, parfois utile pour voir les changements en temps r\u00e9els effectu\u00e9s \u00e0 l&#8217;aide de Grunt<br \/><a href=\"http:\/\/feedback.livereload.com\/knowledgebase\/articles\/86242-how-do-i-install-and-use-the-browser-extensions-\" target=\"_blank\">http:\/\/feedback.livereload.com\/knowledgebase\/articles\/86242-how-do-i-install-and-use-the-browser-extensions-<\/a><\/li>\n<li>Un tr\u00e8s bon exemple pour &#8220;Minify PNG and JPEG images&#8221;<br \/><a href=\"https:\/\/github.com\/gruntjs\/grunt-contrib-imagemin\" target=\"_blank\">https:\/\/github.com\/gruntjs\/grunt-contrib-imagemin<\/a><\/li>\n<li>Get Up And Running With Grunt<br \/><a href=\"http:\/\/www.smashingmagazine.com\/2013\/10\/29\/get-up-running-grunt\/\" target=\"_blank\">http:\/\/www.smashingmagazine.com\/2013\/10\/29\/get-up-running-grunt\/<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>En fait l&#8217;origine de ce billet \u00e9tait de tirer profit de MEAN.JS ou de MEAN.IO bref de toutes des facilit\u00e9s et nouveaut\u00e9s offertes par cet&hellip; <\/p>\n<p class=\"text-center\"><a href=\"https:\/\/flaven.fr\/2015\/02\/grunt-less-automate-mean-lean-decouvrir-le-potentiel-de-grunt\/\" class=\"more-link\">Continue reading &rarr; <span class=\"screen-reader-text\">Grunt, Less, Automate, Mean, Lean &#8211; D\u00e9couvrir le potentiel de Grunt<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":10500,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bf_ai_meta_description":"Grunt automates tasks like minification, compilation, and optimization for efficient, cross-platform app development.","bf_ai_og_title":"Grunt: Automate Code Delivery","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[3439,3444,3449,3435],"tags":[2147,2146,209,2143,2144,226,2152,2150,2151,2145,3514,3491,1869,2148,2149],"class_list":["post-10495","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apis-integration","category-programming-databases","category-tutorials-how-to","category-web-development","tag-automate","tag-concatenating","tag-css","tag-grunt","tag-gruntfile","tag-javascript","tag-lean","tag-less","tag-mean","tag-minifying","tag-mongodb","tag-nosql","tag-npm","tag-package","tag-sass"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Vuhl-2Jh","jetpack_featured_media_url":"https:\/\/flaven.fr\/wp-content\/uploads\/2015\/02\/using_grunt_bf.jpg","_links":{"self":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/10495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/comments?post=10495"}],"version-history":[{"count":3,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/10495\/revisions"}],"predecessor-version":[{"id":10503,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/10495\/revisions\/10503"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media\/10500"}],"wp:attachment":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media?parent=10495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/categories?post=10495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/tags?post=10495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}