JavaScript
Article

An Introduction to Gulp.js

By Craig Buckler

This article was sponsored by New Relic. It was updated in January, 2017, to reflect the current state of Gulp and Gulp plugins. Thank you for supporting the sponsors who make SitePoint possible!

This article was peer reviewed by Giulio Mainardi and Tim Severien. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

Developers spend precious little time coding. Even if we ignore irritating meetings, much of the job involves basic tasks which can sap your working day:

  • generating HTML from templates and content files
  • compressing new and modified images
  • compiling Sass to CSS code
  • removing console and debugger statements from scripts
  • transpiling ES6 to cross-browser-compatible ES5 code
  • code linting and validation
  • concatenating and minifying CSS and JavaScript files
  • deploying files to development, staging and production servers

Tasks must be repeated every time you make a change. You may start with good intentions but the most infallible developer will forget to compress an image or two. Over time, pre-production tasks become increasingly arduous and time-consuming; you’ll dread the inevitable content and template changes. It’s mind-numbing, repetitive work. Would it be better to spend your time on more profitable jobs?

If so, you need a task runner or build process.

That Sounds Scarily Complicated!

Creating a build process will take time. It’s more complex than performing each task manually but, over the long-term, you will save hours of effort, reduce human error and save your sanity. Adopt a pragmatic approach:

  • automate the most frustrating tasks first
  • try not to over-complicate your build process; an hour or two is more than enough for the initial set-up
  • choose task runner software and stick with it for a while. Don’t switch to another option on a whim.

Some of the tools and concepts may be new to you but take a deep breath and concentrate on one thing at a time.

Task Runners: the Options

Build tools such as GNU Make have been available for decades but web-specific task runners are a relatively new phenomenon. The first to achieve critical mass was Grunt – a Node.js task runner which used plug-ins controlled (originally) by a JSON configuration file. Grunt was hugely successful but there were a number of issues:

  1. Grunt required plug-ins for basic functionality such as file watching.
  2. Grunt plug-ins often performed multiple tasks which made customisation more awkward.
  3. JSON configuration could become unwieldy for all but the most basic tasks.
  4. Tasks could run slowly because Grunt saved files between every processing step.

Many issues were addressed in later editions but Gulp had already arrived and offered a number of improvements:

  1. Features such as file watching were built-in.
  2. Gulp plug-ins were (mostly) designed to do a single job.
  3. Gulp used JavaScript configuration code which was less verbose, easier to read, simpler to modify, and provided better flexibility.
  4. Gulp was faster because it uses Node.js streams to pass data through a series of piped plug-ins. Files were only written at the end of the task.

Of course, Gulp itself isn’t perfect and new task runners such as Broccoli.js, Brunch and webpack have also been competing for developer attention. More recently, npm itself has been touted as a simpler option. All have their pros and cons, but Gulp remains the favorite and is currently used by more than 40% of web developers.

Gulp requires Node.js but, while some JavaScript knowledge is beneficial, developers from all web programming faiths will find it useful.

What About Gulp 4?

This tutorial describes how to use Gulp 3 – the most recent release version at the time of writing. Gulp 4 has been in development for some time but remains a beta product. It’s possible to use or switch to Gulp 4 but I recommend sticking with version 3 until the final release.

Step 1: Install Node.js

Node.js can be downloaded for Windows, Mac and Linux from nodejs.org/download/. There are various options for installing from binaries, package managers and docker images – full instructions are available.

Note for Windows users: Node.js and Gulp run on Windows but some plug-ins may not install or run if they depend on native Linux binaries such as image compression libraries. One option for Windows 10 users is the new bash command-line; this solves many issues but is a beta product and could introduce alternative problems.

Once installed, open a command prompt and enter:

node -v

to reveal the version number. You’re about to make heavy use of npm – the Node.js package manager which is used to install modules. Examine its version number:

npm -v

Note for Linux users: Node.js modules can be installed globally so they are available throughout your system. However, most users will not have permission to write to the global directories unless npm commands are prefixed with sudo. There are a number of options to fix npm permissions and tools such as nvm can help but I often change the default directory, e.g. on Ubuntu/Debian-based platforms:

