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
Markdown
and Vite codebases and generate comprehensive component dependency graphs with advanced collision resolution and import analysis.
This project is completely vibe-coded with no coding standard whatsoever. If you want to contribute, you should use Curser.
ā ļø 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.
- **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;
```
To mark a component as a screen:
```bash
ComponentName.isScreen = true;
ComponentName.isEntryRoute = true;
export default ComponentName;
```
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;
```
```bash
npx react-component-scanner
```
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
}
}
}
}
```
The scanner detects various types of React components:
```typescript
function MyComponent() {
return <div>Hello</div>;
}
```
```typescript
const MyComponent = () => {
return <div>Hello</div>;
};
```
```typescript
class MyComponent extends React.Component {
render() {
return <div>Hello</div>;
}
}
```
```typescript
const MyComponent = React.forwardRef((props, ref) => {
return <div ref={ref}>Hello</div>;
});
```
```typescript
const MyComponent = React.memo(() => {
return <div>Hello</div>;
});
```
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'
}
}]
]
};
```
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' }
];
```
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)
Automatically identifies screen components:
- Components with `isScreen = true` property
- Components that use `ScreenContainer` as a child
Extracts navigation sequences from component properties:
```typescript
PaymentScreen.navigate = [
{ screen: 'SuccessScreen', condition: 'payment_success' },
{ screen: 'FailureScreen', condition: 'payment_failed' }
];
```
- Node.js >= 16.0.0
- React/React Native project with JSX/TSX files
- Optional: babel.config.js with module-resolver plugin for path aliases
- 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**
A powerful tool to scan React, React Native, Next.js,