What Does It Mean To Modernize?

Modernizing has a different meaning to each person. A manager might think it means switching to agile. A sales associate might consider it to be updating to the latest POS system. As a developer (or code hobbyist), it probably means to adopt automation and abstraction.

Grunt and Bower are two command-line utilities for automating tasks and dependency management, respectively.

With a few simple commands, they will install all dependencies, concatenate your files, minify the contents, and so much more.

How Do Grunt and Bower Help You?

Quite simply. They take the grunt work out of your work flow. Grunt can be expanded to run various tasks, which can be installed, used in conjunction with each other, and with custom parameters. It’s basically like a robot assistant that’ll do what you program it to.

Bow out of updating your third-party libraries by hand. Bower will download the libraries you use and update them for you. All you need to do is specify what version you want (or let Bower decide).

Installing Node

the node logo in three different colors

Node is a native utility that allows you to write server-side JavaScript. It’s been a huge hit since its release and gave way for many native JavaScript apps. Because of its versatility, tools like Grunt and Bower became possible.

If you’re a Mac or Windows user, you’re lucky to have installers provided by the Node Foundation.

Else, if you run some sort of Linux distro, you can find instructions online. Ubuntu users have this.

Check that node works with

  # each command should show the version number
  node -v
  npm -v

NPM is the utility for the Node Package Manager, which manages all your local and global node modules.

Note: On Linux distros, it may be necessary to run Node commands with root privileges. Simply prepend sudo whenever you call node and npm.

Setting Up Your package.json

The NPM knows what packages you need using a package.json file from your execution root. So, it doesn’t need to be anywhere, just in the same directory when you install your package dependencies.

You can generate one using npm init which runs you through some questions to setup a custom package.json.

Here’s a sample package.json

  {
    "name": "my_project",
    "version": "1.0.0",
    "dependencies": {
      "express": "4.13.3"
    },
    "devDependencies": {
      "grunt": "^0.4.5",
      "grunt-bower-install": "~1.0.0",
      "jshint-stylish": "~0.1.3",
      "load-grunt-tasks": "~0.4.0"
    },
    "engines": {
      "node": ">=0.10.0"
    },
    "scripts": {
      "test": "grunt test"
    }
  }

You do the installation with,

  # install all the packages in your package.json
  npm install

Setting Up Grunt

the grunt logo

Grunt is a task-runner, meaning it runs operations written in JavaScript. This is made possible with the magic that is Node (woo).

To start using it, you need to install a commandline package globally. Do that with,

  # the -g flag indicates a global install
  npm install -g grunt-cli

Then, in the same directory as your package.json, run

  # the flag used saves grunt as a developer-only dependency in your package.json
  npm install grunt --save-dev

All Grunt tasks are specifies in a Gruntfile.

Here’s a sample Gruntfile.js:

  // this is node syntax. modules take after their file name and
// their properties are defined in exports
module.exports = function(grunt){
  // define grunt config settings
  grunt.initConfig({
    // define variables, which are regular json files
    // the readJSON function just 'imports' the JSON
    pkg: grunt.file.readJSON('package.json'),
    dir: grunt.file.readJSON('master.json'),

    // this defines a task named 'concat'
    concat: {
      // Grunt tasks have an 'options' property
      options: {
        separator: ''
      },

      // specify the file types that will be concatenated
      js: {
        src: ['<%= dir.sitePath %>/scripts/**/*.js'],
        dest: '<%= dir.sitePath %>/dist/js/<%= pkg.name %>.js'
      },
      css: {
        src: ['<%= dir.sitePath %>/styles/**/*.css'],
        dest: '<%= dir.sitePath %>/dist/css/<%= pkg.name %>.css'
      }
    },

    // specify a task that lints your JavaScript
    jshint: {
      all: ['Gruntfile.js', '<%= dir.sitePath %>/scripts/**/*.js']
    },

    // specify a task that watches for changes in the specified files
    watch : {
      options: {
        livereload: true,
      },
      files: ['<%= dir.sitePath %>/styles/*.less',
              '<%= dir.sitePath %>/scripts/**/*.js',
              'Gruntfile.js'],
      tasks: ['less'] //these tasks will run when a change happens
    }
  });

  //register grunt tasks by loading their Npm module
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');

  //register composite tasks
  grunt.registerTask('build', ['jshint', 'concat']);
};

You can run the task by name with

  # replace the <task-name> with the task you want to run, like 'watch'
  grunt <task-name>

Read more on Grunt on its official website.

Setting up Bower

the bower logo

Bower manages your dependencies and a little more than that. Get started with it by installing via npm,

Bower keeps track of its dependencies in a bower.json file.

Like with the package.json, you can get a basic bower.json with bower init.

As always, here’s a sample bower.json

  {
    "name": "my_site",
    "version": "1.0.0",
    "dependencies": {
      "json3": "~3.2.6",
      "es5-shim": "~2.1.0",
      "jquery": "~2.1.4",
      "bootstrap": "~3.3.5"
    }
  }

Install libraries with the install command,

  # installs jquery
  bower install jquery

You can even search for libraries with the search command,

  # this prints out a list of libraries with the given keywords
  bower search

The location Bower installs libraries is specified by the .bowerrc.

The contents are only a relative directory, like /public/libs.

Bonus: Integration with Jekyll

I’m pleased to say that Jekyll, Grunt, and Bower play remarkably well together!

In fact, generated changes to the Grunt watched files trigger a regeneration on Jekyll’s end!

It makes for a nice flow.

an approving gif

References

web node automation