@qlover/create-app 0.7.14 → 0.7.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/next-app/README.en.md +131 -0
  5. package/dist/templates/next-app/README.md +115 -20
  6. package/dist/templates/next-app/docs/en/api.md +387 -0
  7. package/dist/templates/next-app/docs/en/component.md +544 -0
  8. package/dist/templates/next-app/docs/en/database.md +496 -0
  9. package/dist/templates/next-app/docs/en/development-guide.md +727 -0
  10. package/dist/templates/next-app/docs/en/env.md +563 -0
  11. package/dist/templates/next-app/docs/en/i18n.md +287 -0
  12. package/dist/templates/next-app/docs/en/index.md +166 -0
  13. package/dist/templates/next-app/docs/en/page.md +457 -0
  14. package/dist/templates/next-app/docs/en/project-structure.md +177 -0
  15. package/dist/templates/next-app/docs/en/router.md +427 -0
  16. package/dist/templates/next-app/docs/en/theme.md +532 -0
  17. package/dist/templates/next-app/docs/en/validator.md +478 -0
  18. package/dist/templates/next-app/docs/zh/api.md +387 -0
  19. package/dist/templates/next-app/docs/zh/component.md +544 -0
  20. package/dist/templates/next-app/docs/zh/database.md +496 -0
  21. package/dist/templates/next-app/docs/zh/development-guide.md +727 -0
  22. package/dist/templates/next-app/docs/zh/env.md +563 -0
  23. package/dist/templates/next-app/docs/zh/i18n.md +287 -0
  24. package/dist/templates/next-app/docs/zh/index.md +166 -0
  25. package/dist/templates/next-app/docs/zh/page.md +457 -0
  26. package/dist/templates/next-app/docs/zh/project-structure.md +177 -0
  27. package/dist/templates/next-app/docs/zh/router.md +427 -0
  28. package/dist/templates/next-app/docs/zh/theme.md +532 -0
  29. package/dist/templates/next-app/docs/zh/validator.md +476 -0
  30. package/package.json +1 -1
  31. package/dist/templates/next-app/docs/env.md +0 -94
