Using Grunt To Streamline Magento Development

Want to know GruntJS and how it can automate huge areas of your Magento workflow?

Why Would You Want It?

Simple. Automation! Every good programmer knows automation is key to a well-oiled development process from build to testing. At Develo, we’re always seeking new ways to improve and optimise our workflow to benefit our customers.

What is it?

If you’re not too familiar with Grunt or maybe you’ve only skimmed the docs and not got your hands dirty with it then here’s a quick intro.

Grunt has over 4000 packages capable of everything from basic shell commands to test automation, web serving, image optimisation, CSS and JS minification and loads more. Check out the Grunt plugins page for a full listing and to get inspiration for what you can automate in your own Magento development process.

At Develo Design, we have our own Magento 1.x Grunt file which we keep updated and tweak per project and if you’re impatient to see then jump past the list to the title below. We customise it and tweak it depending on individual cases, but it remains largely the same.

  • Here are just a few ideas of what Grunt can do to streamline your Magento development:
  • Lint and test your custom JS/PHP/CSS on any file changes.
  • Automate javascript minification.
  • Automate Sass compilation.
  • Check your local PHP code pool for style guide compliance.
  • Force linting of the entire project before a git commit (slight cheat here – as this is a Grunt plugin that generates githook to run your tasks).
  • Minify/Uglify JS.
  • Minify/Optimise template images.
  • Get the latest copy of your staging server database with deployments.

Develo’s Template Gruntfile.js

/**
* @description Gruntfile template for managing sites workflow
*
* @copyright Develo Design Ltd. 2014-2015
* @author Doug Bromley <doug@develo.krizantos.com>
*/
module.exports = function (grunt) {
    'use strict';
 
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        db: grunt.file.readJSON('localdb.json'),
        /**
         * Edit these values for your project
         */
        namespace: 'PHP LOCAL POOL DIR',
        project: 'PROJECTNAME',
        themePath: 'YOUR/THEME/',
        /**
         * Auto install all bower packages
         */
        auto_install: {
            skin: {
                options: {
                    cwd: 'skin/frontend/<%= project %>/default',
                    stdout: true,
                    stderr: true,
                    failOnError: true,
                    npm: false,
                    bower: true
                }
            }
        },
        /**
         * Clean Magento cache
         */
        clean: {
            options: {
                force: true
            },
            cache: {
                src: ['var/cache/*']
            },
            sass: {
                src: ['skin/frontend/<%= project %>/default/.sass-cache/*']
            }
        },
        /**
         * One of th most useful plugins we've used enabling us to
         * push or pull a Magento database renaming the URL as it goes.
         */
        deployments: {
            options: {
                backups_dir: '../'
            },
            local: {
                'title': 'Local MySQL Server',
                'database': '<%= db.database %>',
                'user': '<%= db.user %>',
                'pass': '<%= db.pass %>',
                'host': '<%= db.host %>',
                'url': '<%= db.url %>'
            },
            remote: {
                'title': 'Staging Server',
                'database': 'REMOTEDB',
                'user': 'REMOTEDBUSER',
                'pass': 'REMOTEDBPASS',
                'host': 'localhost',
                'url': 'REMOTEURL',
                'ssh_host': 'root@ip.address'
            }
        },
        /**
         * Running grunt githooks will insert the phplint and sass
         * tasks into your Git commint hooks. Very useful to stop you
         * comitting anything obviously breaking.
         */
        githooks: {
            all: {
                'pre-commit': 'phplint',
                'post-commit': 'sass'
            }
        },
        jshint: {
            options: {
                reporter: require('jshint-stylish')
            },
            grunt: {
                src: 'Gruntfile.js'
            },
            skin: {
                src: [
                    'skin/frontend/<%= project %>/default/js/all.js',
                    'skin/frontend/<%= project %>/default/js/pages/*.js',
                    'skin/frontend/<%= project %>/default/js/plugins/develo-slide-tabs.js',
                ]
            }
        },
        /**
         * Run PHPCS on all local and community extensions
         */
        phpcs: {
            develo: {
                dir: ['app/code/local/<%= namespace %>/**/*.php']
            },
            local: {
                dir: ['app/code/local/**/*.php']
            },
            community: {
                dir: ['app/code/community/**/*.php']
            },
            options: {
                bin: '/usr/local/bin/phpcs',
                standard: 'Zend'
            }
        },
        /**
         * Basic PHP lint of all local and community code pools
         */
        phplint: {
            local: {
                files: [{
                    expand: true,
                    cwd: 'app/code/local/',
                    src: ['**/*.php']
                }]
            },
            community: {
                files: [{
                    expand: true,
                    cwd: 'app/code/community/',
                    src: ['**/*.php']
                }]
            },
            design: {
                files: [{
                    expand: true,
                    cwd: 'app/design/frontend/<%= project %>/default/template/',
                    src: ['**/*.phtml']
                }]
            }
        },
        /**
         * Process our Sass files
         */
        sass: {
            dist: {
                files: {
                    'skin/frontend/<%= project %>/default/css/app.css' : 'skin/frontend/<%= project %>/default/scss/app.scss',
                    'skin/frontend/<%= project %>/default/css/checkout.css' : 'skin/frontend/<%= project %>/default/scss/checkout.scss'
                }
            }
        },
        /**
         * As well as having linting built into our IDE's and editors we
         * have a linter which runs on every default run task.
         */
        scsslint: {
            allFiles: [
                'skin/frontend/<%= project %>/default/scss/*.scss'
            ],
            options: {
                colorizeOutput: true
            }
        },
        /**
         * Processing our Illustrator provided SVGs and placing them in
         * the correct directory for use
         */
        svgmin: {
            dist: {
                expand: true,
                cwd: 'skin/frontend/<%= project %>/default/images/raw',
                src: ['*.svg'],
                dest: 'skin/frontend/<%= project %>/default/images'
            }
        },
        watch: {
            css: {
                files: 'skin/frontend/<%= project %>/default/scss/**/*.scss',
                tasks: ['sass']
            }
        }
    });
 
    grunt.loadNpmTasks('grunt-phplint');
    grunt.loadNpmTasks('grunt-phpcs');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-svgmin');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-githooks');
    grunt.loadNpmTasks('grunt-auto-install');
    grunt.loadNpmTasks('grunt-scss-lint');
    grunt.loadNpmTasks('grunt-deployments');
 
    grunt.registerTask('default', ['sass', 'watch']);
};


