How to use Gulp to generate CSS from Sass/scss

This is the sequel of the post CSS Preprocessors – Introducing Sass to Podcastpedia.org. If in the first part I presented some Sass-features I use to generated the CSS file for Podcastpedia.org, in this part I will present how the .css file generation process can be implemented with the help of Gulpjs.

Octocat Source code for this post is available on Github - podcastpedia.org is an open source project.

1. Set up the infrastructure

1.1. Install Node.js

Well, the first I needed to do is install Nodejs:

“Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.”[1]

1.2. Install gulp

Gulp is a task runner which uses node.js. It doesn’t do much – it provides some streams and a basic task system.

1.2.1. Install gulp globally

npm install -g gulp

1.2.2. Install gulp in your project devDependencies:

npm install --save-dev gulp

1.2.3. Create a gulpfile.js at the root of the project:

var gulp = require('gulp');

gulp.task('default', function() {
  // place code for your default task here
});

1.2.4. Run gulp

The default task from above will run and do nothing for the moment. You can execute it by typing the following command in the root folder of the project

gulp

1.3. Install Gulp plugins

One of the Gulp’s strengths is the myriad of existing “plugins”, and because the Gulp community is growing, new ones are added daily. The ones that I use for the generation of the CSS file are

To install these plugins issue the following command in the console in the root folder of the project:

npm install --save-dev gulp-util  gulp-sass  gulp-minify-css gulp-rename  gulp-autoprefixer gulp-util gulp-minify-css gulp-rename del gulp-uglify gulp-concat jshint gulp-jshint gulp-wrapper gulp-sourcemaps

The --save-dev option saves these packages to the devDependencies list in the package.json:

"devDependencies": {
	"gulp": "~3.6.1",
	"gulp-minify-css": "~0.3.1",
	"gulp-util": "~2.2.14",
	"gulp-rename": "~1.2.0",
	"gulp-sass": "~0.7.1",
	"gulp-autoprefixer": "0.0.7"
}

There are all development dependencies as I only use this project to generate a CSS file. For libraries used in production you would add those under the “dependencies” element in your package.json file. The package.json file holds variaous metadata relevant to the project and is contained in all npm packages. You can create the package.json file according to the docs or by issueing npm init in the root of of your project. You can find the complete package.json file for this project on GitHub.

Now that we have everything set up, let’s do some actual work, and by that I mean some coding not configuration, as with Gulp the build file is code not config.

2. gulpfile.js

2.1. Load the modules

Node has a simple module loading system. In Node, files and modules are in one-to-one correspondence. When I installed the plugins in the previous step, they have been downloaded locally in the root folder under node_modules. You can load them now in the application via the require() function. Variables are defined to be used later in the gulp tasks:

var gulp = require("gulp"),//http://gulpjs.com/
	util = require("gulp-util"),//https://github.com/gulpjs/gulp-util
	sass = require("gulp-sass"),//https://www.npmjs.org/package/gulp-sass
	autoprefixer = require('gulp-autoprefixer'),//https://www.npmjs.org/package/gulp-autoprefixer
	minifycss = require('gulp-minify-css'),//https://www.npmjs.org/package/gulp-minify-css
	rename = require('gulp-rename'),//https://www.npmjs.org/package/gulp-rename
	log = util.log;

2.2. Gulp tasks

Gulp works with tasks. You define them by

  • registering a name (e.g. "sass", "watch")
  • an array of tasks to be executed and completed before your task will run
  • and a function that performs the task’s operations:
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
  // Do stuff
});

2.3. Pipes

Gulp’s power lies in its code over configuration approach and the use of streams. Streams use .pipe() to pair inputs with outputs.

".pipe() is just a function that takes a readable source stream src and hooks the output to a destination writable stream dst:

src.pipe(dst)

.pipe(dst) returns dst so that you can chain together multiple .pipe() calls together:

a.pipe(b).pipe(c).pipe(d)

which is the same as:

a.pipe(b);
b.pipe(c);
c.pipe(d);

This is very much like what you might do on the command-line to pipe programs together:

a | b | c | d

except in node instead of the shell! ” [7]

Using the principle mentioned above I defined a “sass” task, which will eventually generate the CSS file. To achieve that I “piped” the following operations

  • load the .scss files
  • autoprefix them,
  • write them expanded to file
  • minify them
  • and write them (podcastpedia.css, podcastpedia.min.css) minified to disk in the folder target/css:
gulp.task("sass", function(){
	log("Generate CSS files " + (new Date()).toString());
    gulp.src(sassFiles)
		.pipe(sass({ style: 'expanded' }))
					.pipe(autoprefixer("last 3 version","safari 5", "ie 8", "ie 9"))
		.pipe(gulp.dest("target/css"))
		.pipe(rename({suffix: '.min'}))
		.pipe(minifycss())
		.pipe(gulp.dest('target/css'));
});

To run the task I have to execute gulp sass on the command line in the root folder.

With the help of gulp-autoprefixer plugin, you can avoid having to write tedious mixins for vendor prefixes. As it is set up here – autoprefixer("last 3 version","safari 5", "ie 8", "ie 9"), this plugin will do the vendor prefixes covering the last 3 versions of major browsers plus dedicated configuration for safari5, and internet explorer 8 and 9.

2.4. “Watching” files for modifications

Gulp has a built-in “watch” functionality – you can watch files and every time when a file changes you can do something. In the following example:

gulp.task("watch", function(){
	log("Watching scss files for modifications");
	gulp.watch(sassFiles, ["sass"]);
});

every time I modify a .scss file the “sass” task will be executed.

Well, that’s it – few lines of code for pretty good functionality. I am looking forward to dwelve more and find out what Gulp can do… Your comments, suggestions and code contributions are very welcomed.

Octocat Source code for this post is available on Github - podcastpedia.org is an open source project.

3. Resources

3.1. Source code

3.3. Web

  1. nodejs
  2. gulpjs
  3. gulp plugins
  4. package.json
  5. Getting started with Gulp
  6. Getting Started With Gulp.js
  7. Stream-handbook
  8. Gulp – the streaming build system [presentation]
Podcastpedia image

Adrian Matei

Creator of Podcastpedia.org and Codingpedia.org, computer science engineer, husband, father, curious and passionate about science, computers, software, education, economics, social equity, philosophy - but these are just outside labels and not that important, deep inside we are all just consciousness, right?

How to redirect domain to www url with nginx

Snippet from nginx config file that redirects all requests (http and https) to the www URL Continue reading