esifycss
Generates .js or .ts exports class names and custom properties
Last updated 8 days ago by kei-ito .
Apache-2.0 · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install esifycss 
SYNC missed versions from official npm registry.

EsifyCSS

CircleCI Build Status Build status BrowserStack Status codecov

Introduction

EsifyCSS finds CSS files in your project and generates ES modules for each of them.

Assume that you have src/style1.css and src/style2.css. They have the same contents:

/* src/style1.css, src/style2.css */
@keyframes FadeIn {
    0%: {opacity: 0}
  100%: {opacity: 0}
}
@keyframes Rotate {
    0%: {transform: rotate(  0deg)}
  100%: {transform: rotate(360deg)}
}
#container {
  animation: 0.2s linear FadeIn;
}
.icon {
  animation-duration: 1s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}
.icon.rotate {
  animation-name: Rotate;
}

Then, run esifycss --helper src/helper.js src. --helper src/helper.js is where the helper script is written. The last src specifies the directory that contains the file to be processed by EsifyCSS.

The process finds CSS files, parses them, extracts identifiers, replaces them with values.

After the process, you'll get src/style1.css.js and src/style2.css.js:

// src/style1.css.js
import {addStyle} from './helper.js';
addStyle(["WYIGqCCQSCaAQEcSCaAUEE","WYIGsCCQSCeAgBiBIIQkBmBEcSCeAgBiByBkBmBEE","0BGQC2BA4BKOA6BoBIqBIGqCKE","sBGUCOM8BAUoBKOM+BMgCAiCKOMkCMmCAqBKE","sBG2CG4CCOMoCAGsCKE"]);
export const className = {
    "icon": "_1",
    "rotate": "_2"
};
export const id = {
    "container": "_0"
};
export const keyframes = {
    "FadeIn": "_3",
    "Rotate": "_4"
};
// src/style2.css.js
import {addStyle} from './helper.js';
addStyle(["WYIGuBCQSCaAQEcSCaAUEE","WYIGwBCQSCeAgBiBIIQkBmBEcSCeAgBiByBkBmBEE","0BGuCC2BA4BKOA6BoBIqBIGuBKE","sBGwCCOM8BAUoBKOM+BMgCAiCKOMkCMmCAqBKE","sBGyCG0CCOMoCAGwBKE"]);
export const className = {
    "icon": "_6",
    "rotate": "_7"
};
export const id = {
    "container": "_5"
};
export const keyframes = {
    "FadeIn": "_8",
    "Rotate": "_9"
};

The two modules are almost the same, but the exported objects are different. And there will be src/helper.js which exports the addStyle function which applies the style to documents. You can see the code at sample/01-mangle/helper.js.

The exported objects are mappings of identifiers of className, id, and keyframes that were replaced in the process. You should import them and use the replaced identifiers instead of original in the code:

import style from './style1.css.js';
const element = document.createElement('div');
element.classList.add(style.className.icon);

Tools

EsifyCSS consists of PostCSS plugin, Runner and CLI.

PostCSS plugin

The plugin converts the identifiers in CSS and minifies them. It outputs the result of minifications using Root.warn().

Runner

A runner process .css files in your project with PostCSS and output the results to .css.js or .css.ts.

CLI

Usage: esifycss [options] <include ...>

Options:
  -V, --version         output the version number
  --helper <path>       A path to the helper script.
  --config <path>       A path to configuration files.
  --exclude <path ...>  Paths or patterns to be excluded.
  --noMangle            Keep the original name for debugging.
  --watch               Watch files and update the modules automatically.
  -h, --help            output usage information

Installation

npm install --save-dev esifycss

@import Syntax

You can use @import syntax if the style declarations requires identifiers declared in other files.

For example, Assume you have the following a.css and b.css.

/* a.css */
.container {...} /* → ._0 */
/* b.css */
.container {...} /* → ._1 */

The container class names will be shortened to unique names like _0 and _1. You can import the shortened names with the @import syntax.

/* "modA-" is prefix for a.css */
@import './a.css' modA-;
/* "bbbb" is prefix for b.css */
@import './b.css' BBB;
.wrapper>.modA-container {...} /* → ._2>._0 */
.wrapper>.BBBcontainer {...}   /* → ._2>._1 */

JavaScript API for Runner

import {Session} from 'esifycss';
new Session(options).start()
.then(() => console.log('Done'))
.catch((error) => console.error(error));

Options