Getting Grunt Working On Your Magento Store

You’ll find it easier working from our existing Grunt file and tweaking it to your needs. You may all be working from with different setups, but here I’m concentrating on OSX developers and first covering the basic precursors. Skip any you’ve already done.

Install NodeJS and NPM from the NodeJS site then install Grunt:

npm install -g grunt-cli

cd to your Magento’s root folder.

Grab the package.json, localdb.json and Gruntfile.js from Develo’s online repo

wget https://raw.githubusercontent.com/develodesign/Magento-Gruntfile/master/Gruntfile.js
wget https://raw.githubusercontent.com/develodesign/Magento-Gruntfile/master/localdb.json

To install all the packages this Grunt file (assuming you’re using the Develo one) will need:

npm install

After that’s finished you can test your Grunt file out by running one of these commands (others may need tweaking for your project):

grunt clean
grunt phplint:local

# if you want the githooks functionality run

grunt githooks

Now be sure to check out the Grunt file and tweaking the paths and packages to your requirements.

If you ever want to know what commands are available to your Grunt setup simply run the command

grunt --help

The Possibilities are Endless

This article merely scrapes the surface of what Grunt is capable of doing for your Magento development. Just skimming through the available Grunt plugins it would be possible to:

  • Backup and restore your Magento database
  • Run arbitrary SQL on your DB
  • Run vagrant commands to your Vagrant box without first SSH’ing in.
  • Compile any number of CSS pre-processors

Check out Develo Grunt file on Github

If you enjoyed this article, read the other Blog articles from our Magento agency or browse the site to see what else we do with Adobe Commerce, PunchOut Catalog and more.

Get in touch for help with your latest Magento or eCommerce project.


...
Luke

share:

Ready to start your next project?

See how we can help you accelerate your business