Gulp.js – Why your build should be fun!



Gulp.js – Why your build should be fun!

0 1


presentation-gulp-intro

GulpJs introductory presentation for the internal Dev team

On Github keithmorris / presentation-gulp-intro

Gulp.js

or

Why your build should be fun!

Why are we even talking about this?

#buildfirst

“Build Early, Build Always.”

Bring Build Process Closer to

Development

(Where it should be)

Another build tool? Ugh!

But what about...

  • Jenkins
  • Bamboo

Why not these?

  • MSBuild
  • Make
  • Rake
  • Ant
  • Maven
  • Grunt

Why Gulp.js?

Code

vs.

Configuration

Most build tools require

Cryptic

Configuration

Ant Script

<project basedir="../" default="dist" name="MyProject">
    <description>simple example build file</description>
    <!-- set global properties for this build -->
    <property location="src" name="src"></property>
    <property location="build" name="build"></property>
    <property location="dist" name="dist"></property>
    <target name="init">
        <!-- Create the time stamp -->
        <tstamp></tstamp>
        <!-- Create the build directory structure used by compile -->
        <mkdir dir="${build}"></mkdir>
    </target>
    <target depends="init" description="compile the source " name="compile">
        <!-- Compile the java code from ${src} into ${build} -->
        <javac destdir="${build}" srcdir="${src}"></javac>
    </target>
    <target depends="compile" description="generate the distribution" name="dist">
        <!-- Create the distribution directory -->
        <mkdir dir="${dist}/lib"></mkdir>
        <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
        <jar basedir="${build}" jarfile="${dist}/lib/MyProject-${DSTAMP}.jar"></jar>
    </target>
    <target description="clean up" name="clean">
        <!-- Delete the ${build} and ${dist} directory trees -->
        <delete dir="${build}"></delete>
        <delete dir="${dist}"></delete>
    </target>
</project>

Even Grunt.js

grunt.initConfig({
	pkg: grunt.file.readJSON('package.json'),
	meta: {
		banner:
			'/*!\n' +
			' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
			' * http://lab.hakim.se/reveal-js\n' +
			' * MIT licensed\n' +
			' *\n' +
			' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
			' */'
	},

	qunit: {
		files: [ 'test/*.html' ]
	},

	uglify: {
		options: {
			banner: '<%= meta.banner %>\n'
		},
		build: {
			src: 'js/reveal.js',
			dest: 'js/reveal.min.js'
		}
	},

	cssmin: {
		compress: {
			files: {
				'css/reveal.min.css': [ 'css/reveal.css' ]
			}
		}
	},

	sass: {
		main: {
			files: {
				'css/theme/default.css': 'css/theme/source/default.scss',
				'css/theme/beige.css': 'css/theme/source/beige.scss',
				'css/theme/night.css': 'css/theme/source/night.scss',
				'css/theme/serif.css': 'css/theme/source/serif.scss',
				'css/theme/simple.css': 'css/theme/source/simple.scss',
				'css/theme/sky.css': 'css/theme/source/sky.scss',
				'css/theme/moon.css': 'css/theme/source/moon.scss',
				'css/theme/solarized.css': 'css/theme/source/solarized.scss',
				'css/theme/blood.css': 'css/theme/source/blood.scss'
			}
		}
	},

	jshint: {
		options: {
			curly: false,
			eqeqeq: true,
			immed: true,
			latedef: true,
			newcap: true,
			noarg: true,
			sub: true,
			undef: true,
			eqnull: true,
			browser: true,
			expr: true,
			globals: {
				head: false,
				module: false,
				console: false,
				unescape: false
			}
		},
		files: [ 'Gruntfile.js', 'js/reveal.js' ]
	},

	connect: {
		server: {
			options: {
				port: port,
				base: '.'
			}
		}
	},

	zip: {
		'reveal-js-presentation.zip': [
			'index.html',
			'css/**',
			'js/**',
			'lib/**',
			'images/**',
			'plugin/**'
		]
	},

	watch: {
		main: {
			files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
			tasks: 'default'
		},
		theme: {
			files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
			tasks: 'themes'
		}
	}

});

But Developers Like to

CODE!

Gulp.js

Only Four Main

Functions to Learn

Plus a little Node.js/NPM

(And it's JUST JavaScript!)

gulp.task(name, fn)

 

It registers the function with a name.

You can optionally specify some dependencies if other tasks need to run first.

gulp.src(glob)

 

This returns a readable stream.

Takes a file system glob (like grunt) and starts emitting files that match.

gulp.dest(folder)

 

This returns a writable stream

File objects piped to this are saved to the file system

gulp.watch(glob, fn || ['task'])

 

Runs a function or one or more gulp.tasks when a file that matches the glob changes.

gulpfile.js

(Again... just JavaScript)

// Node.js modules used by the tasks
var gulp = require('gulp'),
	less   = require('gulp-less'),
	concat = require('gulp-concat'),
	uglify = require('gulp-uglify'),
	mocha  = require('gulp-mocha'),
	run    = require('run-sequence');


// The Gulp tasks
gulp.task('less', function () {
	return gulp.src(['./less/styles.less'])
		.pipe(less())
		.pipe(gulp.dest('./css/'));
});


gulp.task('watch', function () {
	return gulp.watch('./less/**/*.less', ['less']);
});


gulp.task('test', function () {
	return gulp.src('./test/tests/**/*.js')
		.pipe(mocha());
});


gulp.task('concat', function () {
	return gulp.src(['./js/**/*.js'])
		.pipe(concat('scripts.min.js'))
		.pipe(uglify())
		.pipe(gulp.dest('./js/'));
});


gulp.task('dist', function (callback) {
	run('test', ['test', 'less'], callback);
});


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

What's the difference?

  • With Gulp your build file is code, not config
  • Build file lives with your code in Git (you are using Git, right?)
  • You use standard Node.js libraries to do things
  • Plugins are simple and do one thing - most are a ~20 line function
  • Plugins are simple to write*
  • Tasks are executed with maximum concurrency
  • Custom functionality with JavaScript

Demos & Examples