cd ~
mkdir .node_modules_global
npm config set prefix=$HOME/.node_modules_global
npm install npm -g

Then add the following line to the end of ~/.bashrc:

export PATH="$HOME/.node_modules_global/bin:$PATH"

and update with:

source ~/.bashrc

Step 2: Install Gulp Globally

Install Gulp command-line interface globally so the gulp command can be run from any project folder:

npm install gulp-cli -g

Verify Gulp has installed with:

gulp -v

Step 3: Configure Your Project

Note for Node.js projects: you can skip this step if you already have a package.json configuration file.

Presume you have a new or pre-existing project in the folder project1. Navigate to this folder and initialize it with npm:

cd project1
npm init

You will be asked a series of questions – enter a value or hit Return to accept defaults. A package.json file will be created on completion which stores your npm configuration settings.

Note for Git users: Node.js installs modules to a node_modules folder. You should add this to your .gitignore file to ensure they are not committed to your repository. When deploying the project to another PC, you can run npm install to restore them.

For the remainder of this article we’ll presume your project folder contains the following sub-folders:

src folder: pre-processed source files

This contains further sub-folders:

  • html – HTML source files and templates
  • images — the original uncompressed images
  • js — multiple pre-processed script files
  • scss — multiple pre-processed Sass .scss files

build folder: compiled/processed files

Gulp will create files and create sub-folders as necessary:

  • html – compiled static HTML files
  • images — compressed images
  • js — a single concatenated and minified JavaScript file
  • css — a single compiled and minified CSS file

Your project will almost certainly be different but this structure is used for the examples below.

Tip: If you’re on a Unix-based system and you just want to follow along with the tutorial, you can recreate the folder structure with the following command:

mkdir -p src/{html,images,js,scss} build/{html,images,js,css}

Step 4: Install Gulp Locally

You can now install Gulp in your project folder using the command:

npm install gulp --save-dev

This installs Gulp as a development dependency and the "devDependencies" section of package.json is updated accordingly. We will presume Gulp and all plug-ins are development dependencies for the remainder of this tutorial.

Alternative Deployment Options

Development dependencies are not installed when the NODE_ENV environment variable is set to production on your operating system. You would normally do this on your live server with the Mac/Linux command:

export NODE_ENV=production

Or on Windows:

set NODE_ENV=production

This tutorial presumes your assets will be compiled to the build folder and committed to your Git repository or uploaded directly to the server. However, it may be preferable to build assets on the live server if you want to change the way they are created, e.g. HTML, CSS and JavaScript files are minified on production but not development environments. In that case, use the --save option for Gulp and all plug-ins, i.e.

npm install gulp --save

This sets Gulp as an application dependency in the "dependencies" section of package.json. It will be installed when you enter npm install and can be run wherever the project is deployed. You can remove the build folder from your repository since the files can be created on any platform when required.

Step 4: Create a Gulp Configuration File

Create a new gulpfile.js configuration file in the root of your project folder. Add some basic code to get started:

// Gulp.js configuration
var
  // modules
  gulp = require('gulp'),

  // development mode?
  devBuild = (process.env.NODE_ENV !== 'production'),

  // folders
  folder = {
    src: 'src/',
    build: 'build/'
  }
;

This references the Gulp module, sets a devBuild variable to true when running in development (or non-production mode) and defines the source and build folder locations.

ES6 note: ES5-compatible JavaScript code is provided in this tutorial. This will work for all versions of Gulp and Node.js with or without the --harmony flag. Most ES6 features are supported in Node 6 and above so feel free to use arrow functions, let, const, etc. if you’re using a recent version.

gulpfile.js won’t do anything yet because you need to…

Step 5: Create Gulp Tasks

On it’s own, Gulp does nothing. You must:

  1. install Gulp plug-ins, and
  2. write tasks which utilize those plug-ins to do something useful.

It’s possible to write your own plug-ins but, since almost 3,000 are available, it’s unlikely you’ll ever need to. You can search using Gulp’s own directory at gulpjs.com/plugins/, on npmjs.com, or search “gulp something” to harness the mighty power of Google.

