HAST Utility to Parse CSS Selectors
`hast-util-parse-selector` is a focused utility within the `unified` ecosystem designed to create HAST (Hypertext Abstract Syntax Tree) element nodes from simple CSS selector strings. Currently at stable version 4.0.0, this package follows semantic versioning, with major releases typically aligning with dropping support for unmaintained Node.js versions. It processes basic selectors that can include a tag name, multiple class names, and a single ID, transforming them into a `hast` element object with corresponding `tagName` and `properties` (including `id` and `className` arrays). While powerful for its specific use case, it explicitly states its niche nature, recommending more comprehensive alternatives like `hastscript` or `hast-util-from-selector` for handling complex CSS selectors. Its primary differentiator is its simplicity and directness in parsing straightforward selectors into HAST nodes, making it suitable for scenarios where a full-blown selector engine is overkill.
Common errors
-
ERR_REQUIRE_ESM
cause Attempting to use `require()` to import `hast-util-parse-selector`, which is an ESM-only package.fixChange `const { parseSelector } = require('hast-util-parse-selector');` to `import { parseSelector } from 'hast-util-parse-selector';`. Ensure your project's `package.json` has `"type": "module"` or that files are `.mjs`. -
TypeError: parseSelector is not a function
cause This usually indicates an incorrect import or module resolution issue, especially when mixing CommonJS and ESM, or when an invalid import path is used.fixVerify your import statement is `import { parseSelector } from 'hast-util-parse-selector';` and that your environment supports ESM. If using a bundler, ensure it's configured for ESM. -
TS2307: Cannot find module 'hast-util-parse-selector' or its corresponding type declarations.
cause Your TypeScript compiler cannot locate the package's type definitions, possibly due to an outdated TypeScript version, incorrect `moduleResolution` in `tsconfig.json`, or an issue with the `@types/hast` dependency if type inference relies on it.fixEnsure your `tsconfig.json` includes `"moduleResolution": "bundler"` (for modern bundlers) or `"node"` and `"allowSyntheticDefaultImports": true`. Also, update your `typescript` and potentially `@types/hast` dependencies to match the package's requirements (TS 4.2+ for v4.0.0).
Warnings
- breaking Version 4.0.0 raises the minimum required Node.js version to 16. Older Node.js versions are no longer supported.
- breaking Version 4.0.0 removed support for TypeScript 4.1. Ensure your project is using a compatible TypeScript version.
- breaking Version 4.0.0 changed to use `exports` in `package.json` for module resolution. Direct imports of internal or private module paths are no longer supported and will break.
- breaking Version 3.0.0 converted the package to be ESM-only. CommonJS `require()` statements are no longer supported.
- gotcha Using unsanitized user input in the `selector` or `defaultTagName` parameters can lead to a Cross-Site Scripting (XSS) vulnerability. If a `tagName` resolves to `script`, it will inject a script element into the HAST tree.
Install
-
npm install hast-util-parse-selector -
yarn add hast-util-parse-selector -
pnpm add hast-util-parse-selector
Imports
- parseSelector
const { parseSelector } = require('hast-util-parse-selector')import { parseSelector } from 'hast-util-parse-selector' - parseSelector
import { parseSelector } from 'https://esm.sh/hast-util-parse-selector@4' - parseSelector
<script type="module"> import { parseSelector } from 'https://esm.sh/hast-util-parse-selector@4?bundle' </script>
Quickstart
import { parseSelector } from 'hast-util-parse-selector';
import type { Element } from 'hast'; // Import for type definition
// Create a HAST element from a complex class/id selector
const complexSelectorElement: Element = parseSelector('.quux#bar.baz.qux');
console.log('Complex Selector Result:', complexSelectorElement);
// Expected: { type: 'element', tagName: 'div', properties: { id: 'bar', className: [ 'quux', 'baz', 'qux' ] }, children: [] }
// Create a HAST element with a specific tag name and ID
const spanElement: Element = parseSelector('span#foo');
console.log('Span with ID Result:', spanElement);
// Expected: { type: 'element', tagName: 'span', properties: { id: 'foo' }, children: [] }
// Create an element with a default tag name when no selector is provided
const defaultElement: Element = parseSelector(undefined, 'p');
console.log('Default Tag Name Result:', defaultElement);
// Expected: { type: 'element', tagName: 'p', properties: {}, children: [] }
// Using an empty string selector also results in the default tag name
const emptySelectorElement: Element = parseSelector('');
console.log('Empty Selector Result:', emptySelectorElement);
// Expected: { type: 'element', tagName: 'div', properties: {}, children: [] }
// Example with a different default tag name
const customDefaultElement: Element = parseSelector('.my-class', 'section');
console.log('Custom Default Tag Name Result:', customDefaultElement);
// Expected: { type: 'element', tagName: 'section', properties: { className: [ 'my-class' ] }, children: [] }