JSX AST Utilities X
jsx-ast-utils-x is a dedicated utility module for statically analyzing JSX Abstract Syntax Tree (AST) nodes. It provides a set of helper functions to query and extract information from JSX elements, attributes, and expressions, making it particularly useful for developing custom ESLint rules or other static analysis tools for React or similar JSX-based codebases. The current stable version is `0.1.0`. As a new package, its release cadence is likely to be agile, with minor versions addressing new features or bug fixes. Key differentiators include its focused scope, providing a core set of AST traversal and querying functions specifically for JSX, and its lean dependency tree (recently replacing external dependencies with built-in methods) which contributes to a smaller footprint and potentially better performance. It serves as a more modular and potentially more modern alternative to similar functionality found embedded in larger linting plugins.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'type')
cause An AST node passed to a utility function was `undefined` or `null`, often because a property lookup (e.g., `node.attributes`) failed.fixAdd nullish checks before accessing properties or passing them to `jsx-ast-utils-x` functions. For instance, `if (node.attributes) { hasProp(node.attributes, 'name'); }`. -
ESLint encountered a parsing error: 'import' and 'export' may only appear with 'sourceType: 'module''
cause Attempting to use ESM `import` syntax in an ESLint configuration file without specifying `sourceType: 'module'` in your parser options.fixEnsure your ESLint configuration (e.g., `.eslintrc.js`) specifies `parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }` if you are using `import` statements directly in the config file itself, or if the files being linted are ESM.
Warnings
- breaking Version 0.1.0 included a 'chore!: replace all dependencies with built-in methods' change. While this generally improves package robustness and reduces install size, it signifies internal refactoring that *could* subtly alter behavior if previous versions had edge-case behaviors tied to specific versions of external libraries. No explicit API breaking changes are listed for 0.1.0.
- gotcha The utilities strictly work with ESTree AST nodes representing JSX. Passing non-JSX or malformed AST nodes to these functions may result in unexpected errors or incorrect results, as they do not perform comprehensive AST validation.
Install
-
npm install jsx-ast-utils-x -
yarn add jsx-ast-utils-x -
pnpm add jsx-ast-utils-x
Imports
- hasProp
const { hasProp } = require('jsx-ast-utils-x');import { hasProp } from 'jsx-ast-utils-x'; - elementType
import elementType from 'jsx-ast-utils-x/elementType';
import { elementType } from 'jsx-ast-utils-x'; - getPropValue
const getPropValue = require('jsx-ast-utils-x').getPropValue;import { getPropValue } from 'jsx-ast-utils-x';
Quickstart
import { hasProp, getPropValue, elementType } from 'jsx-ast-utils-x';
// Example ESLint rule integration
module.exports = {
meta: {
type: 'suggestion',
schema: [],
},
create(context) {
return {
JSXOpeningElement(node) {
// Check if the element has an 'aria-label' attribute
const ariaLabelProp = hasProp(node.attributes, 'aria-label');
if (ariaLabelProp) {
const value = getPropValue(ariaLabelProp);
if (typeof value === 'string' && value.trim() === '') {
context.report({
node,
message: `Empty aria-label found on <${elementType(node)}> element.`,
});
}
} else {
// Report if a button doesn't have an aria-label or text content
if (elementType(node) === 'button') {
// In a real scenario, you'd also check children for text content
context.report({
node,
message: 'Button elements should have an accessible label via `aria-label` or text content.',
});
}
}
},
};
},
};