Gulp provides three primary task methods:

  • gulp.task – defines a new task with a name, optional array of dependencies and a function.
  • gulp.src – sets the folder where source files are located.
  • gulp.dest – sets the destination folder where build files will be placed.

Any number of plug-in calls are set with pipe between the .src and .dest.

Image Task

This is best demonstrated with an example so let’s create a basic task which compresses images and copies them to the appropriate build folder. Since this process could take time, we’ll only compress new and modified files. Two plug-ins can help us: gulp-newer and gulp-imagemin. Install them from the command-line:

npm install gulp-newer gulp-imagemin --save-dev

We can now reference both modules the top of gulpfile.js:

// Gulp.js configuration

var
  // modules
  gulp = require('gulp'),
  newer = require('gulp-newer'),
  imagemin = require('gulp-imagemin'),

We can now define the image processing task itself as a function at the end of gulpfile.js:

// image processing
gulp.task('images', function() {
  var out = folder.build + 'images/';
  return gulp.src(folder.src + 'images/**/*')
    .pipe(newer(out))
    .pipe(imagemin({ optimizationLevel: 5 }))
    .pipe(gulp.dest(out));
});

All tasks are syntactically similar. This code:

  1. Creates a new task named images.
  2. Defines a function with a return value which…
  3. Defines an out folder where build files will be located.
  4. Sets the Gulp src source folder. The /**/* ensures that images in sub-folders are also processed.
  5. Pipes all files to the gulp-newer module. Source files that are newer than corresponding destination files are passed through. Everything else is removed.
  6. The remaining new or changed files are piped through gulp-imagemin which sets an optional optimizationLevel argument.
  7. The compressed images are output to the Gulp dest folder set by out.

Save gulpfile.js and place a few images in your project’s src/images folder before running the task from the command line:

gulp images

All images are compressed accordingly and you will see output such as:

Using file gulpfile.js
Running 'imagemin'...
Finished 'imagemin' in 5.71 ms
gulp-imagemin: image1.png (saved 48.7 kB)
gulp-imagemin: image2.jpg (saved 36.2 kB)
gulp-imagemin: image3.svg (saved 12.8 kB)

Try running gulp images again and nothing should happen because no newer images exist.

HTML Task

We can now create a similar task which copies files from the source HTML folder. We can safely minify our HTML code to remove unnecessary whitespace and attributes using the gulp-htmlclean plug-in:

npm install gulp-htmlclean --save-dev

which is then referenced at the top of gulpfile.js:

var
  // modules
  gulp = require('gulp'),
  newer = require('gulp-newer'),
  imagemin = require('gulp-imagemin'),
  htmlclean = require('gulp-htmlclean'),

We can now create an html task at the end of gulpfile.js:

// HTML processing
gulp.task('html', ['images'], function() {
  var
    out = folder.build + 'html/',
    page = gulp.src(folder.src + 'html/**/*')
      .pipe(newer(out));

  // minify production code
  if (!devBuild) {
    page = page.pipe(htmlclean());
  }

  return page.pipe(gulp.dest(out));
});

This reuses gulp-newer and introduces a couple of concepts:

  1. The [images] argument states that our images task must be run before processing the HTML (the HTML is likely to reference images). Any number of dependent tasks can be listed in this array and all will complete before the task function runs.
  2. We only pipe the HTML through gulp-htmlclean if NODE_ENV is set to production. Therefore, the HTML remains uncompressed during development which may be useful for debugging.

Save gulpfile.js and run gulp html from the command line. Both the html and images tasks will run.

JavaScript Task

Too easy for you? Let’s process all our JavaScript files by building a basic module bundler. It will:

  1. ensure dependencies are loaded first using the gulp-deporder plug-in. This analyses comments at the top of each script to ensure correct ordering e.g. // requires: defaults.js lib.js.
  2. concatenate all script files into a single main.js file using gulp-concat, and
  3. remove all console and debugging statements with gulp-strip-debug and minimize code with gulp-uglify. This step will only occur when running in production mode.

Install the plug-ins:

npm install gulp-deporder gulp-concat gulp-strip-debug gulp-uglify --save-dev

Reference them at the top of gulpfile.js:

