UNPKG

react-component-scanner

Version:

A powerful tool to scan React/React Native codebases and generate component dependency graphs with collision resolution and import analysis

224 lines (180 loc) • 6.26 kB
# React Component Scanner A powerful tool to scan React, React Native, Next.js, and Vite codebases and generate comprehensive component dependency graphs with advanced collision resolution and import analysis. ### Disclaimer This project is completely vibe-coded with no coding standard whatsoever. If you want to contribute, you should use Curser. ### Why this package āš ļø This package is not intended to be used on its own. It was designed to work alongside **[React Graph](https://react-graph.com/)**, a web-based UI tool that visualizes your component tree and unlocks powerful features using the output generated by this package as input. ## šŸš€ Features - **Auto Project Detection**: Automatically detects project root for React, React Native, Next.js, Vite, and other frameworks - **Component Discovery**: Automatically finds all React components (function, class, arrow, forwardRef, memo) - **Dependency Graph**: Maps parent-child relationships between components - **Collision Resolution**: Handles multiple components with the same name using hash-based unique IDs - **Import Analysis**: Resolves imports with re-export following and path alias support - **Same-File Priority**: Prioritizes components defined in the same file over external imports - **Screen Detection**: Identifies screen components based on ScreenContainer usage - **Navigation Flow**: Extracts navigation sequences from component properties - **Entry Route Detection**: Identifies application entry points - **Babel Integration**: Dynamically reads path aliases from babel.config.js ## šŸ“¦ Installation ### Global Installation ```bash npm install -g react-component-scanner ``` ### Use with npx (Recommended) ```bash npx react-component-scanner ``` ## šŸŽÆ Quick Start ### Basic Usage #### Define entry point. By default, DepGraph opens with entry routes. For example, if your app has 5 tabs, mark them all as entry points: ```bash ComponentName.isEntryRoute = true; export default ComponentName; ``` #### Define screens To mark a component as a screen: ```bash ComponentName.isScreen = true; ComponentName.isEntryRoute = true; export default ComponentName; ``` #### Define custom properties Custom properties help group similar components. For example, in a car-selling app, multiple card/UI can show car info. ```bash ListingCard.isCarCard = true; export default ListingCard; ``` #### Generate dependency graph ```bash npx react-component-scanner ``` ## šŸ“Š Output Files ### Dependency Graph (`dependency-graph.json`) Contains the complete component relationship graph: ```json { "totalComponents": 636, "scanDate": "2024-01-15T10:30:00.000Z", "collisions": 29, "dependencyGraph": { "a1b2c3d4.Button": { "name": "Button", "uniqueId": "a1b2c3d4.Button", "filePath": "src/components/Button/Button.tsx", "absolutePath": "/project/src/components/Button/Button.tsx", "type": "function", "children": ["Text", "e5f6g7h8.TouchableOpacity"], "childrenWithPaths": [ { "name": "Text", "path": null }, { "name": "e5f6g7h8.TouchableOpacity", "path": "/project/src/components/TouchableOpacity/TouchableOpacity.tsx" } ], "properties": { "isScreen": false, "Remote": true } } } } ``` ## šŸŽØ Component Detection The scanner detects various types of React components: ### Function Components ```typescript function MyComponent() { return <div>Hello</div>; } ``` ### Arrow Function Components ```typescript const MyComponent = () => { return <div>Hello</div>; }; ``` ### Class Components ```typescript class MyComponent extends React.Component { render() { return <div>Hello</div>; } } ``` ### forwardRef Components ```typescript const MyComponent = React.forwardRef((props, ref) => { return <div ref={ref}>Hello</div>; }); ``` ### memo Components ```typescript const MyComponent = React.memo(() => { return <div>Hello</div>; }); ``` ## šŸ” Advanced Features ### Path Alias Resolution Automatically reads path aliases from your `babel.config.js`: ```javascript // babel.config.js module.exports = { plugins: [ ['module-resolver', { alias: { '@components': './src/components', '@screens': './src/screens', '@utils': './src/utils' } }] ] }; ``` ### Component Properties Detection Detects custom properties assigned to components: ```typescript const MyScreen = () => <ScreenContainer>...</ScreenContainer>; // These properties are automatically detected MyScreen.isScreen = true; MyScreen.Remote = true; MyScreen.navigate = [ { screen: 'NextScreen', condition: 'success' }, { screen: 'ErrorScreen', condition: 'failure' } ]; ``` ### Collision Resolution Suppose you have multiple components with the same name, the parent will be resolved to have a child with the following preference 1. **Same-file components** (highest priority) 2. **Import-resolved components** (with re-export following) 3. **First available instance** (fallback) ### Screen Detection Automatically identifies screen components: - Components with `isScreen = true` property - Components that use `ScreenContainer` as a child ### Navigation Flow Analysis Extracts navigation sequences from component properties: ```typescript PaymentScreen.navigate = [ { screen: 'SuccessScreen', condition: 'payment_success' }, { screen: 'FailureScreen', condition: 'payment_failed' } ]; ``` ## šŸ› ļø Requirements - Node.js >= 16.0.0 - React/React Native project with JSX/TSX files - Optional: babel.config.js with module-resolver plugin for path aliases ### Troubleshoot #### Wrong component is getting linked as children. - Please check `Collision Resolution` section - To debug, try to remove, React.memo, React.forwardRef, any hoc before remove - Try to have same component import and export name. If component is exported with identifier ShortlistIcon, try to import and use as ShortlistIcon only. - If issue is still there then try to create a extract children into a separate file - If you still have issue, please fell free to raise issue on github --- **Made with ā¤ļø for the React community**