SASS with Gulp and Hugo

August 2017 · 3 minute read

Gulp Pipeline

Create a src directory to store your precompiled assets in.

$ mkdir -p src/{scss,js,images}

Initialise NPM

$ npm init -y

Add node_modules into your .gitignore - You won’t want to store that in your repository

Install Gulp and Gulp-sass npm packages

You will now see a new directory in your project root called node_modules containing those modules

You will also see those files included under devDependencies in your package.json

$ npm install –save-dev gulp gulp-sass gulp-autoprefixer

Install gulp-cli globally to make it available from the command line > $ npm install –global gulp-cli

You can optionally add scripts to your package.json:

"scripts": {
	"gulp": "gulp",
	"minify": "gulp minify"
}

Create gulp file in your project root

$ touch gulpfile.js

In the file, require your gulp dependencies and write the build tasks:

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

var input = './themes/docs-hg/src/scss/**/*.scss';
var output = './themes/docs-hg/static/styles';

// Compile scss into css
gulp.task('scss', function() {
  return gulp
    // Find all `.scss` files from the `stylesheets/` folder
    .src(input)
    // Run Sass on those files
    .pipe(sass())
    // Write the resulting CSS in the output folder
    .pipe(gulp.dest(output));
});

// Watch scss directory
gulp.task('watch', ['scss'], function() {
    gulp.watch('./themes/docs-hg/src/scss/**/*', ['scss'])
});

// Set watch as default task
gulp.task('default', ['watch']);

Check that it worked

Write a style in your src/scss/main.scss

$black: #000;
body {
  background: $black;
}

Run your gulp sass function to see your css compiled in a new main.css file

$ gulp css

Ensure it’s being loaded correctly by running the Hugo server

$ Hugo server

NB: One Key thing to remember after this is that you will need to compile your styles before deploying any updates to s3


Hash Manifests

Build hash manifests

In gulpfile.js

$ npm install –save-dev gulp-hash del

var hash = require('gulp-hash');
var del = require('del');

// Compile scss into css
gulp.task('scss', function() {
  del(['./hugo/themes/docs-hg/static/styles/**/*'])
    // Find all `.scss` files from the `styles/` folder
  gulp.src(input)
    // Run Sass on those files
    .pipe(sass({ outputStyle: 'compressed' }))
    .pipe(autoprefixer({ browsers: ["last 20 versions"] }))
    .pipe(hash())
    // Write the resulting CSS in the output folder
    .pipe(gulp.dest(output))
    // Build css hash manifest
    .pipe(hash.manifest('hash.json', {
      deleteOld: true,
      sourceDir: './hugo/themes/docs-hg/static/styles'
    })) // Switch to the manifest file 
    .pipe(gulp.dest('./hugo/data/css')); // Write the manifest file 
});

Using hash manifests

Index is a Go built-in function that accepts a map and an index and returns the value of the map with the given index. So here we are asking Hugo to give us the value in .Site.Data.css.hash that has the index “main.css”… which of course is the filename of the hashed asset file.

So in our layouts, instead of directly referencing the file /css/main.css we need to do a lookup…

The css link tag originally looked like this…

<link rel="stylesheet" href=“/styles/main.css" />

Will now look like this…

<link rel="stylesheet" href='/styles/{{ index .Site.Data.css.hash "main.css" }}' type="text/css" />