This is an update to my previous setup I wrote about on: How I build my assets pipeline on Windows using NodeJS. This time around I use Gulp to simplify things and add more automation.
First up, you’ll need to install gulp globally (npm i -g gulp) if you haven’t yet, then install it in your project directory (npm i gulp -D). The goal is accomplish the following automatically:
- compile and minify my javascript files when changes are made
- compile and compress my sass into css when changes are made
- automatically reload my browser when the css/js is compiled
Here’s a list of the plugins I use and what they in relation to my workflow. This assumes you are familiar with NodeJS already, if not you may read this post first.
- gulp-concat – concatenate css and/or JavaScript files
- gulp-uglify – compress our JavaScript
- gulp-sass – libsass compiler for our css
- gulp-autoprefixer – add vendor prefixes to our compiled css
- gulp-imagemin – compress images (jpg, png, svg, gif) and some plugins for it
- imagemin-pngquant – PNG
- imagemin-zopfli – also for PNG’s
- imagemin-mozjpeg – lossy compression plugin. Works in conjunction with JpegTran
- gulp-livereload – automatically reloads the page in chrome using the livereload chrome extension.
Some none-gulp plugins we’ll also need are:
- browserify – dynamically load javascript libraries into our project
- event-stream – merge multiple gulp source files for our .css and .js files
- vinyl-source-stream & vinyl-buffer – needed to uglify our browserify js file
Once you have all these installed, create a gulpfile.js in your project directory (where your package.json is) then you can start creating task. In my setup, I simply run the gulp command to watch my JavaScript and sass files, compile them, and reload the browser. I have a different gulp task to compress the images since this is not done often. Note that the paths may vary depending on how you structure your working environment.
var gulp = require('gulp'); var cleanCSS = require('gulp-clean-css'); var terser = require('gulp-terser'); var concat = require('gulp-concat'); var es = require('event-stream'); var merge = require('merge-stream'); var sass = require('gulp-sass'); var autoprefixer = require('gulp-autoprefixer'); var browserify = require('browserify'); var source = require('vinyl-source-stream'); var buffer = require('vinyl-buffer'); var livereload = require('gulp-livereload'); var imagemin = require('gulp-imagemin'); var imageminPngquant = require('imagemin-pngquant'); var imageminZopfli = require('imagemin-zopfli'); var imageminMozjpeg = require('imagemin-mozjpeg'); gulp.task('scripts', function() { var results = []; results.push(browserify('client/index.js') .bundle() .pipe(source('bundle.min.js')) .pipe(buffer()) .pipe(terser()) .pipe(gulp.dest('public/assets/js'))); results.push(browserify('client/index.js') .bundle() .pipe(source('bundle.js')) .pipe(buffer()) .pipe(gulp.dest('public/assets/js'))); return merge(results); }); gulp.task('styles', function() { var sassStream = gulp.src('client/*.scss') .pipe( sass({ outputStyle: 'expanded', errLogToConsole: true }) ); var results = []; results.push(es.merge(sassStream) .pipe(concat('bundle.min.css')) .pipe(autoprefixer()) .pipe(cleanCSS({})) .pipe(gulp.dest('public/assets/css')) .pipe(livereload())); results.push(es.merge(sassStream) .pipe(concat('bundle.css')) .pipe(autoprefixer()) .pipe(cleanCSS({ format:{ breaks: { afterAtRule: true, afterBlockBegins: true, afterBlockEnds: true, afterComment: true, afterProperty: true, afterRuleBegins: true, afterRuleEnds: true, beforeBlockEnds: true, betweenSelectors: true }, spaces: { aroundSelectorRelation: true, beforeBlockBegins: true, beforeValue: true }, indentBy:1, indentWith: 'tab' } })) .pipe(gulp.dest('public/assets/css')) .pipe(livereload())); return merge(results); }); gulp.task('images', function() { return gulp.src('client/img/*.{jpg,png,svg,gif}') .pipe(imagemin([ //gif lossless imagemin.gifsicle({ interlaced: true, optimizationLevel: 3 }), //svg imagemin.svgo({ plugins: [{ removeViewBox: false }] }), //png lossless imageminPngquant(), imageminZopfli({ more: true }), //jpg lossless imagemin.jpegtran({ progressive: true }), //jpeg lossy imageminMozjpeg({ quality: 90 }) ])) .pipe(gulp.dest('public/assets/img')) }); gulp.task('default', function() { livereload.listen(); gulp.watch('client/*.js', gulp.series('scripts')); gulp.watch('client/*.scss', gulp.series('styles')); gulp.watch('client/img/*.*', gulp.series('images')); });
UPDATE April 5, 2018 – fix for deprecated packages and missing Python executable. UPDATE: October 6, 2018 – I updated the image compress gulp task for better compression and added SVG, and GIF support. Also added the default task to trigger image compression when the source image folder contents are updated. Website Planet has an image compression tool which inspired this update.
UPDATE October 11, 2019 – updated the gulp plugin dependency changes and added a non-minified version of the bundled CSS and JS files
1 comment