Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.
/ libsass-asm Public archive

WebAssembly based Javascript bindings for libsass

License

Notifications You must be signed in to change notification settings

kwonoj/libsass-asm

Repository files navigation

CircleCI npm node

libsass-asm

libsass-asm is javascript binding to libsass based on WebAssembly libsass binary. This module aims to provide transparent binding to libsass without requiring native modules, to serve as building blocks for tools.

  • Node.js only : libsass-asm intended to be used for node.js based toolchains.
  • Native WebAssembly binary : Does not provide fallbacks for old version support, works only on node.js supports native web assembly.
  • Transparent binding to libsass interface : Provides 1:1 corresponding interfaces to libsass, furthermore exposes raw interface to libsass itself.

Install

npm install libsass-asm

Usage

Using libsass interface

libsass-asm relies on wasm binary of libsass, which need to be initialized first.

import { loadModule } from 'libsass-asm';

const sassFactory: SassFactory = await loadModule();

loadModule loads wasm binary, initialize it, and returns factory object to create instance of sass interface class. Factory object provide static creation method for each sass* interfaces, for example you can create class to handle sass_options* interface via

const sassOptions: SassOptionsInterface = sassFactory.options.create();

then via sassOptions object can invoke sass_options* interface.

Snippet of SassOptionsInterface

interface SassOptionsInterface {
  ...
  /**
   * Property accessor to `sass_option_(get|set)_precision`
   */
  precision: number;

  /**
   * Property accessor to `sass_option_(get|set)_output_style`
   */
  outputStyle: OutputStyle;

  /**
   * Property accessor to `sass_option_(get|set)_source_comments`
   */
  sourceComments: boolean;

  /**
   * Property accessor to `sass_option_(get|set)_is_indented_syntax_src`
   */
  isIndentedSyntaxSrc: boolean;

  /**
   * Property accessor to `sass_option_(get|set)_omit_source_map_url`
   */
  omitMapComment: boolean;
  ...
}

Mounting files

WebAssembly binary's memory space is separately allocated and cannot use node.js's filesystem access directly. To support it libsass-asm exposes few interfaces interop physical file via SassFactory::interop object.

  • mount(dirPath: string): string : mount physical path. Once directory is mounted libsass can read all files under mounted path. Returns virtual path to mounted path.
  • unmount(mountedFilePath: string): void : Unmount path if it's mounted.

All of virtual paths for mounted filesystem uses unix separator regardless of platform.

Note when setting options for libsass, it should be mounted path instead of physical path since libsass will try to read via mounted path only.

const inputFile = path.resolve('./input.scss');
const mountedPath = sassFactory.interop.mount('./');

const sassOptions: SassOptionsInterface = sassFactory.options.create();

sassOptions.inputPath = inputFile; //this will fail!
sassOptions.inputPath = unixify(path.join(mountedPath, 'input.scss'));

If input file have import paths, those paths should be mounted as well.

Using libsass interface without class factory (advanced)

Most of sass_* bindings in SassFactory are written in ES classes. If you prefer to directly deal with C api style of libsass instead you can use SassFactory::raw object. libsass-asm internally contains wrapped function to call libsass functions in javascript, raw object exposes it directly.

const { raw } = await loadModule();

//calling `struct Sass_Options* sass_make_options (void);`
const sassOptionPtr: number = raw.context.make_options();

As written in above snippet, those interface does not marshall any values but return pointers directly so it have to be dealt with.

Using cli

In addition to interface to libsass, libsass-asm provides cli as well. This is primarily to be used to run test suite for libsass but can be used fo other usage as well.

$ sass -h

Options

  -s, --stdin               Read input from standard input instead of an input file.
  -t, --style               Output style. Can be: nested, expanded, compact, compressed.
  -l, --line-numbers        Emit comments showing original line numbers.
  -I, --load-path           Set Sass import path.
  -P, --plugin-path         Set path to autoload plugins.
  -m, --sourcemap           Emit source map (auto or inline).
  -M, --omit-map-comment    Omits the source map url comment.
  -p, --precision number    Set the precision for numbers.
  -a, --sass                Treat input as indented syntax.
  -v, --version             Display compiled versions.
  -h, --help                Display this help message.
  --files string[]          Specifies files for in order of [INPUT] [OUTPUT]
                            Do not need to explicitly specify --files args
  --root string[]           Top level path where sass inputs are located if there are import paths exist
                            other than input path.

Enabling verbose debug log

  Set 'DEBUG' environment variable to any to enable debug log
  $ DEBUG=* sass ...

Command line args interface mostly mirrors sassc, one notable difference is providing root options to specify which path to mount other than input file's path.

Building / Testing

Few npm scripts are supported for build / test code.

  • build: Transpiles code to ES5 commonjs to dist.
  • lint: Run lint over all codebases
  • lint:staged: Run lint only for staged changes. This'll be executed automatically with precommit hook.
  • commit: Commit wizard to write commit message

License

NOTE: libsass-asm is NOT affiliated with official libsass and sass project.