Rules and patterns for detecting React components that will be transformed by babel-plugin-react-transform.
The plugin identifies React components using multiple detection strategies.
/**
* Component detection configuration
*/
interface ComponentDetectionConfig {
/** Patterns for detecting factory method calls like React.createClass */
factoryMethods: string[];
/** Patterns for detecting class inheritance from React components */
superClasses: string[];
}
/**
* Component visitor object that traverses AST to find React components
*/
const componentVisitor = {
/** Processes class declarations/expressions that extend React components */
Class(path: ASTPath): void;
/** Processes React.createClass and similar factory method calls */
CallExpression(path: ASTPath): void;
};Detects ES6 classes that extend React component classes and have a render method.
/**
* Detects React-like class components
* @param node - AST node representing a class
* @returns Boolean indicating if class is a React component
*/
function isReactLikeClass(node: ClassNode): boolean;Detection Criteria:
render method (ClassMethod with key name 'render')['React.Component', 'React.PureComponent', 'Component', 'PureComponent']Examples Detected:
// Standard React components
class MyComponent extends React.Component {
render() {
return <div>Hello</div>;
}
}
class PureComponent extends React.PureComponent {
render() {
return <div>Pure</div>;
}
}
// Imported Component classes
import { Component } from 'react';
class ImportedComponent extends Component {
render() {
return <div>Imported</div>;
}
}
// Custom superclass patterns (if configured)
class CustomComponent extends BaseComponent {
render() {
return <div>Custom</div>;
}
}Examples NOT Detected:
// No render method
class NotComponent extends React.Component {
doSomething() {}
}
// Doesn't extend React class
class RegularClass {
render() {
return "not a component";
}
}Detects function calls to component factory methods like React.createClass.
/**
* Detects React-like component objects created via factory methods
* @param node - AST node representing an object expression
* @returns Boolean indicating if object is a React component
*/
function isReactLikeComponentObject(node: ObjectNode): boolean;Detection Criteria:
render method or property['React.createClass']Examples Detected:
// Standard createClass usage
const MyComponent = React.createClass({
render: function() {
return <div>CreateClass</div>;
}
});
// Object method syntax
const ModernComponent = React.createClass({
render() {
return <div>Modern</div>;
}
});
// String key render method
const StringKeyComponent = React.createClass({
'render': function() {
return <div>String key</div>;
}
});
// Custom factory methods (if configured)
const CustomComponent = createComponent({
render() {
return <div>Custom factory</div>;
}
});How the plugin matches AST nodes against configured patterns.
/**
* Matches AST path against array of patterns
* @param path - Babel AST path to check
* @param patterns - Array of string patterns to match against
* @returns Boolean indicating if path matches any pattern
*/
function matchesPatterns(path: ASTPath, patterns: string[]): boolean;Pattern Types:
pattern matches nodes with name property equal to patternpath.matchesPattern(pattern) for dotted patterns like React.ComponentPattern Examples:
// Simple identifier patterns
["Component"] // matches: Component
["createClass"] // matches: createClass
// Member expression patterns
["React.Component"] // matches: React.Component
["React.createClass"] // matches: React.createClass
["MyLib.createComponent"] // matches: MyLib.createComponentInformation extracted from detected components.
/**
* Extracts display name from createClass calls
* @param node - Call expression node for createClass
* @returns Display name string or undefined
*/
function getDisplayName(node: CallExpressionNode): string | undefined;
/**
* Checks if component is defined inside a function scope
* @param path - AST path of the component
* @returns Boolean indicating if component is in function
*/
function hasParentFunction(path: ASTPath): boolean;Display Name Extraction:
// From class name
class MyComponent extends React.Component {
// displayName: "MyComponent"
}
// From createClass displayName property
const ComponentWithName = React.createClass({
displayName: 'CustomName',
render() {}
});
// displayName: "CustomName"
// Anonymous components get generated IDs
export default class extends React.Component {
// displayName: undefined, gets unique ID
}Function Scope Detection:
// Component NOT in function
class TopLevel extends React.Component {
// isInFunction: false
}
// Component IN function
function createComponent() {
class InFunction extends React.Component {
// isInFunction: true
}
return InFunction;
}
// Nested function example
function outer() {
function inner() {
const Nested = React.createClass({
// isInFunction: true
});
}
}{
"factoryMethods": ["React.createClass"],
"superClasses": ["React.Component", "React.PureComponent", "Component", "PureComponent"]
}{
"factoryMethods": [
"React.createClass",
"createClass",
"createReactClass",
"MyFramework.createComponent"
],
"superClasses": [
"React.Component",
"React.PureComponent",
"Component",
"PureComponent",
"BaseComponent",
"CustomFramework.Component"
]
}{
"factoryMethods": [
"Preact.createClass",
"createPreactComponent",
"InfernoComponent.create"
],
"superClasses": [
"Preact.Component",
"InfernoComponent",
"CustomBaseClass"
]
}How detected components are processed and wrapped.
/**
* Component information collected during detection
*/
interface DetectedComponent {
/** Unique identifier for the component within the file */
id: string;
/** Display name if available */
name?: string;
/** Whether component is defined inside a function */
isInFunction: boolean;
}Detection and Transformation Flow:
Generated Component Metadata:
// Example metadata for detected components
{
"component1": {
"displayName": "MyComponent",
"isInFunction": false
},
"component2": {
"displayName": "NestedComponent",
"isInFunction": true
},
"_component3": {
// No displayName for anonymous component
"isInFunction": false
}
}