Plugin framework for CSS preprocessing with chainable API and source map support
npx @tessl/cli install tessl/npm-rework@1.0.0Rework is a flexible CSS manipulation framework built on top of the CSS parser library. It provides a plugin-based architecture for creating custom CSS transformations through a simple chainable API, supporting operations like vendor prefixing, property creation, image inlining, and any other CSS manipulations.
npm install reworkconst rework = require('rework');const rework = require('rework');
// Transform CSS with plugins
const css = rework('body { font-size: 12px; }', { source: 'source.css' })
.use(pluginA)
.use(pluginB)
.toString({ sourcemap: true });
console.log(css);Rework is built around several key components:
css library's Abstract Syntax Tree for reliable parsing and stringificationCreates a new Rework instance from CSS string input with optional parsing configuration.
/**
* Creates a new Rework instance from CSS string
* @param {string} str - CSS string to parse
* @param {Object} [options] - Options passed to css.parse
* @param {string} [options.source] - Source filename for source maps
* @returns {Rework} New Rework instance for chaining operations
*/
function rework(str, options);Usage Examples:
// Basic parsing
const stylesheet = rework('body { color: red; }');
// With source information for source maps
const stylesheet = rework(cssString, { source: 'input.css' });
// With CSS parser options
const stylesheet = rework(cssString, {
source: 'styles.css',
position: true // Include position info in AST
});Applies plugin functions to transform the CSS Abstract Syntax Tree. Plugins receive the stylesheet AST and the Rework instance.
/**
* Applies a plugin function to the stylesheet
* @param {Function} fn - Plugin function receiving (stylesheet, rework) parameters
* @returns {Rework} Same Rework instance for method chaining
*/
Rework.prototype.use(fn);Plugin Function Signature:
/**
* Plugin function signature
* @param {Object} stylesheet - CSS AST stylesheet node with rules array
* @param {Rework} rework - The Rework instance for additional context
*/
function plugin(stylesheet, rework) {
// Modify stylesheet.rules or other AST properties
// Example: add vendor prefixes, transform properties, etc.
}Usage Examples:
// Simple plugin example
function addPrefix(stylesheet, rework) {
stylesheet.rules.forEach(rule => {
if (rule.type === 'rule') {
rule.declarations.forEach(decl => {
if (decl.property === 'transform') {
// Add vendor-prefixed versions
stylesheet.rules.push({
type: 'rule',
selectors: rule.selectors,
declarations: [
{ property: '-webkit-transform', value: decl.value },
{ property: '-moz-transform', value: decl.value }
]
});
}
});
}
});
}
// Apply plugin
const result = rework(css)
.use(addPrefix)
.toString();
// Chain multiple plugins
const result = rework(css)
.use(plugin1)
.use(plugin2)
.use(plugin3)
.toString();Converts the manipulated CSS AST back to CSS string with optional formatting and source map support.
/**
* Converts CSS AST to string with optional source map support
* @param {Object} [options] - Options passed to css.stringify plus rework-specific options
* @param {boolean} [options.sourcemap] - Generate and include source map information
* @param {boolean} [options.sourcemapAsObject] - When true with sourcemap, returns {code, map} object instead of string
* @param {boolean} [options.compress] - Compress CSS output (remove whitespace)
* @param {number} [options.indent] - Indentation for pretty printing (default: 2 spaces)
* @returns {string|Object} CSS string with optional inline sourcemap, or {code: string, map: Object} when sourcemapAsObject: true
*/
Rework.prototype.toString(options);Usage Examples:
// Basic stringification
const css = rework(input).use(plugin).toString();
// Compressed output
const minified = rework(input)
.use(plugin)
.toString({ compress: true });
// With inline source map (as base64-encoded comment)
const cssWithMap = rework(input, { source: 'input.css' })
.use(plugin)
.toString({ sourcemap: true });
// Returns: "body{color:red;}\n/*# sourceMappingURL=data:application/json;base64,... */"
// With source map as separate object
const result = rework(input, { source: 'input.css' })
.use(plugin)
.toString({
sourcemap: true,
sourcemapAsObject: true
});
// result.code contains CSS string
// result.map contains source map object with version, sources, mappings, etc.
// Source map requires source option during parsing
const reworkInstance = rework(cssString, { source: 'original.css' });/**
* Rework class - Internal constructor (instantiated via rework factory function)
* @class
*/
function Rework(obj) {
/**
* CSS AST object containing stylesheet structure from css.parse
* @type {Object}
*/
this.obj = obj;
}
/**
* CSS AST stylesheet structure (from css library)
* The root object returned by css.parse()
* @typedef {Object} Stylesheet
* @property {string} type - Always 'stylesheet'
* @property {Object} stylesheet - The stylesheet container
* @property {Rule[]} stylesheet.rules - Array of CSS rules
* @property {Error[]} [stylesheet.parsingErrors] - Parse errors if any
*/
/**
* CSS rule object in the AST
* @typedef {Object} Rule
* @property {string} type - Rule type: 'rule', 'comment', 'media', 'keyframes', 'supports', etc.
* @property {string[]} [selectors] - CSS selectors (for 'rule' type)
* @property {Declaration[]} [declarations] - CSS declarations (for 'rule' type)
* @property {string} [comment] - Comment text (for 'comment' type)
* @property {Rule[]} [rules] - Nested rules (for 'media', 'keyframes', etc.)
*/
/**
* CSS declaration object
* @typedef {Object} Declaration
* @property {string} type - Always 'declaration'
* @property {string} property - CSS property name
* @property {string} value - CSS property value
*/