Generic Gulp tasks used in Lost My Name components and projects
JavaScript
Pull request Compare This branch is 2 commits ahead, 113 commits behind Lostmyname:master.

README.md

Gulp Tasks Build Status

A collection of generic configurable Gulp tasks used in various projects, themes and components at Lost My Name. They'll work in your projects, too!

Install

$ npm install --save-dev lmn-gulp-tasks

Usage

To use:

var gulp = require('gulp');
var getLmnTask = require('lmn-gulp-tasks');

gulp.task('js', getLmnTask('browserify', {
  src: './src/js/monkey.js',
  dest: './demo/build/bundle.js'
}));

You can read why we're taking this approach of splitting Gulp into multiple files instead of the one detailed in the Gulp recipes in my article here.

Handling errors

Most of the tasks in this package have error handling built in so that Gulp doesn't explode if you miss a semi-colon from your JS. By default, the errors will be logged to the console and then ignored, but you can set your own handlers, either by changing the default handler, or by setting a handler per task.

Changing the default handler

var getLmnTask = require('lmn-gulp-tasks');

getLmnTask.setErrorHandler(function (err) {
  console.log('OH NO CRAZY BAD THINGS ARE HAPPENING');
});

Changing the handler per task

var gulp = require('gulp');
var getLmnTask = require('lmn-gulp-tasks');

gulp.task('js', getLmnTask('browserify', {
  src: './src/js/monkey.js',
  dest: './demo/build/bundle.js',
  onError: function (err) {
    console.log('The browserify task died!');
  }
}));

Revisioning assets

A load of these tasks support revisioning of assets. There's an options called rev which should be boolean:

gulp.task('js', getLmnTask('browserify', {
  src: './src/js/monkey.js',
  dest: './demo/build/bundle.js',
  rev: true
}));

That'll create a fingerprinted version of the file, and write the path to a manifest file. The location of the manifest file is by default the root directory, but can be specified using the manifest options, which in turn defaults to process.env.MANIFEST_DEST.

rev defaults to process.env.NODE_ENV === 'production'.

Tasks that support revisioning are marked with asterisks.

Tasks

browserify*

We use browserify on nearly all of our JavaScript at Lost My Name. This very simple task just runs browserify on your input file:

gulp.task('js', getLmnTask('browserify', {
  src: './src/js/monkey.js',
  dest: './demo/build/bundle.js',
  minify: false
}));

minify defaults to true: omitting the option will result in the resulting JS being minified. In addition to minifying, the minify option will call strip-debug, which strips console, alert and debugger statements.

This will remove multiple versions of jQuery and include the version from the package in question. If you don't want jQuery, specify jquery: false. If you want multiple versions of jQuery: you can't do that, weirdo.

clean

This task deletes stuff. src can be either a string or an array.

gulp.task('clean', getLmnTask('clean', {
  src: 'deletethis.json'
}));

copy*

Literally just copies stuff from one place to another, and can fingerprint it if necessary.

Have the option to flatten the directory structure if needed.

gulp.task('move-favicon', loadLmnTask('copy', {
  src: './assets/favicon.ico',
  dest: './demo/build',
  rev: false,
  flatten: false
}));

extract*

This task is used to extract assets (or anything else, for that matter) from modules stored in a node_modules directory somewhere.

gulp.task('getMarkdown', loadLmnTask('extract', {
  module: 'my-module',
  src: '/src/markdown/**/*.md',
  dest: 'markdown'
}));

That will extract everything matching that path inside the first module matching my-module.

html

Useful in LMN components only, probably. Takes faux-erb files and turns them into HTML.

gulp.task('html', getLmnTask('html', {
  langBase: 'component.monkey',
  imagePath: '../imgs',
  context: {
    foo: 'bar' // Will be accessible in the template files
  }
}));

js-quality

This task runs ESLint on your JavaScript, and optionally stops Gulp if an error is found.

gulp.task('js-quality', getLmnTask('js-quality', {
  src: './src/js/**/*.js',
  dieOnError: true
}));

dieOnError defaults to false, so if you miss that option out, Gulp will not die.

Prior to 2.0.0, lmn-gulp-task used JSHint, JSCS, and Buddy.js.

optimise-svgs*

This task gets svgs, optionally flattens the directory structure, optimises the svgs and makes optimised png fallbacks for browsers that don't support svg.

gulp.task('optimise-svgs', loadLmnTask('optimise-svgs', {
  src: './src/images/**/*.svg',
  dest: buildPath + 'images',
  flatten: true // Defaults to false
}));

responsive-images*

The responsive-images task is pretty big. It handles turning images like some-image-500x50@2x.png into some-image-xlarge.png, some-image-large.png, etc.

gulp.task('responsive-images', loadLmnTask('responsive-images', {
  src: './src/images/**/*.{png,jpg,gif}',
  dest: buildPath + 'images',
  lossless: function (file) {
    return _.contains(file.path, 'hero');
  },
  flatten: true // defaults to false
}));

This is an option called retinaSrc, but you might not need to specify it: the task will attempt to calculate it by replacing *.{ with *@2x*.{: for example, if your src is ./img/**/*.{png,jpg}, your generated retinaSrc will be ./img/**/*@2x*.{png,jpg}.

The lossless option should be either a function or a boolean value, and is used to tell whether to compress the image losslessly or not. It defaults to false, and imagemin will use jpegoptim({ max: 80 }). It's a big reduction in file size, and it's not noticeable unless you look hard. You can see in the example code above that we compress everything but the header images using a lossy compression.

There are also two options called skipResize and skipOptimize that you want to set true only on the certain situation. For example, they would be useful when you run integration tests on CI. It skips resizing but copies images with the publishing names. Both are false in default.

scss*

The scss tasks runs compass on one or more specified SCSS files, then runs autoprefixer on the resulting CSS, then optionally minifies it.

gulp.task('scss', getLmnTask('scss', {
  src: './src/scss/*.{sass,scss}',
  dest: './demo/build',
  includePaths: [],
  minify: false
}));

minify defaults to true: omitting the option will result in the resulting CSS being minified.

The task, in addition to passing through any include paths you give it, will pass in the output of find-node-modules, making it easier to include SCSS from modules from npm. Using ../node_modules is an anti-pattern, as explained below! To disable this behaviour, set includePaths to false.

Checking for ../node_modules

The problem with writing "../node_modules" is that there is no guarantee that the module will actually be installed there. It could have been installed a directory up, in which case it won't be installed again below.

There should never be any need to write "../node_modules", as the import paths are set for you. Therefore, it should be considered an antipattern, and this task will throw an error if you write "../node_modules" anywhere in your Sass.

If you really want to use this anti-pattern, you can set the ignoreSuckyAntipattern option to true and the task won't check your code.

test-locales

This searches for localised files and ensures that if a file is localised, it is localised in every language:

gulp.task('test-locales', getLmnTask('test-locales', {
  src: './src/images/**/*.{png,jpg,gif}',
  locales: ['en-US', 'de', 'en-GB']
}));

License

This project is released under the MIT license.