A comprehensive Babel-based transpiler that converts React class components into functional components using React Hooks, with advanced compilation visualization and symbol table analysis.
- AST Parsing: Uses
@babel/parser
to create Abstract Syntax Trees - Class Component Conversion: Transforms
extends React.Component
to functional components - Hook Migration: Converts lifecycle methods to React Hooks
constructor
withthis.state
→useState
hookscomponentDidMount
→useEffect(() => {}, [])
componentDidUpdate
→useEffect(() => {}, [dependencies])
componentWillUnmount
→useEffect
cleanup functions
- State Management: Intelligent
this.setState
to hook setter conversion - Method Conversion: Class methods become internal component functions
- Props Handling:
this.props
references converted to function parameters
- Symbol Table Generation: Comprehensive symbol analysis with:
- Memory address simulation
- Scope tracking (global, class, function)
- Type classification (variable, function, class, method, property, import, export)
- Value extraction and additional metadata
- Three-Address Code: Intermediate representation generation
- Compilation Steps: Complete compilation pipeline visualization
- Modern Web Dashboard: Clean, icon-free interface
- AST Tree Viewer: Interactive, collapsible tree structure
- Symbol Table Browser: Detailed symbol information with filtering
- Before/After Comparison: Side-by-side code comparison
- Compilation Steps: Step-by-step transformation process
This project is configured as an ES Module project ("type": "module"
).
- Clone the repository:
git clone <repository-url>
cd react-class-to-function-transpiler
- Install dependencies:
npm install
The transpiler provides a comprehensive CLI with multiple options:
# Basic transformation
node src/cli.js --in <input.js> --out <output.js>
# Print to stdout
node src/cli.js --in <input.js> --print
# AST analysis
node src/cli.js --ast <input.js> --stats
# Help
node src/cli.js --help
--in <file>
: Input JavaScript/JSX file path--out <file>
: Output file path (default: output.js next to input)--print
: Print transformed code to stdout--ast <file>
: Parse and print AST JSON for given input--stats
: With --ast, print AST statistics (node counts by type)-h, --help
: Show help information
- Generate visualization:
node src/cli.js --in your-component.js --out output.js
- Start the visualization server:
node server.js
- Open in browser: Navigate to
http://localhost:3000
# Transform the included complex example
node src/cli.js --in src/complex-input.js --out transformed-output.js
# Start visualization server
node server.js
# Open http://localhost:3000 in your browser
import React, { Component } from 'react';
class UserDashboard extends Component {
constructor(props) {
super(props);
this.state = {
userData: null,
postsData: [],
searchTerm: '',
notification: null
};
}
componentDidMount() {
this.fetchUserData();
this.setupEventListeners();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.searchTerm !== this.state.searchTerm) {
this.getFilteredPosts();
}
}
componentWillUnmount() {
this.removeEventListeners();
}
fetchUserData = async () => {
try {
const response = await fetch('/api/user');
const userData = await response.json();
this.setState({ userData });
} catch (error) {
this.addNotification('Failed to fetch user data', 'error');
}
};
handleSearch = (event) => {
this.setState({ searchTerm: event.target.value });
};
render() {
const { userData, postsData, searchTerm } = this.state;
return (
<div className="dashboard">
<h1>Welcome, {userData?.name}</h1>
<input
type="text"
value={searchTerm}
onChange={this.handleSearch}
placeholder="Search posts..."
/>
{/* More JSX */}
</div>
);
}
}
export default UserDashboard;
import React, { useState, useEffect } from 'react';
const UserDashboard = (props) => {
const [userData, setUserData] = useState(null);
const [postsData, setPostsData] = useState([]);
const [searchTerm, setSearchTerm] = useState('');
const [notification, setNotification] = useState(null);
const fetchUserData = async () => {
try {
const response = await fetch('/api/user');
const userData = await response.json();
setUserData(userData);
} catch (error) {
addNotification('Failed to fetch user data', 'error');
}
};
const handleSearch = (event) => {
setSearchTerm(event.target.value);
};
useEffect(() => {
fetchUserData();
setupEventListeners();
return () => {
removeEventListeners();
};
}, []);
useEffect(() => {
getFilteredPosts();
}, [searchTerm]);
return (
<div className="dashboard">
<h1>Welcome, {userData?.name}</h1>
<input
type="text"
value={searchTerm}
onChange={handleSearch}
placeholder="Search posts..."
/>
{/* More JSX */}
</div>
);
};
export default UserDashboard;
react-class-to-function-transpiler/
├── src/
│ ├── debug/
│ │ ├── compilerUtils.js # Enhanced compilation with symbol table
│ │ └── compilationSteps.js # Step-by-step compilation logging
│ ├── transformers/
│ │ ├── reactClassToFunction.js # Core transformation logic
│ │ └── dependencyDetection.js # Hook dependency analysis
│ ├── utils/
│ │ └── helpers.js # Utility functions
│ ├── cli.js # Command-line interface
│ ├── index.js # Main entry point
│ ├── parser.js # AST parsing utilities
│ ├── transpiler.js # Core transpiler logic
│ ├── traverse.js # AST traversal utilities
│ ├── visualizer.js # Visualization generator
│ └── complex-input.js # Example complex component
├── compilation-steps/ # Generated compilation artifacts
├── server.js # Visualization web server
├── package.json
└── README.md
The transpiler generates comprehensive symbol tables with:
- ID: Unique identifier for each symbol
- Name: Symbol identifier name
- Type: Classification (variable, function, class, method, property, parameter, import, export)
- Memory Address: Simulated memory location
- Scope: Context (global, program, class:ClassName, function:functionName)
- Value: Extracted or inferred value
- Location: Line and column numbers
- Additional Info: Context-specific metadata
- Lexical Analysis: Source code tokenization
- Syntax Analysis: AST generation using Babel parser
- Symbol Table Construction: Comprehensive symbol extraction
- Semantic Analysis: Type checking and scope analysis
- AST Transformation: React class to function conversion
- Code Generation: Final functional component output
- Visualization: Interactive compilation dashboard
constructor
→useState
initializationcomponentDidMount
→useEffect(() => {}, [])
componentDidUpdate
→useEffect(() => {}, [deps])
componentWillUnmount
→useEffect
cleanupgetDerivedStateFromProps
→useMemo
or conditional logic
this.state.property
→property
(from useState)this.setState({key: value})
→setKey(value)
- Complex state updates with proper hook patterns
- Class methods → Internal component functions
- Arrow function properties → Function declarations
- Event handlers with proper binding
this.props
→props
parameter- Context consumption patterns
- Prop destructuring optimization
- Complex lifecycle method combinations may need manual review
- Advanced patterns like HOCs require additional consideration
- Static class members are not automatically converted
- Some edge cases in state updates may need refinement
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE file for details