Skip to content

Supplies a set of functions to Sass that keep physical asset location details out of your source code

License

localnerve/sass-asset-functions

Repository files navigation

Sass Asset Functions

Supplies a set of functions to Sass that keep physical asset location details out of your source code. Allows one to define a cache-busting policy, specify asset hosts by url, and use arbitrary build-time metadata to drive css generation.

Verify npm version Coverage Status

Overview

This module provides a set of Sass functions that help with asset management in web projects, similar to what Compass provided. You can use functions like image-url() instead of plain url() and the module will automatically resolve paths correctly based on your build configuration. Further, you can expose arbitrary built-time metadata (typically from image processors) for use in sass to generate image references, dimensions, types, breakpoints, etc.

This is a sass compiler plugin that uses the functions option of the sass javascript api. Supports modern and legacy sass javascript api: render, compile, and compileAsync

Origin/History

This module provides some of the asset functions that came with Compass. Originally a fork of node-sass-asset-functions that was never merged.

Release Notes

Changelog

Functions Exposed to Sass

  • image-url($filename: null, $only_path: false)
  • image-width($filename: null)
  • image-height($filename: null)
  • font-url($filename: null, $only-path: false)
  • font-files($filenames...)
  • inline-image($filename: null, $mime-type: null)
  • lookup($keys...)

Usage

Basic usage is as easy as setting the functions property:

// non-module, require usage
const sass = require('sass');
const { default: assetFunctions } = require('@localnerve/sass-asset-functions');

const result = sass.compile(scss_filename, {
  functions: assetFunctions(/* options */)
  [, options...]
});
// module usage
import sass from 'sass';
import assetFunctions from '@localnerve/sass-asset-functions';

const result = sass.compile(scss_filename, {
  functions: assetFunctions(/* options */)
  [, options...]
});

Options

All options are optional.

name type description
sass Object A reference to an alternate Sass compiler to use other than dart-sass (must expose types). Defaults to undefined and a dart-sass reference is used
legacyAPI Boolean truthy to use the legacy sass API via the sass render function. Defaults to false
async Boolean truthy to use modern sass API via the compileAsync function. Required if supplied asset_cache_buster or asset_host function options are asynchronous. Defaults to false
images_path String The build-time file path to images. Defaults to public/images
fonts_path String The build-time file path to fonts. Defaults to public/fonts
http_images_path String The path to images as seen from the web (nothing to do with http). Defaults to /images
http_fonts_path String The path to images as seen from the web (nothing to do with http). Defaults to /fonts
asset_cache_buster Function Signature (http_path, real_path, callback(new_url)). Supply to perform url transform for image-url or font-url, presumably for asset cache busting, but useful for any change to the url path (before fragment)
asset_host Function Signature (http_path, callback(new_url)). Supply to perform url transform for image-url or font-url, presumably to define an asset host, but useful for any change to the url before the path
data Object An object of arbitrary data to reference at build-time. Defaults to (empty)

Advanced Options Quick Links

  • Asset Cache Buster: Modify URLs for cache busting (e.g., adding version numbers)
  • Asset Host: Set custom hostnames for assets
  • Data Lookup: Pass arbitrary data from JavaScript to Sass via the lookup() function

Examples

You can specify the paths to your resources using the following options (shown with defaults):

{
  images_path: 'public/images', // local directory
  http_images_path: '/images',  // map to web path
  fonts_path: 'public/fonts',   // local directory
  http_fonts_path: '/fonts',    // map to web path
  data: {}                      // build data exposed by *lookup*
}

So if your project images reside in public/img at build-time instead of public/images, you use it as follows:

const sass = require('sass');
const { default: assetFunctions } = require('@localnerve/sass-asset-functions');

const result = sass.compile(scss_filename, {
  functions: assetFunctions({
    images_path: 'public/img',  // the local path to the assets 
    http_images_path: '/images' // the path from the browser to the assets
  })
  [, options...]
});

lookup: a function to use arbitrary data in sass stylesheets

This function retrieves arbitrary build-time data for reference in stylesheet compilation. Could be an asset name, prefix, or could be a whole list or map of things. Here's the list of javascript type mappings (everything else returns SassNull):

  • Boolean => SassBoolean
  • Number => SassNumber
  • String => SassString
  • Array => SassList
  • Set => SassList
  • Object => SassMap
  • Map => SassMap
const result = sass.compile(scss_filename, {
  functions: assetFunctions({
    data: {
      'hero-image-names': {
        big: 'hero-1920x300.webp',
        medium: 'hero-1440x300.webp',
        small: 'hero-1024x300.webp'
      },
      nested: {
        process: true,
        'process-map': {
          one: 'one',
          two: 'two'
        }
      }
    }
  })
});
$hero-images: lookup('hero-image-names');
@each $key, $val in $hero-images {
  .hero-image-#{$key} {
    background-image: image-url($val);
  }
}

$nested-process: lookup('nested', 'process');
$nested-data: lookup('nested', 'process-map');
@if $nested-process {
  @each $key, $val in $nested-data {
    .process-#{$key} {
      content: '#{$val}';
    }
  }
}

asset_host: a function which completes with a string used as asset host.

const result = sass.compile(scss_filename, {
  functions: assetFunctions({
    asset_host: (http_path, done) => {
      done('http://assets.example.com');
      // or use the supplied path to calculate a host
      done(`http://assets${http_path.length % 4}.example.com`);
    }
  })
  [, options...]
});

asset_cache_buster: a function to rewrite the asset path

When this function returns a string, it's set as the query of the path. When returned an object, path and query will be used.

const result = sass.compile(scss_filename, {
  functions: assetFunctions({
    asset_cache_buster: (http_path, real_path, done) => {
      done('v=123');
    }
  })
  [, options...]
});
A more advanced example of asset_cache_buster:

Here we include the file's hexdigest in the path, using the hexdigest module.

For example, /images/myimage.png would become /images/myimage-8557f1c9b01dd6fd138ba203e6a953df6a222af3.png.

const sass = require('sass');
const path = require('path');
const fs = require('fs');
const hexdigest = require('hexdigest');
const { default: assetFunctions } = require('@localnerve/sass-asset-functions');

const result = sass.compileAsync(scss_filename, {
  functions: assetFunctions({
    async: true,
    asset_cache_buster: (http_path, real_path, done) => {
      hexdigest(real_path, 'sha1', (err, digest) => {
        if (err) {
          // an error occurred, maybe the file doesn't exist.
          // Calling `done` without arguments will result in an unmodified path.
          done();
        } else {
          const extname = path.extname(http_path);
          const basename = path.basename(http_path, extname);
          const new_name = `${basename}-${digest}${extname}`;
          done({path: path.join(path.dirname(http_path), new_name), query: null});
        }
      });
    }
  })
  [, options...]
});

sass: Overriding the default compiler with Node-Sass

Example using the node-sass compiler using the new option sass.

const sass = require('node-sass');
const { default: assetFunctions } = require('@localnerve/sass-asset-functions');

const result = sass.compile(scss_filename, {
  functions: assetFunctions({ sass })
  [, options...]
});

As of version 7.0.0, node-sass integration is no longer tested

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

About

Supplies a set of functions to Sass that keep physical asset location details out of your source code

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •