On Github 0gust1 / introduction_grunt
Vu par la lorgnette d'un dev-front / UI designer / intégrateur...
Installer globalement le wrapper pour la console.
npm install -g grunt-cli
Ensuite tout se passe au niveau de votre projet :
cd <yourProjectDir>
Si votre projet ne contient pas encore de fichier package.json, faites un npm init à la raçine de votre projet.
Installez les plugins grunt dont vous avez besoin :
npm install grunt --save-dev npm install grunt-contrib-jshint --save-dev
Et non pas un moteur de tâche.
Des tâches pour à peu près tout.
etc...
Ecrire ses propres tâches.
grunt.registerTask('myTask', 'ma super tâche', ['jshint:prod','tests:prod'])
Là où la magie opère.
On va ecrire quelque chose
Là où tout se passe.
module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } }); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); };
Parce qu'on va travailler avec des fichiers et des arborescences. Souvent.
// You can specify single files: {src: 'foo/this.js', dest: ...} // Or arrays of files: {src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: ...} // Or you can generalize with a glob pattern: {src: 'foo/th*.js', dest: ...} // This single node-glob pattern: {src: 'foo/{a,b}*.js', dest: ...} // Could also be written like this: {src: ['foo/a*.js', 'foo/b*.js'], dest: ...} // All .js files, in foo/, in alpha order: {src: ['foo/*.js'], dest: ...} // Here, bar.js is first, followed by the remaining files, in alpha order: {src: ['foo/bar.js', 'foo/*.js'], dest: ...} // All files except for bar.js, in alpha order: {src: ['foo/*.js', '!foo/bar.js'], dest: ...} // All files in alpha order, but with bar.js at the end. {src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...} // Templates may be used in filepaths or glob patterns: {src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'} // But they may also reference file lists defined elsewhere in the config: {src: ['foo/*.js', '<%= jshint.all.src %>'], dest: ...}
Quand on doit travailler avec un ensemble conséquent de fichiers.
Quand on veut pouvoir conserver la hierarchie de système de fichiers (lors d'une copie par ex.)
files: [{ expand: true, // Enable dynamic expansion cwd: 'img/src', // Src matches are relative to this path src: ['**/*.{png,jpg,gif}'], // Actual patterns to match dest: 'img/' // Destination path prefix // ext :'' }]
Parce que tout n'est pas rose chez les cochons sauvages
Pas évident pour les plugins. Plus simple pour les custom tasks.
Assez limité, mais ça peut aider.
node --debug-brk $(which grunt) votre_tache_grunt
ou sinon :
npm install grunt-node-inspector --save-dev
https://npmjs.org/package/grunt-node-inspector
npm install grunt-debug
Pour dégraisser le GruntFile
├── Gruntfile.js ├── grunt-tasks │ ├── options │ │ ├── imagemin.js │ │ ├── notify.js │ │ └── watch.js │ ├── set_config.js │ └── set_global.js
module.exports = function(grunt) { require('load-grunt-config')(grunt, { configPath: 'grunt-tasks/options' }); grunt.loadTasks('grunt-tasks'); grunt.registerTask('default', ['watch']); };
Comment ?
npm install load-grunt-config --save-dev
npm install load-grunt-tasks --save-dev
Les templates sont évaluées à l'execution.
Les templates sont évaluées récursivement (un template peut en utiliser d'autres).
Accès à l'ensemble de l'objet de config ainsi qu'aux fonctions de l'objet grunt (cf API).
(Thomas Parisot) "Dynamic Grunt targets using templates" https://oncletom.io/2013/dynamic-grunt-targets-using-templates/
Plugins Grunt : http://gruntjs.com/plugins
Documentation Grunt : http://gruntjs.com/getting-started
API Grunt : http://gruntjs.com/api
(Thomas Parisot) "Dynamic Grunt targets using templates" https://oncletom.io/2013/dynamic-grunt-targets-using-templates/