Blog Post

Compile and Minify SCSS with Gulpjs in Hugo

December 19, 2020

Category: Javascript

Tags: nodejs scss css gulpjs hugo



I’ve been working with Hugo, the static site generator, for a few months now. I’m new to the web development world and the simplicity of Hugo has been a big advantage.

As I’ve learned SCSS, I’ve been using Live Sass Compiler, the Visual Studio Code plugin. While the general workflow is efficient and simple, I wanted to add a few elements and stumbled upon GulpJS.

It’s a command line utility for NodeJS that automates workflows. Very simple put, you feed files into one end of the pipeline and then give it a series of automations to run in a sequence. When it finishes, your finalized code exists the pipe. There are thousands of plugins (and I’m just figuring out how to use them), but this post will show you to compile and minify SCSS or SASS with GulpJS.

1. Get NodeJS.

To check to see if you have NodeJS, open Terminal and type the following command:

node -v

If you get a number back, that means you have NodeJS installed. If you don’t have it installed go to nodejs.org, download, and install NodeJS.

2. Create a package.json file in your directory.

With NodeJS installed, cd to your directory and create a package.json file. The file essentially tracks your node dependencies. Type the following command:

npm init

This will prompt you with a series of questions. Just hit the Enter button on your keyboard until it finishes and creates a package.json file.

3. Install GulpJS.

You need to install Gulp both globally and in your website’s directory.

Install Gulp globally.

npm install gulp -g

Note: If that doesn’t work, you may need to run it as sudo npm install gulp -g and enter your password. When you type your password in, it won’t look like it’s registering your keystrokes, but that’s a security feature. Type your password and hit Enter.

Install Gulp in your directory.

npm install gulp --save-dev

This installs Gulp locally and adds it under devDependenies in your package.json file.

package.json file example

4. Install Gulp Plugins.

As I mentioned above, Gulp has thousands of plugins. You can see a full list here. For the workflow I’m showing you, you’ll need four plugins. Install them one after the other, using the following commands:

Install the SASS plugin

This plugin compiles your SCSS or SASS into CSS.

npm install gulp-sass --save-dev

Install the Autoprefixer plugin

This plugin adds backwards compatibility for older web browsers to your CSS.

npm install gulp-autoprefixer --save-dev

Important! In order for this plugin to work correctly, you also need to add the following to the top of your package.json.
‌ "browserslist": [ "last 5 versions" ],
It tells the autoprefixer plugin how far backwards it should make your code compatible. Add it just before the “scripts” section in the package.json file. I’ll show you an example of my completed code below.

Install the Clean-CSS plugin

This plugin minifies your CSS to help your code load faster.

npm install gulp-clean-css --save-dev

Install the Rename plugin

This plugin renames your file. I use it to add “.min” to the file.

npm install gulp-rename --save-dev

Your package.json file should now look like this. Notice the "browserlist" config at the top for the autoprefixer plugin adn the devDependencies generated by the install code above.

package.json file example

4. Add a gulpfile.js.

In the root of your website directory, add “gulpfile.js” as a new file.

You need to provide two things in your file:

  1. Dependencies: in our case, gulp and our plugins.
  2. A gulp task (which takes the following items…).
    • A file or files to put through our pipeline: in our case, I’ve got my scss file at /src/css/*.scss (the asterisk tells Gulp to put every scss file from that directory through the pipeline).
    • A series of actions to take on the inputed files: we’ll apply our four plugins to the inputed files.
    • An output file: what we want coming out of the pipeline.

    Add this code to your gulpfile.js and save it.

    const gulp = require('gulp');
    const sass = require('gulp-sass');
    const prefix = require('gulp-autoprefixer');
    const minify = require('gulp-clean-css');
    const rename = require('gulp-rename');
    
    gulp.task('compilescss', function() {
        gulp.src('./src/css/*.scss')
            .pipe(sass())
            .pipe(prefix())
            .pipe(minify())
            .pipe(rename(function (path) {
                return {
                dirname: path.dirname + "",
                basename: path.basename + ".min",
                extname: ".css"
                };
            }))
            .pipe(gulp.dest('./static/css'))
    });
    

    Note: If your input file is different, be sure to change the gulp.src('./src/css/*.scss') line to match the location where you scss files live. Same thing goes for the output. Change .pipe(gulp.dest('./static/css')) to match your desired output location. Make sure the head tag in your HTML points to this location for your css files. For instance, for me, I’m linking to /css/style.min.css in my HTML.

    To run the Gulp task we created, use the following command:

    gulp compilescss

    That will take all SCSS files in my src/css directory and run them through the pipeline, outputting them at static/css/*.min.css. Here’s a screenshot of the result. Notice how the SCSS includes nested elements, SCSS variables, as well as things that need backwards-compatibility like Flexbox. In the end, the CSS is minified, includes all the appropriate prefixes, and has been directly compiled from the SCSS.

    package.json file example

    5. Add a watch task.

    That’s great! It compiles, minifies, auto prefixes, and renames your file whenever you run:

    gulp compilescss

    But you can also create a watch task that will do this everything you save your SCSS file automatically. Replace your existing code in gulpfile.js with this code:

    const gulp = require('gulp');
    const sass = require('gulp-sass');
    const prefix = require('gulp-autoprefixer');
    const minify = require('gulp-clean-css');
    const rename = require('gulp-rename');
    
    async function compilescss () {
        gulp.src('./src/css/*.scss')
            .pipe(sass())
            .pipe(prefix())
            .pipe(minify())
            .pipe(rename(function (path) {
                return {
                dirname: path.dirname + "",
                basename: path.basename + ".min",
                extname: ".css"
                };
            }))
            .pipe(gulp.dest('./static/css'))
    };
    
    gulp.task('watch',function(){
        gulp.watch('./src/css/*.scss', compilescss)
    });
    

    Notice that I changed it to an async function to remove the error we got above and created a gulp task below, telling it which file(s) to automatically watch and then passed it the function we want it to run on those files (our gulp task above).

    Type this command in your terminal:

    gulp watch

    The result should be something like this:

    package.json file example

    Whenever you save your SCSS file, it will run the gulp command and send all SCSS files in your directory through your pipeline.

    package.json file example

    That’s it! If you have any questions, reach out.