Using Gulp with Dart Sass

13th May 2021

I’m playing around with Sass again recently and I noticed newer features (like @use and @forward) are only available on Dart Sass. Upon further inspection, I noticed that LibSass is now deprecated.

This article aims to help you get started with Dart Sass if you’re using Gulp.

Setting up Gulp

First, you need to install Gulp.

npm install gulp --save-dev

Second, you need to create a file called gulpfile.js inside your project.

- project
  |- gulpfile.js 

We will require gulp in this gulpfile. I’m destructuring src and dest at the same time since we’ll use them later.

const {src, dest} = require('gulp')

Next let’s create a css function to transpile Sass to CSS. Make sure you change the src and dest values to match the appropriate folders in your project.

function css () {
  // ... 
  return src('src/scss/**/*.{scss,sass}')
    .pipe(dest('dist/css'))
}

Gulp will register a css command if you export this css from the Gulpfile.

exports.css = css

You should be able to run gulp css if you have Gulp installed globally on your computer. Otherwise, you can run npx gulp css.

gulp css
Run npx gulp css

Transpiling Sass to CSS with Dart Sass

We need two things to use Dart Sass with Gulp:

We can install them both like this:

npm install gulp-sass sass --save-dev

We will require both gulp-sass and sass in the Gulpfile.

gulp-sass uses Libsass by default. We can change it to Dart Sass by changing the compiler property.

const sass = require('gulp-sass')
sass.compiler = require('sass')

We can now transpile Sass to CSS.

function css () {
  return src('src/scss/**/*.{scss,sass}')
    .pipe(sass().on('error', sass.logError))
    .pipe(dest('dist/css'))
}

The sass.logError part is important because it allows any errors to be emitted into the Terminal. Without this, you won’t be able to watch Sass files for changes - any errors would stop the watching of files. (More on watching files later).

Including special paths

If you’ve downloaded any packages with npm, you can include them in gulp-sass so you can write lesser code to import the file. includePath takes in an array. Feel free to include any additional paths if you need to!

function css () {
  return src('src/scss/**/*.{scss,sass}')
    .pipe(
      sass({includePaths: ['./node_modules']})
        .on('error', sass.logError)
    )
    .pipe(dest('dist/css'))
}
// Without includePaths
@use '../../node_modules/package'

// With includePaths
@use 'package'

Increasing compile speed

Synchronous Dart Sass is two times faster than asynchronous Dart Sass. Unfortunately for us, Gulp runs asynchronously. But it’s important for Gulp to be asynchronous so we can process multiple tasks at the same time.

I wrote a book on Automating Your Workflow with Gulp a while ago. The contents are dated (it’s written for Gulp v3, but we’re working with Gulp v4 now).
Although the contents are dated, it should still give you a good understanding on how a developer workflow works and how to set it up. Check it out if you’re interested!

To improve Dart Sass compilation speed, we can use a package called fibers.

npm install fibers --save-dev
const Fiber = require('fibers')

function css () {
  return src('src/scss/**/*.{scss,sass}')
    .pipe(
      sass({
        includePaths: ['./node_modules'],
        fiber: Fiber
      })
        .on('error', sass.logError)
    )
    .pipe(dest('dist/css'))
}

I have no idea what fibers does at this point. I haven’t figured it out yet. I’m just adding it because the official docs recommend it. ¯_(ツ)_/¯

Although Dart Sass is 1.5x slower compared to Libsass, there’s practically no performance hit unless you’re working with a humongous code base. So feel free to switch!

Sourcemaps, PostCSS, and extra plugins

You can add PostCSS plugins like autoprefixer by requiring them in the gulpfile too. Here’s how to include autoprefixer.

npm install gulp-postcss autoprefixer --save-dev
const postcss = require('gulp-postcss')
const autoprefixer = require('autoprefixer')

function css () {
  return src('src/scss/**/*.{scss,sass}')
    .pipe(sass(/* ... */).on(/* ... */))
    .pipe(postcss([autoprefixer()]))
    .pipe(dest('dist/css'))
}

You can include sourcemaps as well.

npm install gulp-sourcemaps --save-dev
function css () {
  return src('src/scss/**/*.{scss,sass}')
    .pipe(sourcemaps.init())
    .pipe(sass(/* ... */).on(/* ... */))
    .pipe(postcss(/* ... */))
    .pipe(sourcemaps.write())
    .pipe(dest('dist/css'))
}

Watching Sass files for changes

When a Sass file changes, we want to compile the new Sass into CSS. We can do this with a watcher function.

function watcher (cb) {
  
}

In watcher we need to use gulp.watch. gulp.watch lets us watch files and perform gulp tasks when the files are changed. It takes in three arguments

  1. The files to watch
  2. Gulp tasks to execute when the files changes
  3. A callback to tell Gulp the execute is complete

Here’s how we can watch our sass files for changes and compile them into CSS when we save a file.

const {src, dest, watch} = gulp

function watcher (cb) {
  watch('src/scss/**/*.{scss,sass}', css, cb)  
}

That’s it! Now go ahead and add Dart Sass into your workflow 🤓

If you enjoyed this article, please tell a friend about it! Share it on Twitter. If you spot a typo, I’d appreciate if you can correct it on GitHub. Thank you!

Hold on while i sign you up…

🤗
Woohoo! You’re in!
Now, hold on while I redirect you.