var
  ...
  concat = require('gulp-concat'),
  deporder = require('gulp-deporder'),
  stripdebug = require('gulp-strip-debug'),
  uglify = require('gulp-uglify'),

Then add a new js task:

// JavaScript processing
gulp.task('js', function() {

  var jsbuild = gulp.src(folder.src + 'js/**/*')
    .pipe(deporder())
    .pipe(concat('main.js'));

  if (!devBuild) {
    jsbuild = jsbuild
      .pipe(stripdebug())
      .pipe(uglify());
  }

  return jsbuild.pipe(gulp.dest(folder.build + 'js/'));

});

Save then run gulp js to watch the magic happen!

CSS Task

Finally, let’s create a CSS task which compiles Sass .scss files to a single .css file using gulp-sass. This is a Gulp plug-in for node-sass which binds to the super-fast LibSass C/C++ port of the Sass engine (you won’t need to install Ruby). We’ll presume your primary Sass file scss/main.scss is responsible for loading all partials.

Our task will also utilize the fabulous PostCSS via the gulp-postcss plug-in. PostCSS requires its own set of plug-ins and we’ll install:

  • postcss-assets to manage assets. This allows us to use properties such as background: resolve('image.png'); to resolve file paths or background: inline('image.png'); to inline data-encoded images.
  • autoprefixer to automatically add vendor prefixes to CSS properties.
  • css-mqpacker to pack multiple references to the same CSS media query into a single rule.
  • cssnano to minify the CSS code when running in production mode.

First, install all the modules:

npm install gulp-sass gulp-postcss postcss-assets autoprefixer css-mqpacker cssnano --save-dev

and reference them at the top of gulpfile.js:

var
  ...
  sass = require('gulp-sass'),
  postcss = require('gulp-postcss'),
  assets = require('postcss-assets'),
  autoprefixer = require('autoprefixer'),
  mqpacker = require('css-mqpacker'),
  cssnano = require('cssnano'),

We can now create a new css task at the end of gulpfile.js. Note the images task is set as a dependency because the postcss-assets plug-in can reference images during the build process. In addition, most plug-ins can be passed arguments – refer to their documentation for more information:

// CSS processing
gulp.task('css', ['images'], function() {

  var postCssOpts = [
  assets({ loadPaths: ['images/'] }),
  autoprefixer({ browsers: ['last 2 versions', '> 2%'] }),
  mqpacker
  ];

  if (!devBuild) {
    postCssOpts.push(cssnano);
  }

  return gulp.src(folder.src + 'scss/main.scss')
    .pipe(sass({
      outputStyle: 'nested',
      imagePath: 'images/',
      precision: 3,
      errLogToConsole: true
    }))
    .pipe(postcss(postCssOpts))
    .pipe(gulp.dest(folder.build + 'css/'));

});

Save the file and run the task from the command line:

gulp css

Step 6: Automate Tasks

We’ve been running one task at a time. We can run them all in one command by adding a new run task to gulpfile.js:

// run all tasks
gulp.task('run', ['html', 'css', 'js']);

Save and enter gulp run at the command line to execute all tasks. Note I omitted the images task because it’s already set as a dependency for the html and css tasks.

Is this still too much hard work? Gulp offers another method – gulp.watch – which can monitor your source files and run an appropriate task whenever a file is changed. The method is passed a folder and a list of tasks to execute when a change occurs. Let’s create a new watch task at the end of gulpfile.js:

// watch for changes
gulp.task('watch', function() {

  // image changes
  gulp.watch(folder.src + 'images/**/*', ['images']);

  // html changes
  gulp.watch(folder.src + 'html/**/*', ['html']);

  // javascript changes
  gulp.watch(folder.src + 'js/**/*', ['js']);

  // css changes
  gulp.watch(folder.src + 'scss/**/*', ['css']);

});

Rather than running gulp watch immediately, let’s add a default task:

// default task
gulp.task('default', ['run', 'watch']);

Save gulpfile.js and enter gulp at the command line. Your images, HTML, CSS and JavaScript will all be processed then Gulp will remain active watching for updates and re-running tasks as necessary. Hit Ctrl/Cmd + C to abort monitoring and return to the command line.

