Last Updated: February 25, 2016
·
3.247K
· yavorskiy

Inlining images with gulp-sass

Compass witch I use to use for SCSS-based project provides count of useful functions like inline-image. I found those are really missing when switched to gulp-sass (internally using node-sass) for pre-processing stylesheets.

Luckily there is the way to write custom functions to add missing functionality.

Following example illustrates the idea

SCSS source:

.my-class { 
  background: #{inline-image('src/images/transparent.png')};
}

Which would be compiled into:

.my-class {
  background: url(data:image/png;base64,iVBORw0KG...);
}

And here is the Gulp magic


/* ----- inline-image(pathToFile) ----- */

function sassFunctions(options) {
  options = options || {};
  options.base = options.base || process.cwd();

  var fs        = require('fs');
  var path      = require('path');
  var types     = require('node-sass').types;

  var funcs = {};

  funcs['inline-image($file)'] = function(file, done) {
    var file = path.resolve(options.base, file.getValue());
    var ext  = file.split('.').pop();
    fs.readFile(file, function(err, data) {
      if (err) return done(err);
      data = new Buffer(data);
      data = data.toString('base64');
      data = 'url(data:image/' + ext + ';base64,' + data +')';
      data = types.String(data);
      done(data);
    });
  };

  return funcs;
}

/* ----- Gulp task ----- */

return gulp.src([
  'stylesheets/**/*.scss', 
  '!src/styles/**/_*.scss'
])
  .pipe(sass({
    outputStyle: argv.optimize ? 'compressed' : 'nested',
    functions: sassFunctions()
  }))
  .pipe(gulp.dest('css/'));
});