Babel plugin to instrument React components with custom transforms
npx @tessl/cli install tessl/npm-babel-plugin-react-transform@3.0.0babel-plugin-react-transform is a Babel plugin that instruments React components with custom transforms during compilation. It enables wrapping React components with arbitrary functionality for debugging, hot reloading, error catching, and other development tools by detecting React components and applying specified transforms to them.
npm install --save-dev babel-plugin-react-transform// Plugin is loaded via Babel configuration, not direct import
// Usage is through .babelrc or babel configurationFor TypeScript definitions (if using TypeScript):
// Plugin types are used in Babel configuration
interface BabelPluginReactTransformOptions {
transforms: TransformConfig[];
factoryMethods?: string[];
superClasses?: string[];
}Add to .babelrc or Babel configuration:
{
"presets": ["react", "es2015"],
"env": {
"development": {
"plugins": [
["react-transform", {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"transform": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}]
]
}
}
}babel-plugin-react-transform is built around several key components:
The default export function that creates the Babel plugin.
/**
* Main plugin factory function for babel-plugin-react-transform
* @param babel - Babel object containing types and template utilities
* @param babel.types - Babel types object for AST manipulation
* @param babel.template - Babel template function for creating AST nodes
* @returns Babel plugin visitor object
*/
function babelPluginReactTransform({ types: t, template }): BabelPlugin;
interface BabelPlugin {
visitor: {
Program(path: ASTPath, state: { file: any, opts: BabelPluginReactTransformOptions }): void;
};
}Core configuration options for setting up the Babel plugin with transforms and component detection rules.
interface BabelPluginReactTransformOptions {
transforms: TransformConfig[];
factoryMethods?: string[];
superClasses?: string[];
}
interface TransformConfig {
transform: string;
imports?: string[];
locals?: string[];
}Interface that custom transforms must implement to work with the plugin.
/**
* Transform function interface - custom transforms must follow this pattern
* @param options - Configuration object with component metadata and dependencies
* @returns Function that wraps React components
*/
function customTransform(options: TransformOptions): TransformWrapper;
interface TransformOptions {
filename: string;
components: { [id: string]: ComponentInfo };
imports: any[];
locals: any[];
}
interface ComponentInfo {
displayName?: string;
isInFunction?: boolean;
}
type TransformWrapper = (ReactClass: any, uniqueId: string) => any;Rules and patterns for detecting React components that will be transformed.
interface ComponentDetectionConfig {
factoryMethods: string[];
superClasses: string[];
}Internal builder class that orchestrates the transformation process.
/**
* Builder class that handles component detection and transform application
*/
class ReactTransformBuilder {
/**
* Creates a new transform builder instance
* @param file - Babel file object
* @param options - Plugin configuration options
*/
constructor(file: any, options: BabelPluginReactTransformOptions);
/**
* Validates plugin configuration options
* @param options - Configuration object to validate
* @returns Boolean indicating if options are valid
*/
static validateOptions(options: any): boolean;
/**
* Asserts plugin configuration is valid, throws error if not
* @param options - Configuration object to validate
* @throws Error if options are invalid
*/
static assertValidOptions(options: any): void;
/**
* Normalizes plugin options with defaults
* @param options - Raw plugin options
* @returns Normalized options with defaults applied
*/
normalizeOptions(options: BabelPluginReactTransformOptions): NormalizedOptions;
/**
* Main build method that orchestrates the transformation
*/
build(): void;
/**
* Collects and wraps all React components in the file
* @param wrapperFunctionId - Identifier for the wrapper function
* @returns Array of detected component information
*/
collectAndWrapComponents(wrapperFunctionId: any): ComponentInfo[];
}
interface NormalizedOptions {
factoryMethods: string[];
superClasses: string[];
transforms: TransformConfig[];
}Utility functions used internally for component detection and AST manipulation.
/**
* Checks if an AST path matches any of the provided 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;
/**
* Creates wrapper function call expression for component transformation
* @param node - Component AST node to wrap
* @param componentId - String identifier for the component
* @param wrapperFunctionId - Identifier for the wrapper function
* @returns CallExpression AST node wrapping the component
*/
function wrapComponent(node: any, componentId: string, wrapperFunctionId: any): any;
/**
* Converts plain JavaScript object to AST ObjectExpression
* @param object - Plain JavaScript object
* @returns ObjectExpression AST node
*/
function toObjectExpression(object: any): any;
/**
* Checks if the current AST path is inside a function scope
* @param path - Babel AST path to check
* @returns Boolean indicating if inside a function
*/
function hasParentFunction(path: ASTPath): boolean;interface BabelPluginReactTransformOptions {
transforms: TransformConfig[];
factoryMethods?: string[];
superClasses?: string[];
}
interface TransformConfig {
transform: string;
imports?: string[];
locals?: string[];
}
interface TransformOptions {
filename: string;
components: { [id: string]: ComponentInfo };
imports: any[];
locals: any[];
}
interface ComponentInfo {
displayName?: string;
isInFunction?: boolean;
}
type TransformWrapper = (ReactClass: any, uniqueId: string) => any;
interface ComponentDetectionConfig {
factoryMethods: string[];
superClasses: string[];
}
interface BabelPlugin {
visitor: {
Program(path: ASTPath, state: { file: any, opts: BabelPluginReactTransformOptions }): void;
};
}
interface NormalizedOptions {
factoryMethods: string[];
superClasses: string[];
transforms: TransformConfig[];
}
interface ASTPath {
node: any;
get(key: string): ASTPath;
findParent(callback: (path: ASTPath) => boolean): ASTPath | null;
matchesPattern(pattern: string): boolean;
isFunction(): boolean;
replaceWith(node: any): void;
insertBefore(node: any): void;
parentPath: ASTPath;
parent: any;
scope: any;
}