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/