@@ -0,0 +1,544 @@
1
+ # Component Development and State Management Guide
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Component Architecture Overview](#component-architecture-overview)
6
+ 2. [Component Architecture and Design Principles](#component-architecture-and-design-principles)
7
+ 3. [State Management System](#state-management-system)
8
+ 4. [Component Communication and Event Handling](#component-communication-and-event-handling)
9
+ 5. [Component Testing and Performance Optimization](#component-testing-and-performance-optimization)
10
+ 6. [Best Practices and Examples](#best-practices-and-examples)
11
+
12
+ ## Component Architecture Overview
13
+
14
+ ### 1. Overall Architecture
15
+
16
+ The project adopts a layered component architecture design:
17
+
18
+ ```
19
+ Component Layer State Layer
20
+ ┌──────────────┐ ┌──────────────┐
21
+ │ UI Components│ │State Interface│
22
+ ├──────────────┤ ├──────────────┤
23
+ │ Containers │ ◄─────┤State Implement│
24
+ ├──────────────┤ ├──────────────┤
25
+ │ Business │ │State Actions │
26
+ └──────────────┘ └──────────────┘
27
+ ```
28
+
29
+ ### 2. Core Concepts
30
+
31
+ - **UI Components**: Pure presentation components, no business logic
32
+ - **Container Components**: Responsible for state management and business logic
33
+ - **Business Components**: Components for specific business scenarios
34
+ - **State Management**: Store pattern-based state management system
35
+
36
+ ### 3. Technology Stack
37
+
38
+ - **React + Next.js**: Base framework
39
+ - **TypeScript**: Type system
40
+ - **Inversify**: Dependency injection
41
+ - **Ant Design**: UI component library
42
+ - **Tailwind CSS**: Styling system
43
+
44
+ ## Component Architecture and Design Principles
45
+
46
+ ### 1. Component Categories
47
+
48
+ ```typescript
49
+ // 1. UI Component
50
+ export function Button({ onClick, children }: ButtonProps) {
51
+ return (
52
+ <button
53
+ onClick={onClick}
54
+ className="px-4 py-2 bg-primary text-white rounded"
55
+ >
56
+ {children}
57
+ </button>
58
+ );
59
+ }
60
+
61
+ // 2. Container Component
62
+ export function UserProfileContainer() {
63
+ const userStore = useIOC(UserStore);
64
+ const user = useStore(userStore, userStore.selector.user);
65
+
66
+ return <UserProfile user={user} />;
67
+ }
68
+
69
+ // 3. Business Component
70
+ export function LoginForm({ tt }: { tt: LoginI18nInterface }) {
71
+ const userService = useIOC(I.UserServiceInterface);
72
+
73
+ const handleLogin = async (values: LoginFormData) => {
74
+ await userService.login(values);
75
+ };
76
+
77
+ return (
78
+ <Form onFinish={handleLogin}>
79
+ {/* Form content */}
80
+ </Form>
81
+ );
82
+ }
83
+ ```
84
+
85
+ ### 2. Component Providers
86
+
87
+ ```typescript
88
+ // Combine multiple providers
89
+ export function ComboProvider({
90
+ themeConfig,
91
+ children
92
+ }: Props) {
93
+ const mounted = useMountedClient();
94
+ const IOC = clientIOC.create();
95
+
96
+ return (
97
+ <AntdThemeProvider theme={themeConfig.antdTheme}>
98
+ <ThemeProvider
99
+ themes={themeConfig.supportedThemes}
100
+ defaultTheme={themeConfig.defaultTheme}
101
+ >
102
+ <BootstrapsProvider>
103
+ <AntdRegistry>
104
+ {mounted ? children : null}
105
+ </AntdRegistry>
106
+ </BootstrapsProvider>
107
+ </ThemeProvider>
108
+ </AntdThemeProvider>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ### 3. Component Interface Design
114
+
115
+ ```typescript
116
+ // 1. Component interface definition
117
+ interface ChatComponentInterface {
118
+ // Property definitions
119
+ messages: MessageInterface[];
120
+ loading?: boolean;
121
+
122
+ // Event handlers
123
+ onSend: (message: string) => void;
124
+ onClear: () => void;
125
+ }
126
+
127
+ // 2. Component implementation
128
+ @injectable()
129
+ export class ChatComponent implements ChatComponentInterface {
130
+ constructor(
131
+ @inject(ChatStore) private store: ChatStoreInterface,
132
+ @inject(I.Logger) private logger: LoggerInterface
133
+ ) {}
134
+
135
+ // Implement interface methods
136
+ async onSend(message: string) {
137
+ try {
138
+ await this.store.sendMessage(message);
139
+ } catch (error) {
140
+ this.logger.error('Failed to send message:', error);
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ ## State Management System
147
+
148
+ ### 1. State Interfaces
149
+
150
+ ```typescript
151
+ // 1. State interface definition
152
+ export interface StoreStateInterface {
153
+ readonly loading?: boolean;
154
+ readonly error?: Error | null;
155
+ }
156
+
157
+ // 2. Async state interface
158
+ export interface AsyncStateInterface<T> {
159
+ loading: boolean;
160
+ result: T | null;
161
+ error: unknown | null;
162
+ startTime: number;
163
+ endTime: number;
164
+ }
165
+
166
+ // 3. Request state implementation
167
+ export class RequestState<T = unknown> implements AsyncStateInterface<T> {
168
+ startTime: number;
169
+ endTime: number;
170
+
171
+ constructor(
172
+ public loading: boolean = false,
173
+ public result: T | null = null,
174
+ public error: unknown | null = null
175
+ ) {
176
+ this.startTime = Date.now();
177
+ this.endTime = 0;
178
+ }
179
+
180
+ end(): this {
181
+ this.endTime = Date.now();
182
+ return this;
183
+ }
184
+ }
185
+ ```
186
+
187
+ ### 2. Store Implementation
188
+
189
+ ```typescript
190
+ // 1. Store base class
191
+ export abstract class StoreInterface<State extends StoreStateInterface> {
192
+ protected state: State;
193
+ protected subscribers: Set<(state: State) => void>;
194
+
195
+ constructor(initialState: () => State) {
196
+ this.state = initialState();
197
+ this.subscribers = new Set();
198
+ }
199
+
200
+ // State update
201
+ protected emit(newState: State): void {
202
+ this.state = newState;
203
+ this.subscribers.forEach((subscriber) => subscriber(this.state));
204
+ }
205
+
206
+ // Selectors
207
+ selector = {
208
+ loading: (state: State) => state.loading,
209
+ error: (state: State) => state.error
210
+ };
211
+ }
212
+
213
+ // 2. Concrete Store implementation
214
+ @injectable()
215
+ export class UserStore extends StoreInterface<UserState> {
216
+ constructor(@inject(UserService) private userService: UserServiceInterface) {
217
+ super(() => ({
218
+ user: null,
219
+ loading: false,
220
+ error: null
221
+ }));
222
+ }
223
+
224
+ async fetchUser(id: string) {
225
+ this.emit({ ...this.state, loading: true });
226
+ try {
227
+ const user = await this.userService.getUser(id);
228
+ this.emit({ ...this.state, user, loading: false });
229
+ } catch (error) {
230
+ this.emit({ ...this.state, error, loading: false });
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ ### 3. State Usage
237
+
238
+ ```typescript
239
+ // 1. Using Store in components
240
+ export function UserProfile() {
241
+ const userStore = useIOC(UserStore);
242
+ const user = useStore(userStore, userStore.selector.user);
243
+ const loading = useStore(userStore, userStore.selector.loading);
244
+
245
+ useEffect(() => {
246
+ userStore.fetchUser(userId);
247
+ }, [userStore, userId]);
248
+
249
+ if (loading) return <Loading />;
250
+ if (!user) return <NotFound />;
251
+
252
+ return <UserInfo user={user} />;
253
+ }
254
+
255
+ // 2. Combining multiple Stores
256
+ export function Dashboard() {
257
+ const userStore = useIOC(UserStore);
258
+ const statsStore = useIOC(StatsStore);
259
+
260
+ const user = useStore(userStore, userStore.selector.user);
261
+ const stats = useStore(statsStore, statsStore.selector.stats);
262
+
263
+ return (
264
+ <div>
265
+ <UserWidget user={user} />
266
+ <StatsWidget stats={stats} />
267
+ </div>
268
+ );
269
+ }
270
+ ```
271
+
272
+ ## Component Communication and Event Handling
273
+
274
+ ### 1. Event Handling
275
+
276
+ ```typescript
277
+ // 1. Define event interface
278
+ interface ChatEvents {
279
+ onSend: (message: string) => void;
280
+ onClear: () => void;
281
+ onError: (error: Error) => void;
282
+ }
283
+
284
+ // 2. Implement event handling
285
+ export function ChatComponent({ onSend, onClear, onError }: ChatEvents) {
286
+ const handleSend = useCallback(async (message: string) => {
287
+ try {
288
+ await onSend(message);
289
+ } catch (error) {
290
+ onError(error as Error);
291
+ }
292
+ }, [onSend, onError]);
293
+
294
+ return (
295
+ <div>
296
+ <ChatInput onSend={handleSend} />
297
+ <ClearButton onClick={onClear} />
298
+ </div>
299
+ );
300
+ }
301
+ ```
302
+
303
+ ### 2. Component Communication
304
+
305
+ ```typescript
306
+ // 1. Through props
307
+ export function ParentComponent() {
308
+ const [data, setData] = useState<Data>();
309
+
310
+ return (
311
+ <ChildComponent
312
+ data={data}
313
+ onUpdate={setData}
314
+ />
315
+ );
316
+ }
317
+
318
+ // 2. Through Context
319
+ const ThemeContext = createContext<Theme>(defaultTheme);
320
+
321
+ export function ThemeProvider({ children }: PropsWithChildren) {
322
+ const [theme, setTheme] = useState(defaultTheme);
323
+
324
+ return (
325
+ <ThemeContext.Provider value={{ theme, setTheme }}>
326
+ {children}
327
+ </ThemeContext.Provider>
328
+ );
329
+ }
330
+ ```
331
+
332
+ ## Component Testing and Performance Optimization
333
+
334
+ ### 1. Component Testing
335
+
336
+ ```typescript
337
+ // 1. Unit testing
338
+ describe('UserProfile', () => {
339
+ it('should render user info', () => {
340
+ const user = { id: '1', name: 'Test' };
341
+ render(<UserProfile user={user} />);
342
+
343
+ expect(screen.getByText(user.name)).toBeInTheDocument();
344
+ });
345
+
346
+ it('should handle loading state', () => {
347
+ render(<UserProfile loading />);
348
+ expect(screen.getByTestId('loading')).toBeInTheDocument();
349
+ });
350
+ });
351
+
352
+ // 2. Integration testing
353
+ describe('LoginForm', () => {
354
+ it('should handle login flow', async () => {
355
+ const mockLogin = jest.fn();
356
+ const { getByLabelText, getByRole } = render(
357
+ <LoginForm onLogin={mockLogin} />
358
+ );
359
+
360
+ await userEvent.type(getByLabelText('Email'), 'test@example.com');
361
+ await userEvent.type(getByLabelText('Password'), 'password');
362
+ await userEvent.click(getByRole('button', { name: 'Login' }));
363
+
364
+ expect(mockLogin).toHaveBeenCalledWith({
365
+ email: 'test@example.com',
366
+ password: 'password'
367
+ });
368
+ });
369
+ });
370
+ ```
371
+
372
+ ### 2. Performance Optimization
373
+
374
+ ```typescript
375
+ // 1. Using memo for render optimization
376
+ const UserCard = memo(function UserCard({ user }: UserCardProps) {
377
+ return (
378
+ <div>
379
+ <h3>{user.name}</h3>
380
+ <p>{user.email}</p>
381
+ </div>
382
+ );
383
+ });
384
+
385
+ // 2. Using useMemo and useCallback
386
+ function UserList({ users }: UserListProps) {
387
+ const sortedUsers = useMemo(() => {
388
+ return [...users].sort((a, b) => a.name.localeCompare(b.name));
389
+ }, [users]);
390
+
391
+ const handleUserClick = useCallback((userId: string) => {
392
+ // Handle user click
393
+ }, []);
394
+
395
+ return (
396
+ <div>
397
+ {sortedUsers.map(user => (
398
+ <UserCard
399
+ key={user.id}
400
+ user={user}
401
+ onClick={handleUserClick}
402
+ />
403
+ ))}
404
+ </div>
405
+ );
406
+ }
407
+ ```
408
+
409
+ ## Best Practices and Examples
410
+
411
+ ### 1. Component Design Principles
412
+
413
+ ```typescript
414
+ // 1. Single Responsibility Principle
415
+ // ❌ Wrong: Too many responsibilities
416
+ function UserCard({ user, onEdit, onDelete, onShare }) {
417
+ return (
418
+ <div>
419
+ <UserInfo user={user} />
420
+ <UserActions user={user} />
421
+ <SocialSharing user={user} />
422
+ </div>
423
+ );
424
+ }
425
+
426
+ // ✅ Correct: Split into focused components
427
+ function UserCard({ user }) {
428
+ return <UserInfo user={user} />;
429
+ }
430
+
431
+ function UserActions({ user }) {
432
+ return (
433
+ <div>
434
+ <EditButton user={user} />
435
+ <DeleteButton user={user} />
436
+ </div>
437
+ );
438
+ }
439
+
440
+ // 2. Composition over Inheritance
441
+ // ❌ Wrong: Using inheritance
442
+ class SpecialButton extends Button {
443
+ render() {
444
+ return <button className="special">{this.props.children}</button>;
445
+ }
446
+ }
447
+
448
+ // ✅ Correct: Using composition
449
+ function Button({ variant, children, ...props }) {
450
+ return (
451
+ <button className={`btn-${variant}`} {...props}>
452
+ {children}
453
+ </button>
454
+ );
455
+ }
456
+ ```
457
+
458
+ ### 2. State Management Best Practices
459
+
460
+ ```typescript
461
+ // 1. State isolation
462
+ @injectable()
463
+ export class UserStore extends StoreInterface<UserState> {
464
+ // Encapsulate state logic in Store
465
+ private async validateUser(user: User): Promise<boolean> {
466
+ return this.validator.validate(user);
467
+ }
468
+
469
+ async updateUser(user: User) {
470
+ if (await this.validateUser(user)) {
471
+ this.emit({ ...this.state, user });
472
+ }
473
+ }
474
+ }
475
+
476
+ // 2. Selector pattern
477
+ @injectable()
478
+ export class DashboardStore extends StoreInterface<DashboardState> {
479
+ selector = {
480
+ ...super.selector,
481
+ activeUsers: (state: DashboardState) =>
482
+ state.users.filter((u) => u.isActive),
483
+ totalRevenue: (state: DashboardState) =>
484
+ state.transactions.reduce((sum, t) => sum + t.amount, 0)
485
+ };
486
+ }
487
+ ```
488
+
489
+ ### 3. Performance Optimization Examples
490
+
491
+ ```typescript
492
+ // 1. Virtualized list
493
+ function VirtualizedList({ items }: Props) {
494
+ return (
495
+ <VirtualScroller
496
+ itemCount={items.length}
497
+ itemSize={50}
498
+ height={400}
499
+ width="100%"
500
+ >
501
+ {({ index, style }) => (
502
+ <div style={style}>
503
+ <ListItem item={items[index]} />
504
+ </div>
505
+ )}
506
+ </VirtualScroller>
507
+ );
508
+ }
509
+
510
+ // 2. Lazy loading components
511
+ const LazyUserProfile = lazy(() => import('./UserProfile'));
512
+
513
+ function App() {
514
+ return (
515
+ <Suspense fallback={<Loading />}>
516
+ <LazyUserProfile />
517
+ </Suspense>
518
+ );
519
+ }
520
+ ```
521
+
522
+ ## Summary
523
+
524
+ The project's component and state management system follows these principles:
525
+
526
+ 1. **Component Design**:
527
+ - Clear responsibility separation
528
+ - Reusable component interfaces
529
+ - Type-safe property definitions
530
+
531
+ 2. **State Management**:
532
+ - Centralized state management
533
+ - Reactive state updates
534
+ - Type-safe state definitions
535
+
536
+ 3. **Performance Optimization**:
537
+ - Component-level optimization
538
+ - State update optimization
539
+ - Resource loading optimization
540
+
541
+ 4. **Best Practices**:
542
+ - Single Responsibility Principle
543
+ - Composition over Inheritance
544
+ - State Isolation Principle