Parseley: CSS Selectors Parser
Parseley is a JavaScript/TypeScript library designed for parsing CSS selector strings into a structured Abstract Syntax Tree (AST) and for serializing those ASTs back into strings. It also automatically calculates CSS specificity for each selector component. As of version 0.13.1, the library provides core functionalities such as `parse1` for parsing individual selectors, `serialize` for converting an AST back into a CSS string, and `normalize` for standardizing the order of simple selectors within an AST. It ships with comprehensive TypeScript types and is compatible with both Node.js and Deno environments. Parseley's AST structure is optimized for right-to-left processing, representing complex selectors via 'combinator' nodes integrated into 'compound' selectors rather than distinct 'complex selector' nodes. The library maintains a consistent overall AST shape, aiming to simplify client-side processing tasks.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax to import Parseley in an ES Module context (e.g., a Node.js project with `"type": "module"` in `package.json` or a modern browser environment).fixMigrate your import statements from `const { symbol } = require('parseley');` to `import { symbol } from 'parseley';` to align with ES Module syntax. -
TypeError: parse1 is not a function
cause Incorrectly importing a named export (like `parse1`, `serialize`, or `normalize`) as a default import, or attempting to access it as a property of a non-existent default export.fixEnsure you are using named imports for all Parseley functions: `import { parse1, serialize, normalize } from 'parseley';`. If using a namespace import, access via `parseley.parse1`. -
Error: Unexpected token ','
cause Using the `parse1` function with a CSS selector string that contains multiple selectors separated by commas (e.g., `'div, span'`). `parse1` is designed to parse only a single selector.fixIf your input string contains multiple comma-separated selectors, use the dedicated parsing function for selector lists (e.g., `parse`, if available in the API documentation), or manually split the string by commas and parse each segment individually with `parse1`.
Warnings
- gotcha Parseley provides distinct parsing functions for single CSS selectors versus potentially comma-separated lists of selectors. Using `parse1` (which handles single selectors) with an input string containing multiple, comma-separated selectors will lead to a parsing error or an incomplete AST. Always ensure you are using the correct parsing function for your input type.
- gotcha The internal AST representation for complex selectors in Parseley does not use a dedicated 'complex selector' node type. Instead, combinators (e.g., `>`, `+`, `~`, ` `) are represented as nodes attached to `compound` selector nodes, with `left` and `right` properties. This design is optimized for right-to-left processing.
Install
-
npm install parseley -
yarn add parseley -
pnpm add parseley
Imports
- parse1
import parse1 from 'parseley'; const { parse1 } = require('parseley');import { parse1 } from 'parseley'; - serialize
const serialize = require('parseley').serialize;import { serialize } from 'parseley'; - normalize
const normalize = require('parseley').normalize;import { normalize } from 'parseley'; - parseley (namespace)
const parseley = require('parseley');import * as parseley from 'parseley';
Quickstart
import { parse1, serialize, normalize } from 'parseley';
import { inspect } from 'node:util';
const str = 'div#id1 > .class2.class1[attr1]';
// Parse the CSS selector string into an AST
const ast = parse1(str);
console.log('Parsed AST:', inspect(ast, { breakLength: 45, depth: null }));
// Serialize the AST back into a CSS selector string
const serialized = serialize(ast);
console.log(`Serialized: '${serialized}'`);
// Normalize the AST (e.g., reorder simple selectors) and then serialize again
normalize(ast);
const normalized = serialize(ast);
console.log(`Normalized: '${normalized}'`);