This project is deprecated in lieu of the more evolved gulp-commonjs-tasks. For future projects please use gulp-commonjs-tasks.
Gulp tasks as CommonJS modules
Because large gulpfiles are a pain, CommonJS modules are fine for managing gulp tasks.
- Gulp tasks as CommonJS modules.
- Pass as many arguments as you need to your modules.
- Built-in run-sequence for more fine grained control over sequences.
- Anonymous dependencies and sequences, no need to create a gulp task for every dependend or sequenced task.
- Inheritance of optional task params.
- Self documenting tasks on the command line.
- Plays well with gulp-load-plugins.
Install gulp
and gulp-cjs-tasks
dependencies.
$ npm install --save-dev gulp gulp-cjs-tasks
Here's an example of your regular average gulpfile with some arbitrary tasks, a help task and a default task.
// ./examples/straight-gulp/gulpfile.js
var gulp = require('gulp');
gulp.task('first-task', function (done) {
done();
});
gulp.task('second-task', function (done) {
done();
});
var help = {
'first-task': 'My first task',
'second-task': 'My second task'
};
gulp.task('help', function () {
Object.keys(help).map(function (taskName) {
console.log(taskName + ' ' + help[taskName]);
});
});
gulp.task('default', ['help']);
Let's try create the same with a CommonJS module.
Create a gulpfile.js
file and add the following:
// ./examples/commonjs/gulpfile.js
var gulp = require('gulp');
var taskLoader = require('gulp-cjs-tasks/task-loader');
// load tasks
var tasksContext = taskLoader.load('./tasks', gulp);
// Add the gulp help task
tasksContext.addHelpTask();
Now let's create a module in ./tasks
and call it simple.js
// ./examples/commonjs/tasks/simple.js
module.exports = function (gulp) {
var tasks = {
'first-task': {
fn: firstTask,
description: 'My first task'
},
'second-task': {
fn: secondTask,
description: 'My second task'
}
};
return tasks;
function firstTask(done) {
done();
}
function secondTask(done) {
done();
}
};
The CommonJS module above returns a function which takes in the gulp
object as an argument. This argument is needed to access gulp tasks in other task files. It is not mandatory, but if you'd like to use gulp.src()
for instance, you need it.
[gulp-cjs-tasks-examples] cd examples/straight-gulp
[straight-gulp] gulp
[07:08:10] Using gulpfile ~/temp/gulp-cjs-tasks-examples/examples/straight-gulp/gulpfile.js
[07:08:10] Starting 'help'...
first-task My first task
second-task My second task
[07:08:10] Finished 'help' after 156 ÎĽs
[07:08:10] Starting 'default'...
[07:08:10] Finished 'default' after 7.22 ÎĽs
[gulp-cjs-tasks-examples] cd examples/commonjs
[commonjs] gulp
[07:06:08] Using gulpfile ~/gulp-cjs-tasks-examples/examples/commonjs/gulpfile.js
[07:06:08] Starting 'help'...
help Usage
gulp task [ option ... ]
Tasks
help : Show help
-a, --all : Also show tasks without descriptions
first-task : My first task
second-task : My second task
[07:06:08] Finished 'help' after 1.87 ms
[07:06:08] Starting 'default'...
[07:06:08] Finished 'default' after 17 ÎĽs
Passing arguments to each gulp task module is easy.
In our gulp file we'll pass on defaults
and moreDefaults
.
// ./examples/passing-multiple-arguments/gulpfile.js
var gulp = require('gulp'),
path = require('path');
var taskLoader = require('gulp-cjs-tasks/task-loader');
var defaults = {
foo: 'foo!',
bar: 'bar!'
};
var moreDefaults = {
snafu: 'snafu!',
pebkac: 'pebkac!'
};
var tasks = taskLoader.load(path.resolve(__dirname, 'tasks'), gulp, defaults, moreDefaults);
In the task module defaults
and moreDefaults
are picked up.
// ./examples/passing-multiple-arguments/tasks/multiple.js
module.exports = function (gulp, defaults, moreDefaults) {
var tasks = {
'multiple': {
fn: function () {
console.log('second argument', defaults);
console.log('third argument', moreDefaults);
}
}
};
return tasks;
};
The example above is not of much use in the real world, but passing on something like gulp-load-plugins does make sense.
We pass on gulp-load-plugins
as $
.
// ./examples/gulp-load-plugins/gulpfile.js
var gulp = require('gulp'),
path = require('path'),
$ = require('gulp-load-plugins')();
var taskLoader = require('gulp-cjs-tasks/task-loader');
var tasks = taskLoader.load(path.resolve(__dirname, 'tasks'), gulp, $);
tasks.addHelpTask();
And we use it in a task to use gulp-template
.
// ./examples/gulp-load-plugins/tasks/readme.js
module.exports = function (gulp, $) {
var tasks = {
'create-readme': {
fn: function () {
return gulp.src('./templates/README.md')
.pipe($.template({
foo: 'foo!',
bar: 'bar!'
}))
.pipe(gulp.dest('./'));
},
description: 'Create readme file'
}
};
return tasks;
};
[gulp-load-plugins] gulp create-readme
[11:39:38] Using gulpfile ~/temp/gulp-cjs-tasks-examples/examples/gulp-load-plugins/gulpfile.js
[11:39:38] Starting 'create-readme'...
[11:39:38] Finished 'create-readme' after 71 ms
[gulp-load-plugins] cat README.md
# My read me
Foo : foo!
Bar : bar!
Our gulp file
// ./examples/external-defaults/gulpfile.js
var gulp = require('gulp'),
path = require('path');
var taskLoader = require('gulp-cjs-tasks/task-loader');
var defaults = require('./defaults.json');
var currentTasks = taskLoader.load(path.resolve(__dirname, 'tasks'), gulp, defaults);
currentTasks.addHelpTask();
A bit of json containing the defaults
// ./examples/external-defaults/defaults.json
{
"foo": "Foo value",
"bar": "Bar value"
}
Our task module
// ./examples/external-defaults/tasks/external.js
module.exports = function (gulp, defaults) {
var tasks = {
'external': {
fn: function () {
console.log('External defaults', defaults);
},
description: 'Displays external defaults'
}
};
return tasks;
};
Let's take a closer look at the gulp.task
function.
gulp.task('second', ['first'], function (done){
console.log('second');
done();
});
gulp.task('first', function (done) {
console.log('first');
done();
});
If we run task second
, then task first
will be executed first.
In our module format we add a dep
property to provide the same functionality.
// ./examples/dependencies/tasks/dependencies.js
module.exports = function (gulp) {
var tasks = {
'first': {
fn: firstTask,
description: 'My first task'
},
'second': {
dep: ['first'],
fn: secondTask,
description: 'My second task'
}
};
return tasks;
function firstTask(done) {
done();
}
function secondTask(done) {
done();
}
};
Instead of creating a task for every dependency we can also reference functions.
// ./examples/dependency-referencing/tasks/dependencies.js
module.exports = function (gulp) {
var tasks = {
'second': {
dep: [firstTask, 'otherTask', function () {
console.log('anonymous task');
}],
fn: lastTask,
description: 'My second task'
},
'otherTask': {
fn: otherTask
}
};
return tasks;
function firstTask(done) {
console.log('firstTask');
done();
}
function lastTask(done) {
console.log('lastTask');
done();
}
function otherTask(done) {
console.log('other task');
done();
}
};
I don't know about you but if you want to have some control of when tasks will be executed you'll end up using something like run-sequence
to avoid the mess of chaining tasks together.
Using run-sequence we can run tasks in sequence rather than all at once before running a task.
Here we have three tasks which are run in order by the all
task. A fn
property is not needed, but if you add it, it will executed when the sequence is done.
// ./examples/sequences/tasks/sequence.js
module.exports = function (gulp) {
var tasks = {
'first': {
fn: firstTask,
description: 'My first task'
},
'second': {
fn: secondTask,
description: 'My second task'
},
'third': {
fn: thirdTask,
description: 'My third task'
},
'all': {
seq: ['first', 'second', 'third'],
description: 'All three tasks'
},
'all-and-self': {
fn: lastTask,
seq: ['first', 'second', 'third'],
description: 'All three tasks'
}
};
return tasks;
function firstTask(done) {
done();
}
function secondTask(done) {
done();
}
function thirdTask(done) {
done();
}
function lastTask(done) {
done();
}
};
We are not bound to handing task names in the seq
array. We can also use function names or anonymous functions.
// ./examples/sequence-referencing/tasks/sequence.js
module.exports = function (gulp) {
var tasks = {
'all': {
seq: [firstTask, secondTask, thirdTask],
description: 'All three tasks'
}
};
return tasks;
function firstTask(done) {
done();
}
function secondTask(done) {
done();
}
function thirdTask(done) {
done();
}
};
We can also mix the type of objects a sequence array can take.
// ./examples/sequence-mixed-referencing/tasks/sequence.js
module.exports = function (gulp) {
var tasks = {
'first': {
fn: firstTask,
description: 'My first task'
},
'all': {
fn: lastTask,
seq: ['first', secondTask, function(done){
done();
}],
description: 'All three tasks'
}
};
return tasks;
function firstTask(done) {
done();
}
function secondTask(done) {
done();
}
function lastTask(done) {
done();
}
};
As you probably have noticed by now, you can add a description
property for every task. It can be used by the help task to provide some valuable information of what the task should do.
// ./examples/description/tasks/description.js
module.exports = function (gulp) {
var tasks = {
'info': {
fn: firstTask,
description: 'Shows info about this task'
},
'second-task': {
fn: secondTask,
description: 'Shows info about the second task',
options: {
'-f, --foo': 'Some stuff'
}
}
};
return tasks;
function firstTask(done) {
done();
}
function secondTask(done) {
done();
}
};
We can also add optional command line parameters. Handling these are your own responsibility, a simple way is using gulp-util's env
property.
Tasks with sequences or dependencies will inherit the optional parameters when calling the help task.
// ./examples/options/tasks/options.js
module.exports = function (gulp) {
var gutil = require('gulp-util');
var tasks = {
'first': {
fn: firstTask,
description: 'Shows info about this task',
options: {
'-f, --foo': 'Foo option'
}
},
'second': {
fn: secondTask,
description: 'Show info about the second task',
options: {
'-b, --bar': 'Bar option'
}
},
'third': {
fn: thirdTask,
seq: ['first', 'second'],
description: 'Info about third task',
options: {
'-s, --snafu': 'Snafu option'
}
},
'fourth': {
fn: fourthTask,
dep: ['third'],
description: 'Info about fourth task',
options: {
'-p, --pebkac': 'Pebkac option'
}
}
};
return tasks;
function firstTask() {
var option = gutil.env.f || gutil.env.foo;
console.log('first option: f/foo', option);
}
function secondTask() {
var option = gutil.env.b || gutil.env.bar;
console.log('second option: b/bar', option);
}
function thirdTask() {
var option = gutil.env.s || gutil.env.snafu;
console.log('third option: s/snafu', option);
}
function fourthTask() {
var option = gutil.env.p || gutil.env.pebkac;
console.log('fourth option: p/pebkac', option);
console.log('All options', gutil.env);
}
};
[19:35:22] Starting 'help'...
help Usage
gulp task [ option ... ]
Tasks
help : Show help
-a, --all : Also show tasks without descriptions
first : Shows info about this task
-o, --option : Some option
second : Show info about the second task
-m, --more : Another option
third : Info about third task
-o, --option : Some option
-m, --more : Another option
-e, --evenmore : And another option
fourth : Info about fourth task
-e, --evenmore : And another option
-o, --option : Some option
-m, --more : Another option
-f, --foo : And another option
var cjsTasks = require('gulp-cjs-tasks');
var taskLoader = cjsTasks.taskLoader;
var taskInfo = cjsTasks.taskInfo;
You can also retrieve this object directly.
var taskLoader = require('gulp-cjs-tasks/task-loader');
The return value of taskLoader.load()
is an object which contains the following keys.
{
taskNames: [ list of task names ],
defaultTaskNames: [ list of default task names ],
addHelpTask: [ adds a help task ],
taskTree: [Function: returns all tasks ],
cliHelp: [Function: returns formatted help string ]
}
You can also retrieve this object directly.
var taskInfo = require('gulp-cjs-tasks/task-info');
{
cliHelp: [Function: returns formatted help string ],
taskTree: [Function: returns all tasks ]
}
{
a : [ boolean: wether or not to display tasks without descriptions ],
all : [ boolean: wether or not to display tasks without descriptions ]
}
Returns flattened tree of all tasks.