Socket
Socket
Sign inDemoInstall

rockey-css-parse

Package Overview
Dependencies
1
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    rockey-css-parse

Dynamic CSS string parser


Version published
Weekly downloads
1
decreased by-80%
Maintainers
1
Install size
1.41 MB
Created
Weekly downloads
 

Readme

Source

Rockey CSS Parse

Very fast function to parse dynamic CSS (with JS functions inside) and generate CSS string according to props. And very small (~5kb gzipped).

CSS in JS. Rockey

npm install --save rockey-css-parse

Rockey tests rockey-css-parse gzip size

Table of contents:

Perfomance

rockey-css-parse is very fast but note that it does not generate AST tree. rockey uses another easy format for fast CSS generating with dynamic CSS supporting.

Used libraries in benchmark:

To run benchmarks for CSS with nested selector:

npm run bench:nested -- --size=10000

To run benchmarks for native CSS string:

npm run bench:native -- --size=10000
results

NOTE that benchmarks is not 100% correct because each lib was developed for different goals. And there are very different libs features.

Nested CSS syntax for 1000 blocks (screenshot nested 1000):

  • rockey parseOptimize - 0.521 sec
  • rockey parse - 0.771 sec
  • postcssNested - 1.7 sec
  • postcssNestedSafeParser - 1.961 sec
  • stylis - 8.68 sec

Nested CSS syntax for 10000 blocks (screenshot nested 10000):

  • rockey parseOptimize - 4.949 sec
  • rockey parse - 7.154 sec
  • postcssNested - 19.251 sec
  • postcssNestedSafeParser - 22.169 sec
  • stylis - failed

Native CSS syntax for 1000 blocks (screenshot native 1000):

  • rockey parseOptimize - 0.402 sec
  • postcssSafeParser - 0.439 sec
  • postcss - 0.452 sec
  • rockey parse - 0.504 sec
  • stylis - 0.568 sec
  • css - 0.504 sec

Native CSS syntax for 10000 blocks (screenshot native 10000):

  • stylis - 1.88 sec
  • rockey parseOptimize - 3.586 sec
  • postcssSafeParser - 3.622 sec
  • postcss - 3.831 sec
  • css - 4.674 sec
  • rockey parse - 4.927 sec

Parse Usage

import hash from 'rockey-css-parse/utils/hash';
import createParser from 'rockey-css-parse';

const parse = createParser({
  getClassName: component => `${component}-${hash()}`,
  getMixinName: mixin => `m-${mixin}`,
  getAnimationName: animation => `a-${animation}`,
  plugins: []
});

All config props are optional.

  • getClassName(component) - generate component classname. Takes original component name as first argument. Results are cached per parse call - so fell free to use random hashes to make classnames uniq.

  • getMixinName(mixin) - generate mixin classname. Takes original mixin name as first argument

mixin - is a JS function inside CSS string. Its name - is a function name or function displayName attribute and anon for anonymous or arrow functions.

  • getAnimationName(animation) - generate animation name. Takes original animation name as first argument
  • plugins - array of plugins
parse
import hash from 'rockey-css-parse/utils/hash';
import createParser from 'rockey-css-parse';

const parse = createParser({
  getClassName: component => `${component}-${hash()}`,
});

const { precss, classList } = parse(`
  Button {
    color: red;

    :hover {
      color: green;
    }
  }

  Layer {
    padding: 15px;

    Button {
      color: purple;

      :hover {
        color: red;
      }

      @media (max-width: 699px) {
        color: blue;
      }
    }
  }
`);

expect(classList.Button).toEqual('Button-abc4');
expect(classList.Layer).toEqual(('Layer-ccf9');


expect(precss).toEqual([{
  selector: '.Button-abc4',
  styles: {
    color: 'red'
  }
}, {
  selector: '.Button-abc4:hover',
  styles: {
    color: 'green'
  }
}, {
  selector: '.Layer-ccf9',
  styles: {
    padding: '15px'
  }
}, {
  selector: '.Layer-ccf9 .Button-abc4',
  styles: {
    color: 'purple'
  }
}, {
  selector: '.Layer-ccf9 .Button-abc4:hover',
  styles: {
    color: 'red'
  }
}, {
  selector: '.Layer-ccf9 .Button-abc4:hover',
  media: '@media (max-width: 699px)',
  styles: {
    color: 'red'
  }
}]);

NOTE: That precss is not the AST tree. It is just easy format for fast CSS generating with dynamic CSS supporting.

  • classList - map of root selector and generated classnames
  • precss - array of precss objects. Each precss object consist of CSS selector, dynamic CSS functions, styles and root parent components.
plugins

Plugin - function that takes styles object, process it and returns it back.

Example of plugin that do console.warn if there are rules with !important flag.

function warnIfImportant(styles) {
  Object.keys(styles).forEach(prop => {
    const isImportant = styles[prop].indexOf('!important') !== -1;
    if (isImportant) {
      console.warn(
        `(warnIfImportant) rule should not be with !important flag. "${prop}:${styles[prop]}"`
      );
    }
  });

  return styles;
}

Stringify

Stringify without dynmaic rules:

import createParser from 'rockey-css-parse';
import stringify from 'rockey-css-parse/stringify';

const parse = createParser();

const { classList, precss } = parse(`
  Button {
    color: black;
    background-color: #ccc;

    :hover {
      color: purple;
    }
  }`
);

// stringify all precss
const fullCSSContent = stringify(precss);
// stringify only first precss object
const firstCSSSelector = strigify(precss[0]);

Stringify with dynamic rules:

import createParser from 'rockey-css-parse';
import stringify from 'rockey-css-parse/stringify';

const parse = createParser();

const { classList, precss } = parse`
  Button {
    color: ${props => props.primary ? 'purple' : 'black'};
    background-color: ${props => props.bgColor};

    ${props => props.primary && `
      :hover {
        color: black;
      }
    `}
  }
`;

const fullCSSContent = stringify(precss, {
  primary: true,
  bgColor: '#ccc'
});

Example

import shader from 'shader';
import createParser from 'rockey-css-parse';

const parse = createParser();

const bgColor = '#f6f6f6';

const { classList, parsed } = parse`
  Button {
    font-size: 20px;
    padding: 5px;
    margin: 5px;
    background: ${bgColor};
    border: 1px solid #ccc;

    ${props => props.raised && `
      box-shadow: 5px 5px 5px rgba(0, 0, 0, .3);
    `}

    Icon {
      margin: 5px;
    }

    :hover {
      background: ${shader(bgColor, -0.03)}
    }
  }

  PrimaryButton {
   color: blue;
  }

  SuccessButton {
   color: green;
  }
`;

Contribute

  • npm run dev - starts watchers and transpiles code.
  • npm run optimize-parse to auto optimize CSS parser packages/rockey-css-parse/parse.js => packages/rockey-css-parse/parseOptimized.js

benchmarks:

For nested CSS syntax:

npm run bench:nested -- --size {{ SIZE }}

For native CSS syntax:

npm run bench:native -- --size {{ SIZE }}

{{ SIZE }} - number of generated CSS classes to parse (1000 by default).

Feedback wanted

This is a very new approach and library and not all features are implemented yet. Feel free to file issue or suggest feature to help me to make rockey better. Or ping me on twitter @tuchk4.

🎉

Keywords

FAQs

Last updated on 12 May 2017

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc