• Stars
    star
    147
  • Rank 250,512 (Top 5 %)
  • Language
    JavaScript
  • Created over 9 years ago
  • Updated over 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Sass with JavaScript superpowers.

Sassport

Sassport logo

Plugins Quick Start Usage Assets Custom Modules Loaders Examples

JavaScript modules for Sass (node-sass). Easily share assets, and JavaScript functions and values in your Sass projects.

  • npm install sassport --save-dev
  • sassport([...]).render(...);

Available Plugins

Available Modules

Quick Start

  1. npm install sassport --save-dev
  2. Use sassport just like you would use Node-Sass (see example below)
  3. Use require() in your Sass (SCSS) stylesheets to import JS values (see example below)
  4. node index.js

EXAMPLE:

// index.js
var sassport = require('sassport');

sassport().render({
  file: 'path/to/stylesheet.scss'
}, function(err, result) {
  console.log(result.css.toString());
  // ... or whatever you want to do with the result
});
// path/to/my-colors.js
module.exports = {
  primary: '#C0FF33',
  secondary: '#B4D455'
};
// path/to/stylesheet.scss
$colors: require('path/to/my-colors'); // Just like Node require()!

.foo {
  color: map-get($colors, primary);
  
  &:hover {
    // Sassport uses inferred Sass values, not strings!
    color: lighten(map-get($colors, primary), 10%);
}

Result:

.foo {
  color: #C0FF33;
}

.foo:hover {
  color: #D0FF66;
}

Inspiration

Sassport was created to solve a few problems related to creating and maintaining Sass projects:

  • How can values be shared between JavaScript and Sass?
  • How can assets be easily included from 3rd-party modules, such as sprites, fonts, or other stylesheets?
  • Can remote asset URLs easily be managed, without hard-coding them in the stylesheets? (Yes!)
  • Can JavaScript functions be used inside Sass stylesheets? (Yes!)

The last question is especially important - it means that you can communicate with JavaScript from Sass to do complex tasks such as creating sprite sheets and receive useful information from the completed task's return value, such as image dimensions or sprite locations. With sassport.wrap(), it's possible to wrap entire JavaScript libraries for use inside your Sass project.

Is this similar to Sass Eyeglass? Yes, and no. Both projects achieve similar goals, with different philosophies. Eyeglass is based on convention - 3rd-party Eyeglass modules must be configured to be discoverable by Eyeglass via NPM. With Sassport, you explicity state which Sassport plugins (modules) you're going to use, which can come from anywhere - NPM, Bower, or even your own project. This is very similar to how PostCSS works.

Sassport is also agnostic and simple with assets - its only job is to copy assets from the source folder to your project's assets folder (inside the sassport-assets subdirectory). With this, you can wrap any plugin to transform your assets (see examples below). Sassport is not meant to be another asset management tool - Gulp, Grunt, Broccoli, etc. already exist for that.

Using Sassport modules

Sassport modules can provide extra functionality and give you access to module-specific stylesheets. The syntax for including Sassport modules is very similar to PostCSS' syntax:

EXAMPLE:

var sassport = require('sassport');

sassport([
  require('sassport-foo'), // example foo module
  require('sassport-bar')  // example bar module
]).render({
  file: 'path/to/stylesheet.scss'
}, function(err, result) { /* ... */ });
// path/to/stylesheet.scss
@import 'sassport-foo'; // imports default export(s)
                        // from sassport-foo module
@import 'sassport-bar'; 

@import 'sassport-bar/images'; // imports specific images export(s) 
                               // from sassport-bar module

When a Sassport module is included:

  • Sass functions from that module get imported automatically.
  • Sass variables and rulesets get imported when you @import 'that-module'.
  • Specified exports get imported when you @import 'that-module/specific-export'.

Managing Assets

To specify where your assets are, configure the asset paths by using the .assets(localAssetPath, remoteAssetPath) method. Then, you can use the Sass helper function resolve-url($source, $module: null) to generate the remote URL path. The $source is relative to the provided localAssetPath.

EXAMPLE:

var sassport = require('sassport');

sassport([ /* modules */ ])
  .assets(__dirname + '/assets', 'public/assets')
  .render(/* ... */);
.my-image {
  // Renders as:
  // background-image: url(public/assets/images/my-image.png);
  background-image: resolve-url('images/my-image.png');
}

When you @import assets (files or directories) from a Sassport module, those get copied into the sassport-assets/ subdirectory inside the provided localAssetPath. These assets can then be referenced in resolve-url() by specifying the $module that it came from.

EXAMPLE:

@import 'foo-module/images';

.their-image {
  // Renders as:
  // background-image: url(public/assets/sassport-assets/images/their-image.png);
  background-image: resolve-url('images/their-image.png', 'foo-module');
}

Creating Sassport Modules

A Sassport module is created with sassport.module(name). From there, you can use the below methods to configure your Sassport module:

  • .functions({...}) - Registers a collection of custom functions, just like in Node-Sass, with the Sassport module.
  • .variables({...}) - Registers Sass $variables whose values can either be Sass values or JS values (converted to Sass values automatically).
  • .exports({...}) - Registers exports whose values are either file paths or directory paths to Sass stylesheets or assets.

EXAMPLE:

var sassport = require('sassport');
var sass = require('node-sass');

module.exports = sassport.module('test')
  .functions({
    'greet($val)': function(val) {
      return sass.types.String('Hello, ' + val.getValue());
    },
    'greet-simple($value)': sassport.wrap(function(val) {
      return 'Hey, ' + val;
    })
  })
  .variables({
    '$a-number': 42,
    '$a-string': 'Sassport rocks!',
    '$a-list': [1, 2, 3, 4, 5],
    '$a-map': {a: 1, b: 2, c: 3}
  })
  .exports({
    'default': __dirname + '/stylesheets/main.scss', // @import 'test';
    'images': __dirname + '/images', // @import 'test/images';
  });
.greeting {
  test: greet('David'); // Hello, David
  test: greet-simple('David'); // Hey, David
}

With the sassport.wrap(fn, options) utility function, normal JS functions can be wrapped to automatically have arguments converted to JS values, and to automatically have the JS return value converted to Sass values using this conversion:

  • Number (Sass) - converted to a unitless JS number.
  • Number (JS) - converted to a unitless Sass number.
  • String (Sass) - converted to a JS string.
  • String (JS) - converted to an unquoted Sass string, unless {quotes: true} is specified for the options object.
  • List (Sass) - converted to a JS array.
  • Array (JS) - converted to a Sass list.
  • Map (Sass) - converted to a JS map-like object, with .get(key) and .set(key, value) methods.
  • Object (JS) - converted to a Sass map.
  • Bool (Sass) - converted to a JS boolean.
  • Boolean (JS) - converted to a Sass boolean.
  • Null (Sass) - converted to a JS null value.
  • null (JS) - converted to a Sass null value.

Also, sassport.utils provides Chris Eppstein's excellent node-sass-utils library.

Custom Loaders

You can now specify custom loaders for @import files by separating them with an ! after the import path. Here's an example that uses the Sassport reference module to load SCSS files by reference:

var sassport = require('sassport');

// The Sassport reference module provides:
// - a !reference loader
// - a reference() Sass function
var referenceModule = require('sassport/modules/reference');

sassport([ referenceModule ])
  .render({ file: 'main.scss' }, /* ... */);
// In path/to/_foo.scss:
@for $i from 1 through 10 {
  .col-#{$i} {
    display: block;
    width: percentage($i / 10);
  }
}

