npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sass-parser

v0.4.3

Published

A PostCSS-compatible wrapper of the official Sass parser

Downloads

689

Readme

A PostCSS-compatible CSS and Sass parser with full expression support.

Warning: sass-parser is still in active development, and is not yet suitable for production use. At time of writing it only supports a small subset of CSS and Sass syntax. In addition, it does not yet support parsing raws (metadata about the original formatting of the document), which makes it unsuitable for certain source-to-source transformations.

Using sass-parser

  1. Install the sass-parser package from the npm repository:

    npm install sass-parser
  2. Use the scss, sass, or css Syntax objects exports to parse a file.

    const sassParser = require('sass-parser');
    
    const root = sassParser.scss.parse(`
      @use 'colors';
    
      body {
        color: colors.$midnight-blue;
      }
    `);
  3. Use the standard PostCSS API to inspect and edit the stylesheet:

    const styleRule = root.nodes[1];
    styleRule.selector = '.container';
    
    console.log(root.toString());
    // @use 'colors';
    //
    // .container {
    //   color: colors.$midnight-blue;
    // }
  4. Use new PostCSS-style APIs to inspect and edit expressions and Sass-specific rules:

    root.nodes[0].namespace = 'c';
    const variable = styleRule.nodes[0].valueExpression;
    variable.namespace = 'c';
    
    console.log(root.toString());
    // @use 'colors' as c;
    //
    // .container {
    //   color: c.$midnight-blue;
    // }

Why sass-parser?

We decided to expose Dart Sass's parser as a JS API because we saw two needs that were going unmet.

First, there was no fully-compatible Sass parser. Although a postcss-scss plugin did exist, its author requested we create this package to fix compatibility issues, support the indented syntax, and provide first-class support for Sass-specific rules without needing them to be manually parsed by each user.

Moreover, there was no robust solution for parsing the expressions that are used as the values of CSS declarations (as well as Sass variable values). This was true even for plain CSS, and doubly problematic for Sass's particularly complex expression syntax. The postcss-value-parser package hasn't been updated since 2021, the postcss-values-parser since January 2022, and even the excellent @csstools/css-parser-algorithms had limited PostCSS integration and no intention of ever supporting Sass.

The sass-parser package intends to solve these problems by providing a parser that's battle-tested by millions of Sass users and flexible enough to support use-cases that don't involve Sass at all. We intend it to be usable as a drop-in replacement for the standard PostCSS parser, and for the new expression-level APIs to feel highly familiar to anyone used to PostCSS.

API Documentation

The source code is fully documented using TypeDoc. Hosted, formatted documentation will be coming soon.

PostCSS Compatibility

PostCSS is the most popular and long-lived CSS post-processing framework in the world, and this package aims to be fully compatible with its API. Where we add new features, we do so in a way that's as similar to PostCSS as possible, re-using its types and even implementation wherever possible.

Statement API

All statement-level AST nodes produced by sass-parser—style rules, at-rules, declarations, statement-level comments, and the root node—extend the corresponding PostCSS node types (Rule, AtRule, Declaration, Comment, and Root). However, sass-parser has multiple subclasses for many of its PostCSS superclasses. For example, sassParser.PropertyDeclaration extends postcss.Declaration, but so does sassParser.VariableDeclaration. The different sass-parser node types may be distinguished using the sassParser.Node.sassType field.

In addition to supporting the standard PostCSS properties like Declaration.value and Rule.selector, sass-parser provides more detailed parsed values. For example, sassParser.Declaration.valueExpression provides the declaration's value as a fully-parsed syntax tree rather than a string, and sassParser.Rule.selectorInterpolation provides access to any interpolated expressions as in .prefix-#{$variable} { /*...*/ }. These parsed values are automatically kept up-to-date with the standard PostCSS properties.

Expression API

The expression-level AST nodes inherit from PostCSS's Node class but not any of its more specific nodes. Nor do expressions support all the PostCSS Node APIs: unlike statements, expressions that contain other expressions don't always contain them as a clearly-ordered list, so methods like Node.before() and Node.next aren't available. Just like with sass-parser statements, you can distinguish between expressions using the sassType field.

Just like standard PostCSS nodes, expression nodes can be modified in-place and these modifications will be reflected in the CSS output. Each expression type has its own specific set of properties which can be read about in the expression documentation.

Constructing New Nodes

All Sass nodes, whether expressions, statements, or miscellaneous nodes like Interpolations, can be constructed as standard JavaScript objects:

const sassParser = require('sass-parser');

const root = new sassParser.Root();
root.append(new sassParser.Declaration({
  prop: 'content',
  valueExpression: new sassParser.StringExpression({
    quotes: true,
    text: new sassParser.Interpolation({
      nodes: ["hello, world!"],
    }),
  }),
}));

However, the same shorthands can be used as when adding new nodes in standard PostCSS, as well as a few new ones. Anything that takes an Interpolation can be passed a string instead to represent plain text with no Sass expressions:

const sassParser = require('sass-parser');

const root = new sassParser.Root();
root.append(new sassParser.Declaration({
  prop: 'content',
  valueExpression: new sassParser.StringExpression({
    quotes: true,
    text: "hello, world!",
  }),
}));

Because the mandatory properties for all node types are unambiguous, you can leave out the new ...() call and just pass the properties directly:

const sassParser = require('sass-parser');

const root = new sassParser.Root();
root.append({
  prop: 'content',
  valueExpression: {quotes: true, text: "hello, world!"},
});

You can even pass a string in place of a statement and PostCSS will parse it for you! Warning: This currently uses the standard PostCSS parser, not the Sass parser, and as such it does not support Sass-specific constructs.

const sassParser = require('sass-parser');

const root = new sassParser.Root();
root.append('content: "hello, world!"');

Known Incompatibilities

There are a few cases where an operation that's valid in PostCSS won't work with sass-parser:

  • Trying to convert a Sass-specific at-rule like @if or @mixin into a different at-rule by changing its name is not supported.

  • Trying to add child nodes to a Sass statement that doesn't support children like @use or @error is not supported.

Contributing

Before sending out a pull request, please run the following commands from the pkg/sass-parser directory:

  • npm run check - Runs eslint, and then tries to compile the package with tsc.

  • npm run test - Runs all the tests in the package.

Note: You should run dart run grinder before-test from the dart-sass directory beforehand to ensure you're running sass-parser against the latest version of dart-sass JavaScript API.