export interface ISessionOptions {
  /**
   * Pattern(s) to be included
   * @default "** / *.css"
   */
  include?: string | Array<string>,
  /**
   * Pattern(s) to be excluded.
   * @default []
   */
  exclude?: anymatch.Matcher,
  /**
   * Where this plugin outputs the helper script.
   * The hash in the default value is calculated from the include.
   * @default "helper.{hash}.css.js"
   */
  helper?: string,
  /**
   * It it is true, a watcher is enabled.
   * @default false
   */
  watch?: boolean,
  /**
   * Options passed to chokidar.
   * You can't set ignoreInitial to true.
   * @default {
   *   ignore: exclude,
   *   ignoreInitial: false,
   *   useFsEvents: false,
   * }
   */
  chokidar?: chokidar.WatchOptions,
  /**
   * An array of postcss plugins.
   * esifycss.plugin is appended to this array.
   * @default []
   */
  postcssPlugins?: Array<postcss.AcceptedPlugin>,
  /**
   * Parameters for esifycss.plugin.
   */
  esifycssPluginParameter?: IPluginOptions,
  /**
   * A stream where the runner outputs logs.
   * @default process.stdout
   */
  stdout?: stream.Writable,
  /**
   * A stream where the runner outputs errorlogs.
   * @default process.stderr
   */
  stderr?: stream.Writable,
}

Source: src/runner/types.ts

JavaScript API for Plugin

const postcss = require('postcss');
const esifycss = require('esifycss');
postcss([
  esifycss.plugin({/* Plugin Options */}),
])
.process(css, {from: '/foo/bar.css'})
.then((result) => {
  const pluginResult = esifycss.extractPluginResult(result);
  console.log(pluginResult);
  // → {
  //   className: {bar: '_1'},
  //   id: {foo: '_0'},
  //   keyframes: {aaa: '_2'},
  // }
});

The code is at sample/plugin.js. You can run it by node sample/plugin.js after cloning this repository and running npm run build.

Options

export interface IPluginOptions {
    /**
     * When it is true, this plugin minifies classnames.
     * @default true
     */
    mangle?: boolean,
    /**
     * A function returns an unique number from a given file id. If you process
     * CSS files in multiple postcss processes, you should create an identifier
     * outside the processes and pass it as this value to keep the uniqueness
     * of mangled outputs.
     * @default esifycss.createIdentifier()
     */
    identifier?: IIdentifier,
    /**
     * Names starts with this value are not passed to mangler but replaced with
     * unprefixed names.
     * @default "raw-"
     */
    rawPrefix?: string,
    /**
     * A custom mangler: (*id*, *type*, *name*) => string.
     * - *id*: string. A filepath to the CSS.
     * - *type*: 'id' | 'class' | 'keyframes'. The type of *name*
     * - *name*: string. An identifier in the style.
     *
     * If mangler is set, `mangle` and `identifier` options are ignored.
     *
     * For example, If the plugin processes `.foo{color:green}` in `/a.css`,
     * The mangler is called with `("/a.css", "class", "foo")`. A mangler should
     * return an unique string for each input pattern or the styles will be
     * overwritten unexpectedly.
     * @default undefined
     */
    mangler?: IPluginMangler,
}

Source: src/postcssPlugin/types.ts

LICENSE

The esifycss project is licensed under the terms of the Apache 2.0 License.

Current Tags

  • 1.3.8                                ...           latest (8 days ago)

39 Versions

  • 1.3.8                                ...           8 days ago
  • 1.3.7                                ...           23 days ago
  • 1.3.6                                ...           2 months ago
  • 1.3.5                                ...           3 months ago
  • 1.3.4                                ...           3 months ago
  • 1.3.3                                ...           4 months ago
  • 1.3.2                                ...           4 months ago
  • 1.3.1                                ...           5 months ago
  • 1.3.0                                ...           5 months ago
  • 1.2.11                                ...           5 months ago
  • 1.2.10                                ...           5 months ago
  • 1.2.9                                ...           5 months ago
  • 1.2.8                                ...           5 months ago
  • 1.2.7                                ...           5 months ago
  • 1.2.6                                ...           5 months ago
  • 1.2.5                                ...           5 months ago
  • 1.2.3                                ...           5 months ago
  • 1.2.2                                ...           5 months ago
  • 1.2.1                                ...           5 months ago
  • 1.2.0                                ...           5 months ago
  • 1.1.2                                ...           5 months ago
  • 1.1.1                                ...           5 months ago
  • 1.1.0                                ...           5 months ago
  • 1.0.1                                ...           5 months ago
  • 0.1.16                                ...           10 months ago
  • 0.1.15                                ...           a year ago
  • 0.1.14                                ...           a year ago
  • 0.1.13                                ...           a year ago
  • 0.1.12                                ...           a year ago
  • 0.1.11 [deprecated]           ...           a year ago
  • 0.1.10                                ...           a year ago
  • 0.1.9                                ...           a year ago
  • 0.1.8                                ...           a year ago
  • 0.1.7                                ...           a year ago
  • 0.1.6                                ...           a year ago
  • 0.1.5                                ...           a year ago
  • 0.1.4                                ...           a year ago
  • 0.1.3                                ...           a year ago
  • 0.1.2                                ...           a year ago
Maintainers (1)
Downloads
Today 0
This Week 1
This Month 74
Last Day 0
Last Week 72
Last Month 14
Dependencies (9)
Dev Dependencies (25)

Copyright 2014 - 2016 © taobao.org |