With JavaScript being no toy language anymore our demands on a high quality development environment have risen tremendously. One part of a good development environment are build tools, and Gulp.js -- being the JavaScript streaming build system -- is but one of the many choices a developer has nowadays. For many however, it's considered to be the best! In this three hour workshop, we will take a good look into Gulp and its possibilities. After our in-depth 3 hour course you will be able to do the following:
- Know how Gulp's API and the ecosystem of its plugins work
- Create parallel and sequential execution chains to be in total control of your build flow
- Know how 3rd party Node modules evolve around Gulp and how they can be integrated
- Create incremental builds to speed up your build time
- Know how streams work in Node.js
- And use stream arrays and merge streams to plumb together sophisticated pipelines doing all the work for you
Join us and become a build plumber!
More information
http://github.com/frontend-tooling
http://bit.ly/gulp-tool-book
http://fettblog.eu
5. Sass CoffeeScript LESS
P o s t C S S H A M L J a d e
U g l i f y E S 6 R e a c t J S
B r o w s e r i f y A n g u l a r J S
E m b e r C S S M i n J S L i n t
ESHint ImageOptim Mocha
Jasmine TypeScript
6.
7.
8.
9.
10. 1530 lines of code
original Ant tasks used:
concat — copy — delete — mkdir
39. Gulp API
• gulp.task creates a new task
• It requires to return either a Stream, a Promise or an Observable
• gulp.src “globs” files and returns a stream of virtual file objects
• each file can be piped through a process (jshint, uglify, less, etc.)
• gulp.dest saves the file back to the file system
41. gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
defines a new task
42. gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
with a defined name
43. gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
we load a certain file
(or files)
Starting here, we have virtual
files in-memory instead of
real files we
44. gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
and pipe it through a
series of operations
45. gulp.task('styles', function() {
return gulp.src('app/styles/main.less')
.pipe(less())
.pipe(minifyCSS())
.pipe(prefix())
.pipe(gulp.dest('dist/styles'));
});
before we save it
again on the "real" file system
51. Gulp API
• The second parameter of gulp.task is always a function.
• gulp.series is a task function that runs tasks in sequential order.
• gulp.parallel is a task function that starts every task concurrently
• Both task functions accept task names and other functions as
parameters.
• They can be combined infinitly
59. Gulp API
• gulp.watch creates a file watcher and listens to changes
• changes include ‘change’, ‘add’, ‘unlink’ and others
• BrowserSync is a development tool that can be fully integrated in
Gulp.
• Watchers trigger a browserSync.reload call
67. Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
68. Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
69. Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
Too much is going on!
Each change: Uglify all
the files?
70. Some tasks take long
gulp.src(‘scripts/*.js’)
.pipe(uglify())
.pipe(gulp.dest())
.pipe(concat())
77. Gulp Plugins
• gulp-cached and gulp-remember can be used to create file caches
• The plugin filters non-changed files and ads them back to the
stream once we are done with performance-heavy tasks
• Additionally to that, we can use gulp.lastRun in Gulp 4 to filter files
during globbing
• gulp-newer allows us to do incremental copies/builds on a per-file
basis
79. gulp.task('scripts', function () {
return gulp.src('app/scripts/**/*.js')
.pipe(cached('ugly'))
.pipe(uglify())
.pipe(remember('ugly'))
.pipe(concat('main.min.js'))
.pipe(gulp.dest('dist/scripts'));
});
we use the cache to
check if files have
changed
80. gulp.task('scripts', function () {
return gulp.src('app/scripts/**/*.js')
.pipe(cached('ugly'))
.pipe(uglify())
.pipe(remember('ugly'))
.pipe(concat('main.min.js'))
.pipe(gulp.dest('dist/scripts'));
});
once we are done,
we remember all
the other files
we stored in
the cache
86. var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
87. var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
b.bundle emits a
stream.
But no vinyl file
objects
88. var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
vinyl-source-stream
wraps the original
stream into
a vinyl file object
89. var b = browserify({
entries: ['_js/main.js']
});
var bundle = function() {
return b.bundle()
.pipe(source(‘main.js’))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('js'));
}
vinyl-buffer converts
the stream contents
to a buffer for
plugins who need
such
92. What does it do?
• Generates static HTML sites
• From a templating engine
• Can parse Markdown
• Can parse HTML
• Can create permalinks
• For different types (posts, pages)
93. The stack
• We use kramdown to convert Markdown to HTML
• We use nujucks for our templating engine
• We rename posts to feature blog permalink
• We rename pages to resemble pretty URLs