// In main.scss:
@import 'path/to/foo !reference';

.my-thing {
  @extend #{reference('.col-4')};
}

// Result CSS:
// Notice how the other column selectors never get output.
.my-thing {
  display: block;
  width: 40%;
}

Value Inference

By default, Sassport automatically infers Sass values from JavaScript strings. This means that you can seamlessly share CSS-like or (Sass-like) values as strings between JS and Sass, and Sassport will hand them over to sass as their inferred values, not as strings. For example:

  • "235px" becomes a Sass number with a px unit
  • "#C0FF33" becomes a Sass color (that looks nothing like coffee)
  • "3rem + 5rem" becomes a Sass number with value 8rem and a rem unit
  • "rebeccapurple" becomes a Sass color (yes, color keywords are understood)
  • "3px 5rem 0 auto" becomes a Sass list
  • "(a: 1, b: 2)" becomes a Sass map

To turn this option off, set infer to false as an option: sassport([...], { infer: false }).render(...). If you do this, you can selectively use inference in custom wrapped functions: sassport.wrap(fn, { infer: true });, or as a param in the Sass require() function as $infer: true.

Examples

Getting image dimensions

TERMINAL

npm install sassport image-size --save-dev

JAVASCRIPT

// index.js
var sassport = require('sassport');
var sizeOf = require('image-size');

sassport()
  .functions({
    'size-of($path)': sassport.wrap(function(path) {
      return sizeOf(path);
    }, { unit: 'px' })
  })
  .assets('./assets', 'public/assets')
  .render({
    file: 'stylesheet.scss'
  }, function(err, res) {
    console.log(res.css.toString());
  });

SCSS

// stylesheet.scss
$image-path: 'sassport-sm.png';
$image-size: size-of(resolve-path($image-path));

.my-image {
  background-image: resolve-url($image-path);
  width: map-get($image-size, 'width');
  height: map-get($image-size, 'height');
}

RESULT (CSS)

.my-image {
  background-image: url(public/assets/sassport-sm.png);
  width: 145px;
  height: 175px;
}

More Repositories

1

react-redux-form

Create forms easily in React with Redux.
JavaScript
2,066
star
2

flipping

Flipping awesome animations.
TypeScript
1,380
star
3

useEffectReducer

useReducer + useEffect = useEffectReducer
TypeScript
791
star
4

RxCSS

JavaScript
416
star
5

sassdash

