NPM, Gulp, and SASS

This tutroial is part of a series of lessons on Node Package Manager.


In the first lesson in this series of tutorials you downloaded and extracted a folder named npm to serve as a sample project. And in the previous lesson you used Babel to compile the JavaScript code from the src directory into the dist directory. But notice that our dist folder doesn't include the index.html file. We could manually copy it from the src folder to the dist folder, but it would be nice to automate the process. And that's what we'll do now.

Open the terminal and navigate to the npm folder. Enter the following command to install the Gulp Command Line tool (it allows you to run Gulp commands from the terminal) We'll add the -g option to install it 'globally' so you can use it on any project you are working

npm install gulp-cli -g

After the install completes, check to see which version of Gulp is installed:

npx gulp -v

It should say that you have version 2.3.0 or later installed.

Now install gulp for the project (note that the --save-dev option will add Gulp to the package.json file):

npm install gulp --save-dev

When the install completes, check the package.json file to see which version of Gulp was installed. It should be at least version 4

Create a file in the npm folder named gulpfile.js. This file will contain all the tasks that we run, paste this code into it:

// IMPORTS
const gulp = require('gulp');


// TASK FUNCTIONS
function testTask(done){
    console.log("Test task running...");
    done();
}


// EXPORTS
exports.test = testTask;

This .js file imports gulp, then defines a function that runs a task. The task doesn't do anything other than writes a message to the console. In order to be able to run this task from the command line, we have to export it. When you define a task function, you often need to include a parameter that represents a function. Gulp will pass in a function when it invokes you your task function. Then you invoke that function when your task is complete. In this case the parameter name is 'done'.

In the terminal, enter this to run the task we just defined:

npx gulp test

Let's add a task to gulpfile.js that copies the index.html file to the dist folder:

function copy(done){
	gulp.src("src/index.html").pipe(gulp.dest("dist/"));
	done();
}

Make sure to export it at the bottom of gulpfile.js like this:

exports.copy = copy;

Now run the task from the terminal:

npx gulp copy

Look in the dist folder and hopefully you will see that index.html has been copied to it.

When we set up Babel, we ran it from by specifying a script named 'build' in the package.json file. But now we'll run it from Gulp.

First install the Gulp package for Babel by running this command from the terminal:

npm install --save-dev gulp-babel

Then import it in gulpfile.js:

const babel = require('gulp-babel');

Define a task function in gulpfile.js:

function babelTask(done){
	gulp.src('src/**/*.js')
			.pipe(babel())
			.pipe(gulp.dest('./dist'));
	done();
}

The ** tells the task to look for any .js files in any folder inside the src directory.

Now export the task at the bottom of gulpfile.js

exports.babel = babelTask;

And now you can run the task by entering this command in the terminal:

npx gulp babel

Now we'll create a task that combines a few of the tasks that we've defined. Add this line under the exports in gulpfile.js

exports.default = gulp.parallel(copy, babelTask);

Now you can simply run 'npx gulp' in the terminal. If you run gulp without specifying the task name, gulp will look for the 'default' task that has been exported. In this case, the default task first runs the 'copy' task and then runs the 'babelTask'. Go ahead and run the default task by entering this command in the terminal:

npx gulp

Optimizing Images with Gulp

Let's use npm to install a Gulp package that will allow us to optimize the images for our project Open the terminal and navigate to the the npm folder and run this command:

npm install gulp-imagemin  --save-dev

Now import it into gulpfile.js:

const imagemin = require('gulp-imagemin');

Add this task to gulpfile.js:

function images(done) {
	gulp.src('src/images/**/*')
		.pipe(imagemin({ optimizationLevel: 5 }))
		.pipe(gulp.dest('dist/images/'));

	done();
}

Now add it to the exports in gulpfile.js:

exports.images = images;

Now run the task from the terminal:

npx gulp images

If you look compare the images in the src folder with the ones in the dist folder you'll see that the file sizes in the dist folder are dramatically smaller.

Let's add the images to the default tasks, update it to include 'images' task like so:

exports.default = gulp.parallel(copy, babelTask, images);

Now, to run the default task, which actually includes the copy, babelTask, and images tasks, enter this command in the terminal:

npx gulp

Now we'll install the Sass package which is a CSS prepocesser, enter this command in the terminal:

npm install gulp-sass --save-dev

Before we make use of the Sass package, take a look at src/css/main.scss. This is a sass file. Sass allows you to do lots of cool things that you can't normally do in pure CSS. For example, you can set up variables, which makes it very easy to change color themes (instead of having to go through an entire style sheet adjusting color settings, you can simple change the variables).

Import Sass in gulpfile.js:

const sass = require('gulp-sass');

Add this task in gulpfile.js:

function processSass(done){
	gulp.src('src/css/main.scss')
		.pipe(sass().on('error', sass.logError))
		.pipe(gulp.dest('src/css/'));

	done();
}

Export the task in gulpfile.js:

exports.sass = processSass;

Now run the task in the terminal:

npx gulp sass

After the task completes, you should see style sheet called main.css in the css folder. Open this file and note that the variables have been have been replaced with their values. As mentioned, there is much more you can do with Sass than create variables, I'll leave it up to you to explore on your own.

Open index.html in the browser and notice that it has changed now that the main.css style sheet has been created (I put a link to the style sheet in index.html when I set up the files).

Now we'll add the main.css to the copy task so that it gets copied to the dist folder along with the index.html file. Update the copy task to look like this:

function copy(done){
	gulp.src("src/index.html").pipe(gulp.dest("dist/"));
	gulp.src("src/css/main.css").pipe(gulp.dest("dist/css/"));
	done();
}

Add the sass task to the default task in gulpfile.js, update it to include sass so that it looks like this:

exports.default = gulp.parallel(processSass, copy, babelTask, images);

Note that you'll want to run the sass task before copying the files to the dist folder.

Finally, we'll create a task to 'watch' main.scss, and every time it is saved with changes, it will automatically run the sass task.

function watchSass(){
	gulp.watch('src/css/main.scss', processSass);
}

The watch() method in gulp takes two parameters, the first is the file to watch for changes, and the second it the task to run when changes are made to the file. This is nice for developing because as you make changes to the .scss file, you don't have to manually run tasks before viewing index.html in the browser. Note that there is no 'done' parameter. This task is unlike the others in that it runs continuously.

Export the task in gulpfile.js:

exports.watchSass = watchSass;

Now run the task, and when you do, notice that it continues to run in the terminal until you press Ctrl + C But before you end the task, make a change to the main.scss file and save it. You'll notice that the .scss file was automatially compiled into main.css.

npx gulp watchSass
NEXT TUTORIAL: Gulp, Sass, and Bootstrap