Using Gulp with Dart Sass

Zell Liew 🤗 - May 24 '21 - - Dev Community

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
Enter fullscreen mode Exit fullscreen mode

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

- project
  |- gulpfile.js 
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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'))
}
Enter fullscreen mode Exit fullscreen mode

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

exports.css = css
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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'))
}
Enter fullscreen mode Exit fullscreen mode

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'))
}
Enter fullscreen mode Exit fullscreen mode
// Without includePaths
@use '../../node_modules/package'

// With includePaths
@use 'package'
Enter fullscreen mode Exit fullscreen mode

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.

Note: 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
Enter fullscreen mode Exit fullscreen mode
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'))
}
Enter fullscreen mode Exit fullscreen mode

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. ¯_(ツ)_/¯

Note: 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
Enter fullscreen mode Exit fullscreen mode
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'))
}
Enter fullscreen mode Exit fullscreen mode

You can include sourcemaps as well.

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

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) {

}
Enter fullscreen mode Exit fullscreen mode

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)  
}
Enter fullscreen mode Exit fullscreen mode

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


Thanks for reading. This article was originally posted on my blog. Sign up for my newsletter if you want more articles to help you become a better frontend developer.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .