Grunt is commonly used as a javascript build tool. Grunt used NPM (node modules) for build purpose. Sometimes it’s very hard to find useful node modules for grunt. Here I will point out some useful node modules that is commonly used with grunt.
This module will clean any directory by removing the whole folders along with the containing files and folders. The ‘src’ options allow multiple folders with different path.
//clean the build directory
clean: {
build: {
src: ['dist']
}
},
grunt.template.today("yyyy-mm-dd HH-MM-ss-TT") // this will print current date time ex: 2017-01-28 10-10:56 PM
//copy the previous build to
copy: {
build: {
cwd: 'dist',
src: ['**'],
dest: 'backup/dist-<%= grunt.template.today("yyyy-mm-dd HH-MM-ss-TT") %>',
expand: true
}
},
//rename folders or files
rename: {
main: {
files: [
{
src: 'backup/dist',
dest: 'backup/dist_<%= grunt.template.today("yyyy-mm-dd HH-MM-ss-TT") %>'
}
]
}
},
//SASS compilar
sass: {
dist: {
files: [{
expand: true,
cwd: '../css/secondary',
src: ['**/*.scss'],
dest: 'dist/sass',
ext: '.css'
}]
}
},
// configure cssmin to minify css files
cssmin: {
options: {
banner: '/*\n <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> \n*/\n'
},
build: {
files: {
'dist/css/secondary.min.css': ['../css/secondary/**/*.css','dist/sass/**/*.css']
}
}
},
// configure jshint to validate js files
jshint: {
options: {
reporter: require('jshint-stylish'), // use jshint-stylish to make our errors look and read good
reporterOutput: 'jshint.html'
},
// when this task is run, lint the Gruntfile and all js files in src
build: ['gruntfile.js', '../js/secondary/**/*.js']
},
//compress folders
compress: {
main: {
options: {
archive: 'backup/gmil-<%= grunt.template.today("yyyy-mm-dd HH-MM-ss-TT") %>.zip'
},
expand: true,
cwd: 'dist',
src: ['**/*'],
dest: ''
}
},
// configure to uglify to minify js files based on subfolder.js
uglyfolders: {
general: {
options: {
src : '../js/secondary/',
target : 'dist/js'
}
}
},
// configure uglify to minify js files
uglify: {
options: {
banner: '/*\n <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> \n*/\n'
},
build: {
files: {
'dist/js/all.min.js': ['../js/secondary/**/*.js']
}
}
},
Finally this is how the package.json file looks like:
{
"name": "hello-grunt",
"version": "0.1.0",
"devDependencies": {
"grunt": "^1.0.1",
"grunt-build-number": "^1.0.0",
"grunt-contrib-cssmin": "latest",
"grunt-contrib-jshint": "latest",
"grunt-contrib-less": "latest",
"grunt-contrib-uglify": "latest",
"grunt-contrib-watch": "latest",
"grunt-include-source": "^1.0.0",
"grunt-ugly-folders": "^0.1.6",
"jshint-stylish": "latest"
},
"main": "gruntfile.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"buildnum": "1"
}
This is how the gruntfile.js file will looks like with all this configuration:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// configure jshint to validate js files
jshint: {
options: {
reporter: require('jshint-stylish'), // use jshint-stylish to make our errors look and read good
reporterOutput: 'jshint.html'
},
// when this task is run, lint the Gruntfile and all js files in src
build: ['gruntfile.js', '../js/secondary/**/*.js']
},
// configure uglify to minify js files
uglify: {
options: {
banner: '/*\n <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> \n*/\n'
},
build: {
files: {
'dist/js/all.min.js': ['../js/secondary/**/*.js']
}
}
},
// configure to uglify to minify js files based on subfolder.js
uglyfolders: {
general: {
options: {
src : '../js/secondary/',
target : 'dist/js'
}
}
},
// configure cssmin to minify css files ------------------------------------
cssmin: {
options: {
banner: '/*\n <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> \n*/\n'
},
build: {
files: {
'dist/css/secondary.min.css': '../css/secondary/**/*.css'
}
}
},
// include source to common.jsp
includeSource: {
options: {
basePath: '',
baseUrl: '',
templates: {
jsp: {
js: '<script src="{filePath}"></script>',
css: '<link rel="stylesheet" type="text/css" href="{filePath}" />'
}
}
},
myTarget: {
files: {
'dist/common.html' : 'index.tpl.html'
}
}
},
// build number
buildnumber: {
options: {
field: 'buildnum',
},
files: ['package.json', 'bower.json']
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-ugly-folders');
grunt.loadNpmTasks('grunt-include-source');
grunt.loadNpmTasks('grunt-build-number');
// this default task will go through all configuration (dev and production) in each task
grunt.registerTask('default', []);
// this task will only run the dev configuration
grunt.registerTask('dev', ['uglyfolders','cssmin', 'includeSource', 'buildnumber']);
// only run production configuration
grunt.registerTask('production', ['uglify', 'cssmin', 'includeSource', 'buildnumber']);
};
NEXT: How to use this modules with GULP, Yarn and WebPack