volo and grunt

jrburke edited this page Aug 2, 2012 · 2 revisions

volo and grunt

volo and grunt provide project automation tools, using JavaScript and Node. They have some overlapping functionality, but they can be used together.

The most common way is to probably to leverage the volo create, add, search commands in a grunt task. The grunt-volo allows using volo inside grunt for these kinds of operations. Or, use volo on its own to pull down a project template that uses grunt internally, then use volo to fetch dependencies for that project.

Where grunt and volo can do a similar task, they differ in some ways. These differences are mostly stylistic, not really right or wrong. Both end up providing a way to do project automation.

The main thing: if you are already productive and comfortable in one of the tools, there is little reason for you to change. The larger goals of these tools are to make you more efficient, and if you reached that goal, then the job has been done.



GitHub is already used to share code with others, so volo wants to use it for bootstrapping front end projects. It should be possible to install project templates and code dependencies by using references to GitHub- hosted code.

For local project automation, use node as the script driver. Since node is used, it is best to go with the grain of node and use npm to install packages of reusable automation pieces.

Automating these pieces should be similar to using a Makefile or shell script, but something that works on Windows without needing to install Unix tools. Many of the packages in Node already have a command line interface, best to just use that, in a way that works on Windows too.

It should be easy to code up a local automation command with JavaScript, and have some helpers to make the default async style of node javascript easier to use for project automation.


grunt is targeted for local project automation that can reuse automation pieces through npm. It prefers to hide the async nature of node JS code by providing automation pieces a set of APIs to accept JS objects for declarative configuration, and provide more of an API around bridging what a developer might code in a local project's gruntfile and how the automation piece plugs in to that system.

It also comes with some commonly needed tasks for front end projects, like linting and minifying. This means by default grunt helps enforce a particular development style that has come from a set of good practices.


Both use a local project files (volofile for volo and gruntfile for grunt) to wire up automation commands for the local project. Both can reuse code via npm-installed modules.


Starting a new project

volo: volo create fetches project template from GitHub. Project templates can implement an 'onCreate' command in their volofile to do project logic as part of creating a new project.

grunt: uses an init command that uses local grunt script files to generate a new template. You can add new templates by placing a new init script at a specific location on your disk.

summary: volo reaches out to github, grunt relies on the local file system. volo does not use a local cache, but there has been talk of using one in case the network is not available.

volofile/gruntfile construction

volo: wants to use existing npm-published packages and then call out to their "bin" utilities that run on the command line in a way that works on Windows. Favor local node_modules installed versions over any global installed ones. The ideal volofile looks like this.

For coding up local commands that are not reusable across projects or do more work than just call out to command line utilities with project-specific values, inline a command in the volofile that has this structure.

All the commands available are listed explicitly in the volofile, with the ability to reuse commands by just require()ing them in, and passing any config as part of of that call. The [volo-appcache](https://github.com/volojs/volo- appcache) command show an example of this.

grunt: usually has an adapter module that is published via npm that will bridge the declarative configuration in the grunt file to the existing npm- published package, normally favoring calling the existing npm package via its JS API rather than its "bin" utility.

Here is the grunt "lint" task that bridges to jshint and here is how "lint" is used in a gruntfile.

For coding up local tasks that are not reusable across projects, tasks can be registered inline in the gruntfile. See the jquery gruntfile for examples.

Commands can be registered in chunks via [grunt.loadTasks](https://github.com/co wboy/grunt/blob/master/docs/api.md#gruntloadtasks-%E2%9A%91) and [grunt.loadNpmT asks](https://github.com/cowboy/grunt/blob/master/docs/api.md#gruntloadnpmtasks- %E2%9A%91).

The config section for tasks [grunt.initConfig](https://github.com/cowboy/grunt/ blob/master/docs/api.md#gruntinitconfig-%E2%9A%91) and the task registration are done as separate calls in the gruntfile, since reusuable tasks are loaded in groups via the load calls specified above. An example from the jQuery gruntfile.

summary: grunt can load a few commands at once without explicitly mentioning each task. Config is done separate from task loading, via JS object configuration passing. volo requires an explicit mention of each task, but allows for config to be passed as part of task loading, and prefers to use commands that have a command line interface.

Built in commands/tasks

volo: built in commands are mostly about fetching front-end code from GitHub.

grunt: built in tasks are focused on common front-end tasks: project init from from local templates, linting, minification, file concatenation, test running, local server and file watching.

summary: volo's built in commands are more about starting new projects and getting dependencies from the network, and grunt's built in tasks are more about doing the common dev tasks once you have the project set up locally.

Possible areas of improvement

volo: it favors just calling out to command line utilities. While this works in the basic case on Windows, more complex layering of tasks may not work out as well.

volo would do well to have a local cache of project templates and dependencies that the user has installed before from GitHub because the user is like to want to use them again. It would be good to have some robustness in case the network is not available.

grunt: it would be nice to reduce the amount of indirection. Tie task loading directly to the config needed for that task.

By requiring adapter modules that take grunt configs and convert them to the API used by an underlying npm-installed package, it may be harder to scale those adapters and keep them current with changes in the underyling modules.

The bulk loading of tasks from roll-up grunt packages may mean that projects get more tasks that can run against them but may not make sense for the particular project.


Both volo and grunt can do automation. A sentence to describe the shape of each one:

volo: GitHub/network-based for project bootstrapping, local automation that favors calling out to npm-installed command line utilities.

grunt: local project bootstrapping, built in commands for common local automation, which favor using JS object configuration for npm-installed tasks.