Directory structure specification
Component development and directory structure standards are essential parts of front-end engineering. Reasonable standards can improve code maintainability and team collaboration efficiency. From component design principles to directory organization methods, the formulation of standards needs to consider actual project requirements and the characteristics of the technology stack.
Component Design Principles
Components should follow the Single Responsibility Principle, with each component focusing on a specific function. For example, a button component should only handle click interactions and style presentation, without including business logic:
// Good: A button component with a single responsibility
const Button = ({ onClick, children }) => (
<button
className="base-btn"
onClick={onClick}
>
{children}
</button>
);
// Bad: A button mixed with business logic
const LoginButton = () => {
const handleLogin = () => {
// Login logic...
};
return (
<button onClick={handleLogin}>
Login
</button>
);
};
Component interface design should maintain consistency in props. Boolean-type props should default to true
when the value is omitted:
<Modal visible /> // Equivalent to visible={true}
Component File Structure
A single component should include complete functional unit files. A typical structure is as follows:
components/
├── Button/
│ ├── index.tsx // Component entry
│ ├── Button.tsx // Component implementation
│ ├── Button.less // Component styles
│ ├── Button.test.tsx // Unit tests
│ └── README.md // Documentation
Composite components should be organized in a flat structure:
form/
├── Form.tsx
├── FormItem.tsx
├── FormInput.tsx
└── index.ts
Directory Structure Standards
The project root directory should be divided by functionality:
project/
├── src/
│ ├── assets/ # Static resources
│ ├── components/ # Generic components
│ ├── hooks/ # Custom Hooks
│ ├── pages/ # Page components
│ ├── services/ # API services
│ ├── stores/ # State management
│ ├── utils/ # Utility functions
│ └── App.tsx
├── .storybook/ # Component documentation configuration
└── public/ # Public resources
Example of a page-level component directory:
pages/
├── user/
│ ├── components/ # Private components for the page
│ ├── hooks/ # Page-specific Hooks
│ ├── UserList.tsx
│ ├── UserDetail.tsx
│ └── index.ts # Page routing entry
Naming Conventions
Component file names should use PascalCase, while utility functions should use camelCase:
components/
├── DatePicker.tsx
└── useWindowSize.ts
Style files should have the same name as the component:
Button/
├── Button.tsx
└── Button.module.css
Code Organization Standards
Code inside components should be organized in the following order:
interface Props {
// TypeScript interface definition
}
const Component: React.FC<Props> = (props) => {
// Hook calls
const [state, setState] = useState();
// Internal functions
const handleClick = () => {};
// Render content
return <div>{/* ... */}</div>;
};
Style Management Solutions
CSS Modules or CSS-in-JS solutions are recommended:
// CSS Modules example
import styles from './Button.module.css';
const Button = () => (
<button className={styles.primary}>
Button
</button>
);
// styled-components example
const StyledButton = styled.button`
padding: 8px 16px;
background: ${props => props.primary ? '#1890ff' : '#fff'};
`;
Test File Standards
Test files should be placed in the same directory as the component and named *.test.tsx
:
// Button.test.tsx
describe('Button Component', () => {
it('should trigger onClick', () => {
const mockFn = jest.fn();
render(<Button onClick={mockFn} />);
fireEvent.click(screen.getByRole('button'));
expect(mockFn).toBeCalledTimes(1);
});
});
Documentation Standards
Each component directory should include a README.md file:
# Button Component
## Basic Usage
```jsx
<Button type="primary">Submit</Button>
```
## API
| Property | Description | Type | Default |
|------|------|------|-------|
| type | Button type | 'primary'|'default' | 'default' |
Type Definition Standards
Component props should be defined using TypeScript interfaces:
interface ButtonProps {
/**
* Button size
* @default 'medium'
*/
size?: 'small' | 'medium' | 'large';
/**
* Click event handler
*/
onClick?: (event: React.MouseEvent) => void;
}
Version Control Strategy
Component library updates should follow semantic versioning:
- Patch version (0.0.x): Backward-compatible bug fixes
- Minor version (0.x.0): Backward-compatible feature additions
- Major version (x.0.0): Incompatible API changes
Multi-Package Management Solution
Large projects can adopt a monorepo structure:
packages/
├── components/
│ └── package.json
├── theme/
│ └── package.json
└── utils/
└── package.json
Automation Tool Integration
Use Plop.js to generate component templates:
// plopfile.js
module.exports = function(plop) {
plop.setGenerator('component', {
description: 'Create a new component',
prompts: [{
type: 'input',
name: 'name',
message: 'Component name(PascalCase):'
}],
actions: [{
type: 'add',
path: 'src/components/{{name}}/index.tsx',
templateFile: 'templates/component.hbs'
}]
});
};
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn