For a more comprehensive read on streams, check out the “Stream Handbook.”
The gulp.src() function takes a glob (i.e. a string matching one or more files) or an array of globs and returns a stream that can be piped to plugins.
Gulp uses node-glob to get the files from the glob or globs you specify. It’s easiest to explain using examples:
js/app.jsjs/*.js.js in the js directory onlyjs/**/*.js.js in the js directory and all child directories!js/app.jsjs/app.js from the match, which is useful if you want to match all files in a directory except for a particular file*.+(js|css).js or .cssOther features are available, but they’re not commonly used in Gulp. Check out out the Minimatch documentation for more.
Let’s say that we have a directory named js containing JavaScript files, some minified and some not, and we want to create a task to minify the files that aren’t already minified. To do this, we match all JavaScript files in the directory and then exclude all files ending in .min.js:
gulp.src(['js/**/*.js', '!js/**/*.min.js'])
To define a task, use the gulp.task() function. When you define a simple task, this function takes two attributes: the task’s name and a function to run.
gulp.task('greet', function () {
console.log('Hello world!');
});
Running gulp greet will result in “Hello world” being printed to the console.
A task may also be a list of other tasks. Suppose we want to define a build task that runs three other tasks, css, js and imgs. We can do this by specifying an array of tasks, instead of the function:
gulp.task('build', ['css', 'js', 'imgs']);
These will be run asynchronously, so you can’t assume that the css task will have finished running by the time js starts — in fact, it probably won’t have. To make sure that a task has finished running before another task runs, you can specify dependencies by combining the array of tasks with the function. For example, to define a css task that checks that the greet task has finished running before it runs, you can do this:
gulp.task('css', ['greet'], function () {
// Deal with CSS here
});
Now, when you run the css task, Gulp will execute the greet task, wait for it to finish, and then call the function that you’ve specified.
You can define a default task that runs when you just run gulp. You can do this by defining a task named default.
gulp.task('default', function () {
// Your default task
});
You can use a number of plugins — over 600, in fact — with Gulp. You will find them listed on the plugins page or by searching gulpplugin on npm. Some plugins are tagged “gulpfriendly”; these aren’t plugins but are designed to work well with Gulp. Be aware when searching directly on npm that you won’t be able to see whether a plugin has been blacklisted (scrolling to the bottom of the plugins page, you will see that many are).
Most plugins are pretty easy to use, have good documentation and are run in the same way (by piping a stream of file objects to it). They’ll then usually modify the files (although some, such as validators, will not) and return the new files to be passed to the next plugin.
Let’s expand on our js task from earlier:
var gulp = require('gulp'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat');
gulp.task('js', function () {
return gulp.src('js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(uglify())
.pipe(concat('app.js'))
.pipe(gulp.dest('build'));
});
We’re using three plugins here, gulp-jshint, gulp-uglify and gulp-concat. You can see in the README files for the plugins that they’re pretty easy to use; options are available, but the defaults are usually good enough.
You might have noticed that the JSHint plugin is called twice. That’s because the first line runs JSHint on the files, which only attaches a jshint property to the file objects without outputting anything. You can either read the jshint property yourself or pass it to the default JSHint reporter or to another reporter, such as jshint-stylish.
The other two plugins are clearer: the uglify() function minifies the code, and the concat('app.js') function concatenates all of the files into a single file named app.js.
A module that I find really useful is gulp-load-plugins, which automatically loads any Gulp plugins from your package.json file and attaches them to an object. Its most basic usage is as follows:
var gulpLoadPlugins = require('gulp-load-plugins'),
plugins = gulpLoadPlugins();
You can put that all on one line (var plugins = require('gulp-load-plugins')();), but I’m not a huge fan of inline require calls.
After running that code, the plugins object will contain your plugins, camel-casing their names (for example, gulp-ruby-sass would be loaded to plugins.rubySass). You can then use them as if they were required normally. For example, our js task from before would be reduced to the following:
var gulp = require('gulp'),
gulpLoadPlugins = require('gulp-load-plugins'),
plugins = gulpLoadPlugins();
gulp.task('js', function () {
return gulp.src('js/*.js')
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('default'))
.pipe(plugins.uglify())
.pipe(plugins.concat('app.js'))
.pipe(gulp.dest('build'));
});
This assumes a package.json file that is something like the following:
{
"devDependencies": {
"gulp-concat": "~2.2.0",
"gulp-uglify": "~0.2.1",
"gulp-jshint": "~1.5.1",
"gulp": "~3.5.6"
}
}
In this example, it’s not actually much shorter. However, with longer and more complicated Gulp files, it reduces a load of includes to just one or two lines.
Version 0.4.0 of gulp-load-plugins, released in early March, added lazy plugin loading, which improves performance. Plugins are not loaded until you call them, meaning that you don’t have to worry about unused plugins in package.json affecting performance (although you should probably clean them up anyway). In other words, if you run a task that requires only two plugins, it won’t load all of the plugins that the other tasks require.
Gulp has the ability to watch files for changes and then run a task or tasks when changes are detected. This feature is amazingly useful (and, for me, probably Gulp’s single most useful one). You can save your LESS file, and Gulp will turn it into CSS and update the browser without your having to do anything.
To watch a file or files, use the gulp.watch() function, which takes a glob or array of globs (the same as gulp.src()) and either an array of tasks to run or a callback.
Let’s say that we have a build task that turns our template files into HTML, and we want to define a watch task that watches our template files for changes and runs the task to turn them into HTML. We can use the watch function as follows:
gulp.task('watch', function () {
gulp.watch('templates/*.tmpl.html', ['build']);
});
Now, when we change a template file, the build task will run and the HTML will be generated.
You can also give the watch function a callback, instead of an array of tasks. In this case, the callback would be given an event object containing some information about the event that triggered the callback:
gulp.watch('templates/*.tmpl.html', function (event) {
console.log('Event type: ' + event.type); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
});
Another nifty feature of gulp.watch() is that it returns what is known as a watcher. Use the watcher to listen for additional events or to add files to the watch. For example, to both run a list of tasks and call a function, you could add a listener to the change event on the returned watcher:
var watcher = gulp.watch('templates/*.tmpl.html', ['build']);
watcher.on('change', function (event) {
console.log('Event type: ' + event.type); // added, changed, or deleted
console.log('Event path: ' + event.path); // The path of the modified file
});
In addition to the change event, you can listen for a number of other events:
enderrorreadynomatchThe watcher object also contains some methods that you can call:
watcher.end()watcher (so that no more tasks or callbacks will be called)watcher.files()watcherwatcher.add(glob)watcher that match the specified glob (also, accepts an optional callback as a second argument)watcher.remove(filepath)watcherYou can get Gulp to reload or update the browser when you — or, for that matter, anything else, such as a Gulp task — changes a file. There are two ways to do this. The first is to use the LiveReload plugin, and the second is to use BrowserSync
LiveReload combines with browser extensions (including a Chrome extension) to reload your browser every time a change to a file is detected. It can be used with the gulp-watch plugin or with the built-in gulp.watch() that I described earlier. Here’s an example from the README file of the gulp-livereload repository:
var gulp = require('gulp'),
less = require('gulp-less'),
livereload = require('gulp-livereload'),
watch = require('gulp-watch');
gulp.task('less', function() {
gulp.src('less/*.less')
.pipe(watch())
.pipe(less())
.pipe(gulp.dest('css'))
.pipe(livereload());
});
This will watch all files matching less/*.less for changes. When a change is detected, it will generate the CSS, save the files and reload the browser.
An alternative to LiveReload is available. BrowserSync is similar in that it displays changes in the browser, but it has a lot more functionality.
When you make changes to code, BrowserSync either reloads the page or, if it is CSS, injects the CSS, meaning that the page doesn’t need to be refreshed. This is very useful if your website isn’t refresh-resistant. Suppose you’re developing four clicks into a single-page application, and refreshing the page would take you back to the starting page. With LiveReload, you would need to click four times every time you make a change. BrowserSync, however, would just inject the changes when you modify the CSS, so you wouldn’t need to click back.


There isn’t actually a plugin for Gulp because BrowserSync doesn’t manipulate files, so it wouldn’t really work as one. However, the BrowserSync module on npm can be called directly from Gulp. First, install it through npm:
npm install --save-dev browser-sync
Then, the following gulpfile.js will start BrowserSync and watch some files:
var gulp = require('gulp'),
browserSync = require('browser-sync');
gulp.task('browser-sync', function () {
var files = [
'app/**/*.html',
'app/assets/css/**/*.css',
'app/assets/imgs/**/*.png',
'app/assets/js/**/*.js'
];
browserSync.init(files, {
server: {
baseDir: './app'
}
});
});
Running gulp browser-sync would then watch the matching files for changes and start a server that serves the files in the app directory.
The developer of BrowserSync has written about some other things you can do in his BrowserSync + Gulp repository.
As mentioned, Gulp is one of quite a few build tools available in JavaScript, and other build tools not written in JavaScript are available, too, including Rake. Why should you choose Gulp?
The two most popular build tools in JavaScript are Grunt and Gulp. Grunt was very popular in 2013 and completely changed how a lot of people develop websites. Thousands of plugins are available for it, doing everything from linting, minifying and concatenating code to installing packages using Bower and starting an Express server. This approach is pretty different from Gulp’s, which has only plugins to perform small individuals tasks that do things with files. Because tasks are just JavaScript (unlike the large object that Grunt uses), you don’t need a plugin; you can just start an Express server the normal way.
Grunt tasks tend to be over-configured, requiring a large object containing properties that you really wouldn’t want to have to care about, while the same task in Gulp might take up only a few lines. Let’s look at a simple gruntfile.js that defines a css task to convert our LESS to CSS and then run Autoprefixer on it:
grunt.initConfig({
less: {
development: {
files: {
"build/tmp/app.css": "assets/app.less"
}
}
},
autoprefixer: {
options: {
browsers: ['last 2 version', 'ie 8', 'ie 9']
},
multiple_files: {
expand: true,
flatten: true,
src: 'build/tmp/app.css',
dest: 'build/'
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.registerTask('css', ['less', 'autoprefixer']);
Compare this to the gulpfile.js file that does the same:
var gulp = require('gulp'),
less = require('gulp-less'),
autoprefix = require('gulp-autoprefixer');
gulp.task('css', function () {
gulp.src('assets/app.less')
.pipe(less())
.pipe(prefix('last 2 version', 'ie 8', 'ie 9'))
.pipe(gulp.dest('build'));
});
The gulpfile.js version is considerably more readable and smaller.
Because Grunt hits the file system far more often than Gulp, which uses streams, Gulp is nearly always much faster than Grunt. For a small LESS file, the gulpfile.js file above would usually take about 6 milliseconds. The gruntfile.js would usually take about 50 milliseconds — more than eight times longer. This is a tiny example, but with longer files, the amount of time increases significantly.
(ds, al, ml)
Source Article from http://www.smashingmagazine.com/2014/06/11/building-with-gulp/