Useful NPM Modules for Grunt

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