The Sass implementation of lodash.
SCSS
386
star
6

sass-svg

Inline SVG for Sass.
CSS
314
star
7

frontend-masters-xstate-workshop

Frontend Masters State Machines & XState Workshop
JavaScript
243
star
8

frontend-masters-css

SCSS
169
star
9

frontend-masters-react-workshop

Code for the Frontend Masters React State Modeling Workshop
JavaScript
128
star
10

nm8

Ridiculously small animation library.
TypeScript
122
star
11

frontend-masters-xstate-v2

Frontend Masters XState Workshop v2
JavaScript
121
star
12

react-simple-datepicker

Simple datepicker for React.
JavaScript
119
star
13

xstate-test-demo

Demo React project for model-based testing with @xstate/test
JavaScript
111
star
14

durable-entities-xstate

XState + Durable Entities = 🚀
TypeScript
53
star
15

xstate-react-workshop

React Finland - Modeling React Applications with Statecharts Workshop
JavaScript
24
star
16

weatherboard

TypeScript
23
star
17

xviz

Small graph visualization library
TypeScript
19
star
18

propelcss

CSS
19
star
19

postcss-emoji-style

JavaScript
19
star
20

xstate-todomvc

Created with CodeSandbox
JavaScript
18
star
21

xstate-examples

Example XState Projects
17
star
22

xstate-command

Command palette with XState
TypeScript
12
star
23

react-finland-xstate-2022

React Finland 2022 XState Workshop
JavaScript
11
star
24

mbt-workshop

Model-Based Testing Workshop
JavaScript
11
star
25

react-finland-xstate-workshop

React Finland XState Workshop
JavaScript
11
star
26

sass-v

CSS Custom Properties + Sass = 🚀
SCSS
10
star
27

RxAnimate

Reactive Animations
TypeScript
10
star
28

openapi-test

OpenAPI Testing Library
TypeScript
10
star
29

node-azure-mvc

Example application for creating an MVC Express + Node + TypeScript app and deploying it to Azure
TypeScript
10
star
30

redux-test-store

Test existing stores in Redux, the easy way
JavaScript
8
star
31

skylake

💎 A light JavaScript library.
JavaScript
8
star
32

xstate-interpreter

Reactive statechart interpreter.
TypeScript
7
star
33

paz

Peaceful Azure deployments with node
6
star
34

movement

Sass/SCSS/CSS animation framework for creating, composing, sequencing, and using animations.
CSS
6
star
35

davidkpiano

5
star
36

getrect

TypeScript
5
star
37

rxio

TypeScript
4
star
38

xstate-tetris

TypeScript
4
star
39

issuspensereadyyet

...
JavaScript
4
star
40

tracker

Track DOM elements efficiently.
4
star
41

netlify-edge-machine

TypeScript
4
star
42

neo4j-workshop

Neo4j Statecharts Workshop
JavaScript
3
star
43

rxform

TypeScript
3
star
44

gulp-sassport

Sassport gulp plugin
JavaScript
3
star
45

sassport-reference

Import by Reference in Sass using Sassport
JavaScript
3
star
46

vanilla-todomvc-ts

TypeScript
3
star
47

cadenza-old

SCSS/CSS Framework
CSS
2
star
48

movi

Stately animations
2
star
49

cse-articles

Microsoft CSE Articles
2
star
50

rxstyle

Animation framework for RxJS
JavaScript
2
star
51

sassport-svgo

Inline, optimized SVG inside your Sass files.
JavaScript
2
star
52

sassport-dynamic

Dynamic imports for Node-Sass using Sassport
JavaScript
2
star
53

rrf-docs

CSS
2
star
54

react-redux-form-builder

React Redux Form Builder
JavaScript
2
star
55

webanimate

TypeScript
2
star
56

stately-site

HTML
2
star
57

cz-temp

CSS
2
star
58

angular-fluid

Form Logic User Interface Directive - Form Logic implementation for AngularJS
CSS
2
star
59

orlandodevs-site

HTML
1
star
60

react-redux-form-docs

1
star
61

styledash

JavaScript
1
star
62

react-state-machine

Finite State Machines for React.
1
star
63

logicapp-specflow-demo

C#
1
star
64

generator-sass-guide

Yeoman generator for Sass Guidelines
JavaScript
1
star
65

sassport-math

Math for Sass.
JavaScript
1
star
66

emojio

1
star
67

goatspresso

Goats and Espresso
JavaScript
1
star
68

test-gen-demo

TypeScript
1
star
69

react-redux-form-book

1
star
70

postcss-movement

1
star
71

rxy

For Atomic Hack Party
PHP
1
star
72

movt

Movement
JavaScript
1
star
73

react-dynamic

Dynamic.js Animation Library for React
1
star
74

styleguides

1
star
75

react-move

Nothing to see here
JavaScript
1
star
76

cadenza

1
star
77

sass-z

Z-index management for Sass.
1
star
78

eyeglass-math

Math. For Sass.
JavaScript
1
star