Last Updated: February 25, 2016
·
2.027K
· eugenf

Grunt workflow for sass & coffee

Here's my workflow for Grunt for a simple frontend. Can be used with WordPress.

Package.json

{
    "name" : "random-website",
    "version" : "1.0.0",
    "devDependencies" : {
        "grunt" :                       "latest",
        "grunt-contrib-cssmin":         "*",
        "grunt-contrib-sass":           "*",
        "grunt-contrib-uglify":         "*",
        "grunt-contrib-imagemin":       "*",
        "grunt-contrib-watch":          "*",
        "grunt-contrib-jshint":         "*",
        "grunt-contrib-coffee":         "*",
        "grunt-cssc":                   "*",
        "grunt-htmlhint":               "*",
        "grunt-rsync":                  "*",
        "matchdep":                     "*"
    }
}

Gruntfile.js

'use strict';

module.exports = function(grunt) {

    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    grunt.initConfig({

        appDir: './assets',
        sassDir: '<%= appDir %>/stylesheets/sass',
        cssDir: '<%= appDir %>/stylesheets/css',
        coffeeDir: '<%= appDir %>/scripts/coffee',
        jsLibsDir: '<%= appDir %>/scripts/libs',
        jsDir: '<%= appDir %>/scripts/js',

        pkg: grunt.file.readJSON("package.json"),

        // watch for changes and trigger compass, jshint, uglify and livereload
        watch: {
            js: {
                files: '<%= jshint.all %>',
                tasks: ['uglify']
            },
            coffee: {
                files: ['<%= coffeeDir %>/*'],
                tasks: ['coffee']
            },
            css: {
                files: ['<%= sassDir %>/*.scss'],
                tasks: ['sass'],
                options: {
                    livereload: true
                }
            }
        },

        sass: {
            dist: {
                options: {
                    // nested, compact, compressed, expanded
                    style: 'expanded'
                },
                files: {
                    '<%= cssDir %>/main.css': '<%= sassDir %>/main.scss'
                }
            }
        },

        // javascript linting with jshint
        jshint: {
            all: [
                'Gruntfile.js'
            ]
        },

        // uglify to concat, minify, and make source maps
        uglify: {
            dist: {
                files: {
                    '<%= jsDir %>/plugins.js': [
                        '<%= jsLibsDir %>/*.js'
                    ],
                    '<%= jsDir %>/scripts.js': [
                        '<%= jsDir %>/scripts.js'
                    ]
                }
            }
        },

        // uglify to concat, minify, and make source maps
        coffee: {
            compile: {
                files: {
                    '<%= jsDir %>/scripts.js': [
                        '<%= coffeeDir %>/*',
                    ]
                }
            }
        },

        // image optimization
        imagemin: {
            dist: {
                options: {
                    optimizationLevel: 7,
                    progressive: true
                },
                files: [{
                    expand: true,
                    cwd: '<%= appDir %>/images/',
                    src: '**/*',
                    dest: '<%= appDir %>/images/'
                }]
            }
        },

        // deploy via rsync
        deploy: {
            options: {
                args: ["--verbose"],
                exclude: ['.git*', '.sass-cache*', "*.scss", 'node_modules', 'Gruntfile.js', 'package.json', '.DS_Store', 'README.md'],
                recursive: true
            },
            production: {
                options: {
                    src: "./",
                    dest: "~/public_html/",
                    host: "figursky@somehost.com",
                    syncDestIgnoreExcl: true
                }
            }
        },
    });

    // rename tasks
    grunt.renameTask('rsync', 'deploy');

    // register task
    grunt.registerTask('default', ['watch']);
};