Step 7: Profit!

Other plug-ins you may find useful:

One useful method in gulp-util is .noop() which passes data straight through without performing any action. This could be used for cleaner development/production processing code, e.g.

var gutil = require('gulp-util');

// HTML processing
gulp.task('html', ['images'], function() {
  var out = folder.src + 'html/**/*';

  return gulp.src(folder.src + 'html/**/*')
    .pipe(newer(out))
    .pipe(devBuild ? gutil.noop() : htmlclean())
    .pipe(gulp.dest(out));

});

Gulp can also call other Node.js modules – they don’t necessarily need to be plug-ins, e.g.

  • browser-sync – automatically reload assets or refresh your browser when changes occur
  • del – delete files and folders (perhaps clean your build folder at the start of every run).

Invest a little time and Gulp could save many hours of development frustration. The advantages:

  • plug-ins are plentiful
  • configuration using pipes is readable and easy to follow
  • gulpfile.js can be adapted and reused in other projects
  • your total page weight can be reduced to improve performance
  • you can simplify your deployment.

Useful links:

Applying the processes above to a simple website reduced the total weight by more than 50%. You can test your own results using page weight analysis tools or a service such as New Relic which provides a range of sophisticated application performance monitoring tools.

Gulp can revolutionize your workflow. I hope you found this tutorial useful and consider Gulp for your production process. I’d be glad to hear your thoughts in the comments below.

  • Jed Lehmann

    Nice writeup. I’m new to using a build process such as this, and it all makes sense (conceptually anyway).

    My only question is, what process would you go through for the second, third etc project using Gulp (once you’ve got it set up on one)? Can you simply duplicate the existing project folder, or is there more to it than that?

  • Craig Buckler

    Thanks Jed. You can duplicate the node_modules folder and your gulpfile.js configuration. However, I suggest you write a batch/shell script with all npm install commands (or a single command) so the latest versions are downloaded when you start a new project.

    Note also you can run “npm update” to update all dependencies at any point.

    • Jed Lehmann

      Thanks Craig, sounds like I’ll have to dive in when I find some time.

  • adimauro

    Just as I start getting the hang of Grunt, I’m now reading about Gulp everywhere! The syntax is nice. It feels more like coding, whereas the Grunt configuration is only slightly better than having to manage XML config files. Gulp syntax reads much nicer.

    Of course, I prefer the Grunt logo…if that counts for anything! But, after going through this article, I think you’ve convinced me to give Gulp a serious try. Thanks.

    Too many tools, too little time.

    • Aurelio De Rosa

      If you’re happy with Grunt stick with it, there’s no sense in just changing tools because of fashion. Otherwise you’ll find yourself *next week* dealing with the next shining tool that we’ll released.

      • adimauro

        Yes, I agree, but, I also like trying out new technologies. There is always something to learn from new approaches. I’m in the process of researching for a new project, but, I certainly wouldn’t suddenly switch tools mid-project!

        You bring up a good point, though. The number of libraries being released seems to be accelerating, especially with JavaScript. Keeping up is almost impossible. At some point you do have to focus on your core group of libraries that fit best with your workflow/programming style and not worry about every new library that comes out.

        • Craig Buckler

          I agree with Aurelio: stick with Grunt if you’re happy using it. Since writing this I’ve also discovered Brunch — yet another task runner.

          Personally, I prefer Gulp but I wouldn’t encourage anyone to switch for the sake of it. Something better will almost certainly appear within a matter of weeks!

  • vsync

    on the HTML tast, why do you need “changed(htmlDst)” if you are already using the gult “WATCH” method?

    • Craig Buckler

      The watch process will fire if it spots any new or updated files. Every file is then processed regardless of whether it’s been done before. Sometimes that’s necessary, e.g. for Sass compilation. Sometimes it’s not, e.g. image processing. The change() pipe only passes files which have changed to ensure they’re not done again.

  • Kurt Meredith

    Craig, thanks for this tutorial on Gulp. I am embarrassed to say I got stymied at step 3 where you start talking about navigating to the “test” directory. Could you explain this a little bit more? Do we have to create our own “test” directory and sub-directories, or is there something that I am missing? I tried creating my own “test” directory structure manually, where I usually create my development files, but then the following steps in the tutorial don’t work. That leads me to think I have missed a step somewhere. I appreciate any pointers. [currently running Linux 10.04; node, npm and gulp are all successfully installed]

    • Craig Buckler

      Hi Kurt. First, create your own directory/folder. In Linux, you use “mkdir test” to create a test folder. You then use “cd test” to move into that folder. I hope that helps?

      • Kurt Meredith

        Thanks, Craig. I must have something set incorrectly. In the terminal, I created and moved to the “test” directory at ~/Development/gulp/test and then ran:

        kurt@kurt-linux:~/Development/gulp/test$ npm install gulp –save-dev

        But instead of the “node_modules” directory and sub-directories installing under the “test” directory, they installed under my home (~/) directory. I need to figure out why the files are not being installed to the directory that I run the command from.

        [SOLUTION]
        I found that, at least in my setup, if the “node_modules” directory does not already exist in the current working directory, then npm will start traveling up the directory heirarchy until it finds one. Once I made a “node_modules” directory within the “test” working directory, the “npm install gulp –save-dev” command worked properly.

        • Craig Buckler

          Ahh. Try running “npm init” in your work folder first. That doesn’t appear to be necessary for everyone, but it won’t do any harm.

  • http://notrobotic.com/ Jason Rhodes

    Craig, nice intro. Just a few things that I’ve been seeing lots of people be confused about:

    gulp.run is out, dependencies are in. A task’s dependencies are passed as its second argument, as you do in the default task in your example above.

    gulp.task("default", ["scripts", "styles"]);

    But later you have your watch tasks use gulp.run, which is deprecated as of version 3.5. In most cases, dependencies are your friend. For example, you could rewrite your watch tasks:

    // default gulp task
    gulp.task("default", ["imagemin", "htmlpage", "scripts", "styles"], function() {
    // watch for HTML changes
    gulp.watch('./src/*.html', ["htmlpage"]);
    // watch for JS changes
    gulp.watch('./src/scripts/*.js', ["jshint", "scripts"]);
    // watch for CSS changes
    gulp.watch('./src/styles/*.css', ["styles"]);
    });

    gulp is all about async. Remember that when you list dependencies, they won’t run in order—gulp tries to run tasks in parallel by default, to make things finish faster. If you need “jshint” to run before “scripts”, don’t depend on ["jshint", "scripts"]. Instead, make the “scripts” task depend on “jshint”, etc.

    Streams are the main way gulp handles all these dependencies, so if you don’t return the stream (or accept and run the callback in the task function), gulp won’t know when a task has finished. To make sure your dependencies run the way you expect, make sure your tasks return the stream, like this:

    // JS concat, strip debugging and minify
    gulp.task('scripts', function() {
    return gulp.src(['./src/scripts/lib.js','./src/scripts/*.js'])
    .pipe(concat('script.js'))
    .pipe(stripDebug())
    .pipe(uglify())
    .pipe(gulp.dest('./build/scripts/'));
    });

    Just a few simple clarifications, hope they help. Happy gulping!

    • Craig Buckler

      Thanks Jason – appreciate the feedback.

      • http://notrobotic.com/ Jason Rhodes

        It’s hard to keep up. I just see so many confused questions come into the gulp issue queue, I figure it’s a good idea to try to get good information out there where people can find it. Thanks for writing up the article.

  • Peter Januarius

    Hi Craig – very well written & easy to follow. Helped a lot.

    Thanks

    Pete…

  • Gemma W.

    Thanks for this tutorial. I’m new to Gulp and you made it so much easier to understand how to do this. I found this much simpler to understand than the other articles I found previously.

    I have this set up, and I’ve even added a couple of other plugins and added them to the default task at the end. Works well. :)

  • Oliver Martin

    I’m using a gulpfile that a friend setup as part of a theme workflow he created. Here is the code, can you help me input newer and imagemin?

    var gulp = require('gulp'),
    gutil = require('gulp-util'),
    browserify = require('browserify'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    changed = require('gulp-changed'),
    compass = require('gulp-compass'),
    buffer = require('vinyl-buffer'),
    source = require('vinyl-source-stream'),
    livereload = require('gulp-livereload');
    //newer = require('gulp-newer'),
    //imagemin = require('gulp-imagemin'),

    var scssSources = [
    '_src/scss/**/*.scss'
    ],
    jsSources = [
    '_src/js/main.js'
    ],
    jsVendorSources = [
    '_src/js/vendor.js'
    ],
    scriptsPath = 'assets/js',
    scssPath = 'assets/css';

    var onError = function (error)
    {
    gutil.log(gutil.colors.red(error));
    this.emit('end');
    };

    gulp.task('sass', function()
    {
    gulp.src(scssSources)
    .pipe(changed(scssPath))
    .on('error', onError)
    .pipe(compass({
    style: 'expanded',
    sass: '_src/scss',
    css: scssPath,
    relative: true,
    require: ['breakpoint', 'susy']
    }))
    .on('error', onError)
    .pipe(gulp.dest(scssPath))
    .pipe(livereload())
    });

    gulp.task('js', function()
    {
    return browserify(jsSources)
    .on('error', onError)
    .bundle()
    .on('error', onError)
    .pipe(source('main.js'))
    .on('error', onError)
    .pipe(buffer())
    .on('error', onError)
    //.pipe(uglify())
    //.on('error', onError)
    .pipe(gulp.dest(scriptsPath))
    .pipe(livereload());
    });

    gulp.task('js-vendor', function()
    {
    return browserify(jsVendorSources)
    .on('error', onError)
    .bundle()
    .on('error', onError)
    .pipe(source('vendor.js'))
    .on('error', onError)
    .pipe(buffer())
    .on('error', onError)
    //.pipe(uglify())
    //.on('error', onError)
    .pipe(gulp.dest(scriptsPath))
    });

    // image processing
    //gulp.task('images', function() {
    // var out = folder.build + 'assets/images/';
    // return gulp.src(folder.src + '_src/images/**/*')
    // .pipe(newer(out))
    // .pipe(imagemin({ optimizationLevel: 5 }))
    // .pipe(gulp.dest(out));
    // .pipe(livereload());
    //});

    gulp.task('watch', function()
    {
    livereload.listen();
    gulp.watch(['_src/js/main.js', '_src/js/scripts/**/*.js'], ['js']);
    gulp.watch(['_src/js/vendor.js', '_src/js/vendor/**/*.js'], ['js-vendor']);
    gulp.watch(scssSources, ['sass']);
    gulp.watch(['**/*.php', '**/*.html', '**/*.twig']).on('change', function(file) { livereload.changed(file.path) })
    });

    gulp.task('default', ['watch']);

    • Craig Buckler

      It looks to me that it’ll work if you simply uncomment the ‘images’ task code?

      • Oliver Martin

        Hi Craig.

        I originally had the lines uncommented and it hit an error. See below:


        Mac-mini:lion olivermartin$ gulp images
        /Volumes/Wunderful Storage 1/Sites/Development/lionwindows.co.uk/wp-content/themes/lion/gulpfile.js:14
        var scssSources = [
        ^^^

        SyntaxError: Unexpected token var
        at exports.runInThisContext (vm.js:53:16)
        at Module._compile (module.js:373:25)
        at Object.Module._extensions..js (module.js:416:10)
        at Module.load (module.js:343:32)
        at Function.Module._load (module.js:300:12)
        at Module.require (module.js:353:17)
        at require (internal/module.js:12:17)
        at Liftoff.handleArguments (/usr/local/lib/node_modules/gulp/bin/gulp.js:116:3)
        at Liftoff. (/usr/local/lib/node_modules/gulp/node_modules/liftoff/index.js:198:16)
        at module.exports (/usr/local/lib/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/index.js:17:3)

        It seems var is messing it up, but I thought that was necessary?

        • Stephan Zuidberg

          Replace the semicolon after gulp-livereload with a comma. And replace te comma after gulp-imagemin with a semicolon.

Recommended
Sponsors
Get the latest in JavaScript, once a week, for free.