diff --git a/README.md b/README.md index 578a80a..c5b06b3 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,8 @@ graph TD * 🛡️ [security.md](./backend/nestjs/security.md) * 🟢 **[nodejs/](./backend/nodejs/)** * 📄 [readme.md](./backend/nodejs/readme.md) + * 📄 **[docs/](./docs/)** + * 🤖 [vibe-coding-agents.md](./docs/vibe-coding-agents.md) * 🖥️ **[frontend/](./frontend/)** * 📄 [readme.md](./frontend/readme.md) * 🅰️ **[angular/](./frontend/angular/)** diff --git a/backend/nestjs/readme.md b/backend/nestjs/readme.md index d2bc321..a5cb62a 100644 --- a/backend/nestjs/readme.md +++ b/backend/nestjs/readme.md @@ -19,7 +19,7 @@ last_updated: 2026-03-23 Этот документ определяет **лучшие практики (best practices)** для фреймворка NestJS. Руководство создано для обеспечения масштабируемости, безопасности и качества Enterprise-приложений. -# Context & Scope +## 🎯 Context & Scope - **Primary Goal:** Предоставить строгие архитектурные правила и 30 паттернов разработки на NestJS. - **Target Tooling:** AI-агенты (Cursor, Windsurf, Copilot) и Senior-разработчики. - **Tech Stack Version:** NestJS 10+ @@ -29,47 +29,47 @@ last_updated: 2026-03-23 --- -## 1. Clean Architecture Modules (Изоляция логики) -### ❌ Bad Practice +### 🚨 1. Clean Architecture Modules (Изоляция логики) +#### ❌ Bad Practice ```typescript @Injectable() export class UsersService { constructor(@InjectRepository(User) private repo: Repository) {} // Жесткая привязка к TypeORM } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Injectable() export class UsersService { constructor(@Inject('IUserRepository') private repo: IUserRepository) {} // Интерфейс порта } ``` -### 🚀 Solution +#### 🚀 Solution Применяйте инверсию зависимостей (Dependency Inversion). Бизнес-логика зависит от абстракций (интерфейсов), а не от конкретных ORM. -## 2. Global ValidationPipe -### ❌ Bad Practice +### 🚨 2. Global ValidationPipe +#### ❌ Bad Practice ```typescript @Post() create(@Body() dto: CreateUserDto) { if (!dto.email) throw new BadRequestException('Email required'); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript // main.ts app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true })); ``` -### 🚀 Solution +#### 🚀 Solution Включите глобальную валидацию на основе `class-validator` и `whitelist`, чтобы автоматически отсекать неизвестные поля. -## 3. Data Transfer Objects (DTO) -### ❌ Bad Practice +### 🚨 3. Data Transfer Objects (DTO) +#### ❌ Bad Practice ```typescript @Post() create(@Body() body: any) {} // Потеря типизации ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript export class CreateUserDto { @IsEmail() @@ -78,11 +78,11 @@ export class CreateUserDto { @Post() create(@Body() dto: CreateUserDto) {} ``` -### 🚀 Solution +#### 🚀 Solution Все данные от клиента должны строго описываться через DTO с декораторами валидации. -## 4. Fat Controllers vs Thin Controllers -### ❌ Bad Practice +### 🚨 4. Fat Controllers vs Thin Controllers +#### ❌ Bad Practice ```typescript @Post() async createUser(@Body() dto: CreateDto) { @@ -90,22 +90,22 @@ async createUser(@Body() dto: CreateDto) { return this.db.users.create({ ...dto, hash }); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Post() async createUser(@Body() dto: CreateDto) { return this.userService.register(dto); } ``` -### 🚀 Solution +#### 🚀 Solution Контроллеры только маршрутизируют запросы. Вся логика — в Service Layer. -## 5. Global Exception Filter -### ❌ Bad Practice +### 🚨 5. Global Exception Filter +#### ❌ Bad Practice ```typescript try { ... } catch (e) { throw new HttpException('Error', 500); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Catch() export class AllExceptionsFilter implements ExceptionFilter { @@ -114,15 +114,15 @@ export class AllExceptionsFilter implements ExceptionFilter { // main.ts app.useGlobalFilters(new AllExceptionsFilter()); ``` -### 🚀 Solution +#### 🚀 Solution Используйте фильтры исключений для стандартизации формата всех HTTP-ошибок API. -## 6. Async Module Configuration -### ❌ Bad Practice +### 🚨 6. Async Module Configuration +#### ❌ Bad Practice ```typescript TypeOrmModule.forRoot({ url: process.env.DB_URL }) // Переменные могут быть еще не загружены ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript TypeOrmModule.forRootAsync({ imports: [ConfigModule], @@ -130,105 +130,105 @@ TypeOrmModule.forRootAsync({ inject: [ConfigService], }) ``` -### 🚀 Solution +#### 🚀 Solution Для сторонних модулей всегда используйте `forRootAsync` / `registerAsync`, чтобы безопасно внедрять конфигурации. -## 7. Configuration Management -### ❌ Bad Practice +### 🚨 7. Configuration Management +#### ❌ Bad Practice ```typescript const secret = process.env.JWT_SECRET; // Прямой вызов ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript constructor(private configService: ConfigService) {} const secret = this.configService.get('JWT_SECRET'); ``` -### 🚀 Solution +#### 🚀 Solution Используйте `@nestjs/config` для безопасного извлечения переменных с типизацией. -## 8. Custom Decorators (Извлечение User) -### ❌ Bad Practice +### 🚨 8. Custom Decorators (Извлечение User) +#### ❌ Bad Practice ```typescript @Get() getProfile(@Req() req: Request) { return req.user; } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript export const CurrentUser = createParamDecorator((data, ctx: ExecutionContext) => ctx.switchToHttp().getRequest().user); @Get() getProfile(@CurrentUser() user: UserEntity) { return user; } ``` -### 🚀 Solution +#### 🚀 Solution Создавайте кастомные декораторы для чистой экстракции данных из Request (например, текущего пользователя). -## 9. JWT Guards (Защита роутов) -### ❌ Bad Practice +### 🚨 9. JWT Guards (Защита роутов) +#### ❌ Bad Practice ```typescript @Get() getData(@Req() req) { if (!req.headers.auth) throw new UnauthorizedException(); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @UseGuards(JwtAuthGuard) @Get() getData() {} ``` -### 🚀 Solution +#### 🚀 Solution Авторизация должна происходить до контроллера через Guards (например, стратегия Passport JWT). -## 10. Role-Based Access Control (RBAC) -### ❌ Bad Practice +### 🚨 10. Role-Based Access Control (RBAC) +#### ❌ Bad Practice ```typescript @Get() getAdminData(@CurrentUser() user) { if (user.role !== 'ADMIN') throw new ForbiddenException(); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Roles('ADMIN') @UseGuards(JwtAuthGuard, RolesGuard) @Get() getAdminData() {} ``` -### 🚀 Solution +#### 🚀 Solution Используйте кастомные декораторы ролей (`@Roles`) и `RolesGuard` для декларативного контроля доступа. -## 11. Built-in Pipes for Transformation -### ❌ Bad Practice +### 🚨 11. Built-in Pipes for Transformation +#### ❌ Bad Practice ```typescript @Get(':id') getUser(@Param('id') id: string) { const userId = parseInt(id, 10); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Get(':id') getUser(@Param('id', ParseIntPipe) id: number) {} ``` -### 🚀 Solution +#### 🚀 Solution Используйте встроенные Pipes (`ParseIntPipe`, `ParseUUIDPipe`) для автоматической конвертации и валидации параметров. -## 12. Response Interceptors (Трансформация ответа) -### ❌ Bad Practice +### 🚨 12. Response Interceptors (Трансформация ответа) +#### ❌ Bad Practice ```typescript return { success: true, data: result, timestamp: new Date() }; // Дублирование везде ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Injectable() export class TransformInterceptor implements NestInterceptor { intercept(context, next) { return next.handle().pipe(map(data => ({ success: true, data }))); } } ``` -### 🚀 Solution +#### 🚀 Solution Стандартизируйте структуру успешного ответа глобально через Interceptor. -## 13. Logging Interceptors -### ❌ Bad Practice +### 🚨 13. Logging Interceptors +#### ❌ Bad Practice ```typescript @Get() getData() { console.log('Request started'); /* ... */ console.log('Done'); } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Injectable() export class LoggingInterceptor implements NestInterceptor { @@ -238,233 +238,236 @@ export class LoggingInterceptor implements NestInterceptor { } } ``` -### 🚀 Solution +#### 🚀 Solution Логируйте время выполнения и детали запроса абстрактно через Interceptors. -## 14. Transaction Handling (TypeORM) -### ❌ Bad Practice +### 🚨 14. Transaction Handling (TypeORM) +#### ❌ Bad Practice ```typescript await this.repo1.save(data1); await this.repo2.save(data2); // Нет транзакции ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript await this.dataSource.transaction(async manager => { await manager.save(Entity1, data1); await manager.save(Entity2, data2); }); ``` -### 🚀 Solution +#### 🚀 Solution Критические мутации нескольких таблиц должны оборачиваться в транзакции через `DataSource.transaction`. -## 15. Swagger / OpenAPI Documentation -### ❌ Bad Practice +### 🚨 15. Swagger / OpenAPI Documentation +#### ❌ Bad Practice ```typescript // Нет никаких аннотаций DTO export class CreateDogDto { name: string; } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript export class CreateDogDto { @ApiProperty({ example: 'Rex', description: 'The name of the dog' }) name: string; } ``` -### 🚀 Solution +#### 🚀 Solution Документируйте все свойства DTO через `@ApiProperty()`. Swagger автоматически сгенерирует схему. -## 16. Rate Limiting (ThrottlerModule) -### ❌ Bad Practice +### 🚨 16. Rate Limiting (ThrottlerModule) +#### ❌ Bad Practice // Нет защиты от DDoS и брутфорса -### ✅ Best Practice +#### ✅ Best Practice ```typescript // app.module.ts ThrottlerModule.forRoot([{ ttl: 60000, limit: 10 }]) ``` -### 🚀 Solution +#### 🚀 Solution Обязательно подключайте `@nestjs/throttler` для защиты API от перегрузок. -## 17. Caching Results -### ❌ Bad Practice +### 🚨 17. Caching Results +#### ❌ Bad Practice // Каждый запрос делает тяжелый расчет в БД -### ✅ Best Practice +#### ✅ Best Practice ```typescript @UseInterceptors(CacheInterceptor) @CacheTTL(30) // 30 секунд @Get('stats') getStats() {} ``` -### 🚀 Solution +#### 🚀 Solution Кешируйте тяжелые запросы через `CacheModule` (в памяти или Redis), чтобы разгрузить БД. -## 18. Event Emitter (Слабая связность) -### ❌ Bad Practice +### 🚨 18. Event Emitter (Слабая связность) +#### ❌ Bad Practice ```typescript await this.userService.create(); await this.emailService.send(); // Жесткая привязка зависимостей ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript await this.userService.create(); this.eventEmitter.emit('user.created', new UserCreatedEvent(user)); ``` -### 🚀 Solution +#### 🚀 Solution Используйте `@nestjs/event-emitter`. Сервис не должен ждать отправки письма, а просто публикует событие. -## 19. Task Scheduling (Cron) -### ❌ Bad Practice +### 🚨 19. Task Scheduling (Cron) +#### ❌ Bad Practice ```typescript setInterval(() => this.cleanupData(), 1000 * 60 * 60); ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT) handleCron() { this.cleanupData(); } ``` -### 🚀 Solution +#### 🚀 Solution Для фоновых задач используйте `@nestjs/schedule` с декларативными декораторами. -## 20. Microservices: Message Patterns -### ❌ Bad Practice +### 🚨 20. Microservices: Message Patterns +#### ❌ Bad Practice ```typescript @Post() // Использование HTTP для межсервисного общения ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @MessagePattern({ cmd: 'get_user' }) getUser(data: any) { return this.userService.findById(data.id); } ``` -### 🚀 Solution +#### 🚀 Solution Для общения микросервисов внутри кластера используйте TCP, Redis или RabbitMQ через `@MessagePattern`. -## 21. Health Checks (Terminus) -### ❌ Bad Practice +### 🚨 21. Health Checks (Terminus) +#### ❌ Bad Practice ```typescript @Get('ping') ping() { return 'pong'; } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Get('health') @HealthCheck() check() { return this.health.check([() => this.db.pingCheck('database')]); } ``` -### 🚀 Solution +#### 🚀 Solution Используйте `@nestjs/terminus` для глубоких проверок (БД, память) для Kubernetes Liveness Probes. -## 22. Avoiding Circular Dependencies -### ❌ Bad Practice +### 🚨 22. Avoiding Circular Dependencies +#### ❌ Bad Practice ```typescript // UserService -> AuthService -> UserService @Injectable() class UserService { constructor(private auth: AuthService) {} } ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Injectable() class UserService { constructor(@Inject(forwardRef(() => AuthService)) private auth: AuthService) {} } ``` -### 🚀 Solution +#### 🚀 Solution Если архитектура вынуждает циклическую зависимость, используйте `forwardRef()`, однако лучше отрефакторить код. -## 23. Module Re-exporting -### ❌ Bad Practice +### 🚨 23. Module Re-exporting +#### ❌ Bad Practice ```typescript // Модуль B импортирует Модуль А, Модуль С импортирует Модуль А... ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Module({ imports: [DatabaseModule], exports: [DatabaseModule] }) export class CoreModule {} // Глобальный фасад ``` -### 🚀 Solution +#### 🚀 Solution Используйте экспорт модулей для создания общих Core/Shared модулей, инкапсулирующих общую логику. -## 24. Global Middleware -### ❌ Bad Practice +### 🚨 24. Global Middleware +#### ❌ Bad Practice // Определение логгера запросов в каждом месте -### ✅ Best Practice +#### ✅ Best Practice ```typescript export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(LoggerMiddleware).forRoutes('*'); } } ``` -### 🚀 Solution +#### 🚀 Solution Глобальные операции до попадания в Guards (например, Request ID) делайте через `NestMiddleware`. -## 25. Unit Testing Providers -### ❌ Bad Practice +### 🚨 25. Unit Testing Providers +#### ❌ Bad Practice ```typescript const service = new UserService(new Database()); // Реальная БД в тестах ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript const module = await Test.createTestingModule({ providers: [UserService, { provide: getRepositoryToken(User), useValue: mockUserRepo }], }).compile(); ``` -### 🚀 Solution +#### 🚀 Solution Все юнит-тесты должны использовать инъекцию моков (Mocks) через `Test.createTestingModule`. -## 26. Custom Validation Constraints -### ❌ Bad Practice +### 🚨 26. Custom Validation Constraints +#### ❌ Bad Practice ```typescript if (!isEmailUnique(dto.email)) throw error; // Ручная логика в сервисе ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript @ValidatorConstraint({ async: true }) export class IsUniqueConstraint implements ValidatorConstraintInterface { ... } @Validate(IsUniqueConstraint) email: string; ``` -### 🚀 Solution +#### 🚀 Solution Создавайте кастомные правила для `class-validator`, в том числе асинхронные проверки (проверка БД). -## 27. File Uploading (Multer) -### ❌ Bad Practice +### 🚨 27. File Uploading (Multer) +#### ❌ Bad Practice // Обработка потоков руками -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Post('upload') @UseInterceptors(FileInterceptor('file')) uploadFile(@UploadedFile() file: Express.Multer.File) {} ``` -### 🚀 Solution +#### 🚀 Solution Для приема файлов стандартом является встроенный `FileInterceptor` на базе Multer. -## 28. Serialization (ClassSerializerInterceptor) -### ❌ Bad Practice +### 🚨 28. Serialization (ClassSerializerInterceptor) +#### ❌ Bad Practice ```typescript const { password, ...safeUser } = user; // Ручное удаление пароля ``` -### ✅ Best Practice +#### ✅ Best Practice ```typescript class UserEntity { @Exclude() password: string; } @UseInterceptors(ClassSerializerInterceptor) // Авто-очистка @Get() getUser() { return new UserEntity(data); } ``` -### 🚀 Solution +#### 🚀 Solution Используйте `@Exclude()` из `class-transformer` вместе с `ClassSerializerInterceptor` для скрытия полей. -## 29. Fastify Integration -### ❌ Bad Practice +### 🚨 29. Fastify Integration +#### ❌ Bad Practice // Вызов специфичных методов req.expressMethod -### ✅ Best Practice +#### ✅ Best Practice ```typescript const app = await NestFactory.create(AppModule, new FastifyAdapter()); ``` -### 🚀 Solution +#### 🚀 Solution Пишите платформо-независимый код. Если нужна экстремальная производительность, Nest легко переключается с Express на Fastify. -## 30. Shutdown Hooks (Graceful Shutdown) -### ❌ Bad Practice +### 🚨 30. Shutdown Hooks (Graceful Shutdown) +#### ❌ Bad Practice // Приложение убивается мгновенно, прерывая активные соединения -### ✅ Best Practice +#### ✅ Best Practice ```typescript app.enableShutdownHooks(); @Injectable() class MyService implements OnApplicationShutdown { onApplicationShutdown() { /* Закрыть соединения */ } } ``` -### 🚀 Solution +#### 🚀 Solution Вызывайте `enableShutdownHooks()`, чтобы отлавливать SIGINT/SIGTERM и безопасно завершать процессы базы данных. +--- +[⬆️ Back to Top](#) +
diff --git a/docs/vibe-coding-agents.md b/docs/vibe-coding-agents.md new file mode 100644 index 0000000..2d9dc03 --- /dev/null +++ b/docs/vibe-coding-agents.md @@ -0,0 +1,68 @@ +--- +description: Discover the best strategies and production-ready techniques for optimizing AI Agents and Vibe Coding workflows to generate clean, scalable code architectures seamlessly. +tags: [vibe coding, ai agents, production-ready, clean code, code generation, ai tools, architecture patterns, prompt engineering] +--- + +> 📦 [best-practise](../README.md) / 📄 [docs](./) + +# 🤖 Vibe Coding Agents: Production-Ready Automation + +## 1. 🎯 Context & Scope + +- **Primary Goal:** Guide engineers and AI agents on optimizing instruction sets to achieve deterministic, production-ready "Vibe Coding" results. +- **Target Tooling:** Cursor, Windsurf, GitHub Copilot, Antigravity IDE. +- **Tech Stack Version:** Agnostic + +> [!IMPORTANT] +> **Vibe Coding Integrity:** Never trust an AI Agent blindly. Always provide strict architectural constraints and explicit context. + +--- + +## 2. 🧠 The "Vibe Coding" Mindset + +Vibe Coding shifts the developer's role from writing syntax to managing logic and constraints. By establishing robust meta-instructions, you can direct AI Agents to implement features flawlessly on the first attempt. + +### 📊 Agent Capability Matrix + +| Agent Characteristic | Advantage in Vibe Coding | Drawback without Context | +| :--- | :--- | :--- | +| **Speed** | Extremely fast code generation. | May introduce untested, legacy APIs. | +| **Refactoring** | Excellent at large-scale structural changes. | Can overwrite existing business logic. | +| **Boilerplate** | Instant scaffolding of complex setups. | Prone to generic, non-scalable patterns. | + +--- + +## 3. 🗺️ Agent Execution Architecture + +To harness Vibe Coding effectively, integrate a defined execution pipeline. + +```mermaid +graph TD + UserIntent[🗣️ User Intent] --> ContextLayer[📂 Context Retrieval] + ContextLayer --> ConstraintCheck[🛡️ Architectural Constraints] + ConstraintCheck --> CodeGeneration[⚡ AI Generation] + CodeGeneration --> Validation[✅ Validation & Tests] + + %% Design Token Styles for Mermaid Diagrams + classDef default fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px,color:#000; + classDef component fill:#e8f5e9,stroke:#4caf50,stroke-width:2px,color:#000; + classDef layout fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px,color:#000; + + class CodeGeneration component; + class ContextLayer component; + class UserIntent default; + class ConstraintCheck layout; + class Validation component; +``` + +--- + +## 4. ✅ Actionable Checklist for Vibe Coding + +Before deploying AI Agents for production tasks, verify the following: + +- [ ] Ensure all prompts explicitly reference the required files or functions. +- [ ] Confirm that `.cursorrules` or `.windsurfrules` are active and updated. +- [ ] Restrict the agent's context window to prevent hallucination. +- [ ] Review the generated code specifically for memory leaks or unhandled exceptions. +- [ ] Always write a failing test before instructing the AI to implement the solution. diff --git a/frontend/angular/readme.md b/frontend/angular/readme.md index 8d43d1e..ec075d5 100644 --- a/frontend/angular/readme.md +++ b/frontend/angular/readme.md @@ -9,9 +9,15 @@ ai_role: Senior Angular Performance Expert last_updated: 2026-03-22 --- +<<<<<<< feat/autonomous-vibe-coding-docs-10177351143416239543 +# 🅰️ Angular Best Practices & Production-Ready Patterns + +## 🎯 Context & Scope +======= # 🎨 Angular Best Practices & Production-Ready Patterns # 🎨 Context & Scope +>>>>>>> main - **Primary Goal:** Enforce strict adherence to modern Angular v20 patterns, specifically Zoneless reactivity and functional APIs for optimal best practices. - **Target Tooling:** Cursor, Windsurf, Antigravity. - **Tech Stack Version:** Angular 20 @@ -22,65 +28,65 @@ last_updated: 2026-03-22 > - **Never** use `@Input()` or `@Output()` decorators; strictly use `input()` and `output()` functional APIs. > - **Always** utilize the built-in control flow (`@if`, `@for`, `@switch`) instead of structural directives (`*ngIf`, `*ngFor`). -## I. Basics & Popular (1-15) +## 🚀 I. Basics & Popular (1-15) -## 1. Using `@Input()` Decorator +### 🚨 1. Using `@Input()` Decorator **Context:** Component Inputs -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript @Input() title: string = ''; ``` -### ⚠️ Problem +#### ⚠️ Problem The `@Input()` decorator operates outside the Signals reactivity system. Changes are not tracked granularly, requiring checks of the entire component tree (Dirty Checking) via Zone.js. -### ✅ Best Practice +#### ✅ Best Practice ```typescript title = input(''); ``` -### 🚀 Solution +#### 🚀 Solution Use Signal Inputs (`input()`). This allows Angular to precisely know *which* specific component requires an update, paving the way for Zoneless applications. -## 2. Using `@Output()` Decorator +### 🚨 2. Using `@Output()` Decorator **Context:** Component Outputs -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript @Output() save = new EventEmitter(); ``` -### ⚠️ Problem +#### ⚠️ Problem The classic `EventEmitter` adds an unnecessary layer of abstraction over RxJS Subject and does not integrate with the Angular functional API. -### ✅ Best Practice +#### ✅ Best Practice ```typescript save = output(); ``` -### 🚀 Solution +#### 🚀 Solution Use the `output()` function. It provides strict typing, better performance, and a unified API with Signal Inputs. -## 3. Two-Way Binding with `@Input()` and `@Output()` +### 🚨 3. Two-Way Binding with `@Input()` and `@Output()` **Context:** Model Synchronization -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript @Input() value: string; @Output() valueChange = new EventEmitter(); ``` -### ⚠️ Problem +#### ⚠️ Problem Boilerplate code that is easy to break if you make a mistake in naming the `Change` event. -### ✅ Best Practice +#### ✅ Best Practice ```typescript value = model(); ``` -### 🚀 Solution +#### 🚀 Solution Use `model()`. This creates a Signal that can be both read and written to, automatically synchronizing its state with the parent. -## 4. Structural Directives (`*ngIf`, `*ngFor`) +### 🚨 4. Structural Directives (`*ngIf`, `*ngFor`) **Context:** Template Control Flow -### ❌ Bad Practice +#### ❌ Bad Practice ```html
  • {{ item }}
  • ``` -### ⚠️ Problem +#### ⚠️ Problem Directives require importing `CommonModule` or `NgIf/NgFor`, increasing bundle size. Micro-template syntax is complex for static analysis and type-checking. -### ✅ Best Practice +#### ✅ Best Practice ```html @if (isLoaded()) { @for (item of items(); track item.id) { @@ -90,48 +96,48 @@ Directives require importing `CommonModule` or `NgIf/NgFor`, increasing bundle s } ``` -### 🚀 Solution +#### 🚀 Solution Use the built-in Control Flow (`@if`, `@for`). It is built into the compiler, requires no imports, supports improved type-narrowing, and runs faster. -## 5. Subscribing in Components (Logic in `ngOnInit`) +### 🚨 5. Subscribing in Components (Logic in `ngOnInit`) **Context:** Data Fetching -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript data: any; ngOnInit() { this.service.getData().subscribe(res => this.data = res); } ``` -### ⚠️ Problem +#### ⚠️ Problem Imperative subscriptions lead to memory leaks (if you forget to `unsubscribe`), "Callback Hell", and state desynchronization. Requires manual subscription management. -### ✅ Best Practice +#### ✅ Best Practice ```typescript data = toSignal(this.service.getData()); ``` -### 🚀 Solution +#### 🚀 Solution Use `toSignal()` to convert an Observable into a Signal. This automatically manages the subscription and integrates the data stream into the reactivity system. -## 6. `BehaviorSubject` for Local State +### 🚨 6. `BehaviorSubject` for Local State **Context:** Component State Management -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript private count$ = new BehaviorSubject(0); getCount() { return this.count$.value; } ``` -### ⚠️ Problem +#### ⚠️ Problem RxJS is overkill for simple synchronous state. `BehaviorSubject` requires `.value` for access and `.next()` for writes, increasing cognitive load. -### ✅ Best Practice +#### ✅ Best Practice ```typescript count = signal(0); // Access: count() // Update: count.set(1) ``` -### 🚀 Solution +#### 🚀 Solution Use `signal()` for local state. It is a primitive designed specifically for synchronizing UI and data. -## 7. Derived State with `ngOnChanges` +### 🚨 7. Derived State with `ngOnChanges` **Context:** Reactivity -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript ngOnChanges(changes: SimpleChanges) { if (changes['firstName']) { @@ -139,34 +145,34 @@ ngOnChanges(changes: SimpleChanges) { } } ``` -### ⚠️ Problem +#### ⚠️ Problem `ngOnChanges` is triggered only when Inputs change, has complex typing, and runs before View initialization. -### ✅ Best Practice +#### ✅ Best Practice ```typescript fullName = computed(() => `${this.firstName()} ${this.lastName()}`); ``` -### 🚀 Solution +#### 🚀 Solution Use `computed()`. The signal is recalculated *only* when its dependencies change, and the result is memoized (cached). -## 8. Constructor Dependency Injection +### 🚨 8. Constructor Dependency Injection **Context:** DI Pattern -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript constructor(private http: HttpClient, private store: Store) {} ``` -### ⚠️ Problem +#### ⚠️ Problem Constructors become cluttered with many dependencies. When inheriting classes, dependencies must be passed through `super()`. -### ✅ Best Practice +#### ✅ Best Practice ```typescript private http = inject(HttpClient); private store = inject(Store); ``` -### 🚀 Solution +#### 🚀 Solution Use the `inject()` function. It operates in the initialization context (fields or constructor), is type-safe, and does not require `super()` during inheritance. -## 9. Modules (`NgModule`) +### 🚨 9. Modules (`NgModule`) **Context:** App Architecture -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript @NgModule({ declarations: [AppComponent], @@ -174,122 +180,763 @@ Use the `inject()` function. It operates in the initialization context (fields o }) export class AppModule {} ``` -### ⚠️ Problem +#### ⚠️ Problem Modules create an unnecessary level of indirection. Components become dependent on the module context, complicating Lazy Loading and testing. -### ✅ Best Practice +#### ✅ Best Practice ```typescript @Component({ standalone: true, imports: [CommonModule] }) ``` -### 🚀 Solution +#### 🚀 Solution Use Standalone Components. This is the Angular v14+ standard that makes components self-sufficient and tree-shakable. -## 10. String-based Route Loading +### 🚨 10. String-based Route Loading **Context:** Lazy Loading Routing -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript loadChildren: () => import('./module').then(m => m.UserModule) ``` -### ⚠️ Problem +#### ⚠️ Problem Loading modules pulls in transitive dependencies that might not be needed. -### ✅ Best Practice +#### ✅ Best Practice ```typescript loadComponent: () => import('./user.component').then(c => c.UserComponent) ``` -### 🚀 Solution +#### 🚀 Solution Use `loadComponent` for routing to Standalone components. This ensures minimal chunk size. -## 11. Heavy Logic in Templates +### 🚨 11. Heavy Logic in Templates **Context:** Template Performance -### ❌ Bad Practice +#### ❌ Bad Practice ```html
    {{ calculateTotal(items) }}
    ``` -### ⚠️ Problem +#### ⚠️ Problem The `calculateTotal` function is called during *every* Change Detection (CD) cycle, even if `items` have not changed. This kills UI performance. -### ✅ Best Practice +#### ✅ Best Practice ```typescript total = computed(() => this.calculateTotal(this.items())); ``` ```html
    {{ total() }}
    ``` -### 🚀 Solution +#### 🚀 Solution Extract logic into `computed()` signals or Pure Pipes. They are only executed when input data changes. -## 12. Manual Subscription Management (`takeUntil`) +### 🚨 12. Manual Subscription Management (`takeUntil`) **Context:** RxJS Memory Leaks -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript destroy$ = new Subject(); ngOnDestroy() { this.destroy$.next(); } stream$.pipe(takeUntil(this.destroy$)).subscribe(); ``` -### ⚠️ Problem +#### ⚠️ Problem It's easy to forget `takeUntil` or `unsubscribe`. Requires a lot of boilerplate code in every component. -### ✅ Best Practice +#### ✅ Best Practice ```typescript stream$.pipe(takeUntilDestroyed()).subscribe(); ``` -### 🚀 Solution +#### 🚀 Solution Use the `takeUntilDestroyed()` operator. It automatically unsubscribes upon context destruction (component, directive, service). -## 13. Deeply Nested Components Passing Data +### 🚨 13. Deeply Nested Components Passing Data **Context:** Prop Drilling -### ❌ Bad Practice +#### ❌ Bad Practice ```html ``` -### ⚠️ Problem +#### ⚠️ Problem "Prop drilling" heavily couples intermediate components to data they don't need, just for the sake of passing it deeper. -### ✅ Best Practice +#### ✅ Best Practice ```typescript // Service theme = signal('dark'); // Grandchild theme = inject(ThemeService).theme; ``` -### 🚀 Solution +#### 🚀 Solution Use Signal Stores or services for state sharing, or the new `input()` API with context inheritance (in the future). -## 14. Accessing DOM directly (`ElementRef.nativeElement`) +### 🚨 14. Accessing DOM directly (`ElementRef.nativeElement`) **Context:** Security & Abstraction -### ❌ Bad Practice +#### ❌ Bad Practice ```typescript el.nativeElement.style.backgroundColor = 'red'; ``` -### ⚠️ Problem +#### ⚠️ Problem Direct DOM access breaks abstraction (doesn't work in SSR/Web Workers) and opens up XSS vulnerabilities. It bypasses Angular Sanitization mechanisms. -### ✅ Best Practice +#### ✅ Best Practice ```typescript // Use Renderer2 or bindings
    ``` -### 🚀 Solution +#### 🚀 Solution Use style/class bindings or `Renderer2`. For direct manipulations, consider directives. -## 15. Zone.js overhead +### 🚨 15. Zone.js overhead **Context:** Change Detection -### ❌ Bad Practice +#### ❌ Bad Practice The application relies on Zone.js for any asynchronous event (setTimeout, Promise, XHR). -### ⚠️ Problem +#### ⚠️ Problem Zone.js patches all browser APIs, adding overhead and increasing bundle size. CD triggers more often than necessary. -### ✅ Best Practice +#### ✅ Best Practice ```typescript bootstrapApplication(App, { providers: [provideExperimentalZonelessChangeDetection()] }); ``` -### 🚀 Solution +#### 🚀 Solution Migrate to Zoneless mode. Use Signals to notify Angular when a re-render is needed. --- +<<<<<<< feat/autonomous-vibe-coding-docs-10177351143416239543 +--- +[⬆️ Back to Top](#) + +## II. Architecture & DI (16-30) + +### 🚨 16. Services provided in 'root' vs Modules +**Context:** Tree Shaking +#### ❌ Bad Practice +```typescript +@NgModule({ providers: [MyService] }) +``` +#### ⚠️ Problem +The service is included in the bundle even if it is not used. +#### ✅ Best Practice +```typescript +@Injectable({ providedIn: 'root' }) +``` +#### 🚀 Solution +Always use `providedIn: 'root'`. This allows the bundler to remove unused services (Tree Shaking). + +### 🚨 17. Class-based Guards +**Context:** Routing Security +#### ❌ Bad Practice +```typescript +@Injectable() +export class AuthGuard implements CanActivate { ... } +``` +#### ⚠️ Problem +Class-based guards require more code and injections. They are less flexible for composition. +#### ✅ Best Practice +```typescript +export const authGuard: CanActivateFn = (route, state) => { + return inject(AuthService).isLoggedIn(); +}; +``` +#### 🚀 Solution +Use functional Guards (`CanActivateFn`). They are concise, easy to test, and composable. + +### 🚨 18. Class-based Interceptors +**Context:** HTTP Requests +#### ❌ Bad Practice +```typescript +@Injectable() +export class TokenInterceptor implements HttpInterceptor { ... } +``` +#### ⚠️ Problem +Similar to guards: lots of boilerplate, complex registration in the providers array. +#### ✅ Best Practice +```typescript +export const tokenInterceptor: HttpInterceptorFn = (req, next) => { + const token = inject(AuthService).token(); + return next(req.clone({ setHeaders: { Authorization: token } })); +}; +``` +#### 🚀 Solution +Use functional Interceptors (`HttpInterceptorFn`) with `provideHttpClient(withInterceptors([...]))`. + +### 🚨 19. State Mutation in Services +**Context:** Data Integrity +#### ❌ Bad Practice +```typescript +updateUser(user: User) { + this.currentUser = user; // Mutable assignment +} +``` +#### ⚠️ Problem +Object mutations complicate change tracking and can lead to unpredictable behavior in components using the `OnPush` strategy. +#### ✅ Best Practice +```typescript +currentUser = signal(null); +updateUser(user: User) { + this.currentUser.set({ ...user }); // Immutable update +} +``` +#### 🚀 Solution +Use Signals for state management. They guarantee reactivity and atomicity of updates. + +### 🚨 20. Calling functions inside `@for` tracking +**Context:** Rendering Performance +#### ❌ Bad Practice +```html +@for (item of items; track getItemId(item)) +``` +#### ⚠️ Problem +The tracking function is called for each element during every re-render. +#### ✅ Best Practice +```html +@for (item of items; track item.id) +``` +#### 🚀 Solution +Use an object property (ID or a unique key) directly. If a function is needed, it must be as simple and pure as possible. + +### 🚨 21. `host` property vs `@HostListener` +**Context:** Component Metadata +#### ❌ Bad Practice +```typescript +@HostListener('click') onClick() { ... } +@HostBinding('class.active') isActive = true; +``` +#### ⚠️ Problem +Decorators increase class size and scatter host configuration across the file. +#### ✅ Best Practice +```typescript +@Component({ + host: { + '(click)': 'onClick()', + '[class.active]': 'isActive()' + } +}) +``` +#### 🚀 Solution +Use the `host` property in component metadata. This centralizes all host element settings. + +### 🚨 22. Dynamic Components with `ComponentFactoryResolver` +**Context:** Dynamic Rendering +#### ❌ Bad Practice +```typescript +const factory = this.resolver.resolveComponentFactory(MyComponent); +this.container.createComponent(factory); +``` +#### ⚠️ Problem +`ComponentFactoryResolver` is deprecated. It is an old imperative API. +#### ✅ Best Practice +```typescript +this.container.createComponent(MyComponent); +// Or strictly in template + +``` +#### 🚀 Solution +Use `ViewContainerRef.createComponent` directly with the component class or the `ngComponentOutlet` directive. + +### 🚨 23. Shared Modules (The "Dump" Module) +**Context:** Modular Architecture +#### ❌ Bad Practice +`SharedModule` imports and exports *all* UI components, pipes, and directives. +#### ⚠️ Problem +If a component needs a single button, it is forced to pull the entire `SharedModule`. This breaks Tree Shaking and increases the initial bundle size. +#### ✅ Best Practice +Import only what is needed directly into the `imports` of the Standalone component. +#### 🚀 Solution +Abandon `SharedModule` in favor of granular imports of Standalone entities. + +### 🚨 24. Circular Dependencies in DI +**Context:** Architecture +#### ❌ Bad Practice +Service A injects Service B, which injects Service A. +#### ⚠️ Problem +Leads to runtime errors ("Cannot instantiate cyclic dependency"). Indicates poor architectural design. +#### ✅ Best Practice +Use `forwardRef()` as a crutch, but it's better to extract the shared logic into a third Service C. +#### 🚀 Solution +Refactoring: break services into smaller ones following SRP (Single Responsibility Principle). + +### 🚨 25. Logic in Pipes +**Context:** Separation of Concerns +#### ❌ Bad Practice +A Pipe performs HTTP requests or complex business logic. +#### ⚠️ Problem +Pipes are intended for data transformation in the template. Side effects in pipes violate function purity and kill CD performance. +#### ✅ Best Practice +Pipes should be "Pure" (without side effects) and fast. +#### 🚀 Solution +Extract logic into services/signals. Leave only formatting to pipes. + +### 🚨 26. `any` in Services +**Context:** TypeScript Safety +#### ❌ Bad Practice +```typescript +getData(): Observable { ... } +``` +#### ⚠️ Problem +`any` disables type checking, nullifying the benefits of TypeScript. Errors only surface at runtime. +#### ✅ Best Practice +```typescript +getData(): Observable { ... } +``` +#### 🚀 Solution +Use DTO interfaces (generate them from Swagger/OpenAPI) and Zod for API response validation. + +### 🚨 27. Multiple `async` pipes for same stream +**Context:** RxJS Subscriptions +#### ❌ Bad Practice +```html +
    {{ (user$ | async).name }}
    +``` +#### ⚠️ Problem +Each `async` pipe creates a new subscription. This can lead to duplicated HTTP requests. +#### ✅ Best Practice +```html +@if (user$ | async; as user) { +
    {{ user.name }}
    +} +``` +#### 🚀 Solution +Use aliases in the template (`as varName`) or convert the stream to a signal (`toSignal`). + +### 🚨 28. ProvidedIn 'any' +**Context:** DI Scopes +#### ❌ Bad Practice +```typescript +@Injectable({ providedIn: 'any' }) +``` +#### ⚠️ Problem +Creates a new service instance for each lazy-loaded module. This is often unexpected behavior, leading to state desynchronization (different singleton instances). +#### ✅ Best Practice +`providedIn: 'root'` or providing at the level of a specific component (`providers: []`). +#### 🚀 Solution +Avoid `any`. Explicitly control the scope: either global (`root`) or local. + +### 🚨 29. Imperative Routing +**Context:** Navigation +#### ❌ Bad Practice +```typescript +this.router.navigateByUrl('/users/' + id); +``` +#### ⚠️ Problem +Hardcoding route strings makes route refactoring a pain. +#### ✅ Best Practice +```typescript +this.router.navigate(['users', id]); +``` +#### 🚀 Solution +Use an array of segments. It is safer (automatic encoding of URL parameters) and cleaner. + +### 🚨 30. Ignoring `OnPush` Strategy +**Context:** Change Detection Strategy +#### ❌ Bad Practice +Default components (`ChangeDetectionStrategy.Default`). +#### ⚠️ Problem +Angular checks this component on *every* app event, even if the component data hasn't changed. +#### ✅ Best Practice +```typescript +changeDetection: ChangeDetectionStrategy.OnPush +``` +#### 🚀 Solution +Always set `OnPush`. With signals, this becomes the de facto standard, as updates occur precisely. + +--- + +--- +[⬆️ Back to Top](#) + +## III. Advanced Performance (31-45) + +### 🚨 31. Eager Loading of Heavy Components +**Context:** Bundle Size +#### ❌ Bad Practice +```html + +``` +#### ⚠️ Problem +A charting library (e.g., ECharts) loads immediately, blocking TTI (Time to Interactive), even if the chart is below the "fold". +#### ✅ Best Practice +```html +@defer (on viewport) { + +} @placeholder { +
    Loading chart...
    +} +``` +#### 🚀 Solution +Use `@defer`. This defers component code loading until a trigger occurs (viewport, interaction, timer). + +### 🚨 32. Heavy Computation in Main Thread +**Context:** Event Loop Blocking +#### ❌ Bad Practice +Sorting an array of 100k elements directly in the component. +#### ⚠️ Problem +Freezes the UI. +#### ✅ Best Practice +Offload computations to a Web Worker. +#### 🚀 Solution +Use Angular Web Workers. In v20, this is easily configured via the CLI. + +### 🚨 33. Memory Leaks in `effect()` +**Context:** Signal Effects +#### ❌ Bad Practice +```typescript +effect(() => { + const timer = setInterval(() => ..., 1000); + // No cleanup +}); +``` +#### ⚠️ Problem +Effects restart when dependencies change. If you don't clean up timers/subscriptions inside an effect, they accumulate. +#### ✅ Best Practice +```typescript +effect((onCleanup) => { + const timer = setInterval(() => ..., 1000); + onCleanup(() => clearInterval(timer)); +}); +``` +#### 🚀 Solution +Always use the `onCleanup` callback to release resources. + +### 🚨 34. Excessive Change Detection with `NgZone.run()` +**Context:** Zone Integration +#### ❌ Bad Practice +Wrapping third-party libraries in `ngZone.run()` unnecessarily. +#### ⚠️ Problem +Forces redundant checks of the entire component tree. +#### ✅ Best Practice +```typescript +ngZone.runOutsideAngular(() => { + // Heavy chart rendering or canvas animation +}); +``` +#### 🚀 Solution +Run frequent events (scroll, mousemove, animationFrame) *outside* the Angular zone. Update signals only when UI updates are required. + +### 🚨 35. Signals equality check default +**Context:** Signal Performance +#### ❌ Bad Practice +```typescript +data = signal({ id: 1 }, { equal: undefined }); // Default checks reference +``` +#### ⚠️ Problem +If you create a new object with the same data `{ id: 1 }`, the signal triggers an update, even though the data hasn't fundamentally changed. +#### ✅ Best Practice +```typescript +import { isEqual } from 'lodash-es'; +data = signal(obj, { equal: isEqual }); +``` +#### 🚀 Solution +Use a custom comparison function for complex objects to avoid redundant re-renders. + +### 🚨 36. Lacking `trackBy` in iterables +**Context:** Re-rendering Lists +#### ❌ Bad Practice +```html +
  • {{ item }}
  • +``` +#### ⚠️ Problem +Without tracking, any array change leads to the recreation of all DOM nodes in the list. $O(n)$ DOM operations. +#### ✅ Best Practice +```html +@for (item of items; track item.id) +``` +#### 🚀 Solution +Always use a unique key in `track`. This allows Angular to move DOM nodes instead of recreating them. + +### 🚨 37. Recursive Template without Caching +**Context:** Tree Rendering +#### ❌ Bad Practice +Recursive component call without `OnPush` and memoization. +#### ⚠️ Problem +Exponential growth in change detection checks. +#### ✅ Best Practice +Using the `Memoization` pattern or `computed()` to prepare the tree data structure. + +### 🚨 38. Global Styles Leakage +**Context:** CSS Encapsulation +#### ❌ Bad Practice +```css +/* global.css */ +button { padding: 10px; } +``` +#### ⚠️ Problem +Global styles unpredictably affect components. +#### ✅ Best Practice +Use `ViewEncapsulation.Emulated` (default) and specific selectors. +#### 🚀 Solution +Keep styles locally within components. + +### 🚨 39. Large Component Bundle +**Context:** Split Chunks +#### ❌ Bad Practice +A single huge component of 3000 lines. +#### ⚠️ Problem +Poor readability, rendering lazy loading of UI parts impossible. +#### ✅ Best Practice +Decompose into "dumb" (UI) and "smart" components. +#### 🚀 Solution +Break down the UI into small, reusable blocks. + +### 🚨 40. Image Optimization Ignorance +**Context:** Core Web Vitals (LCP) +#### ❌ Bad Practice +```html + +``` +#### ⚠️ Problem +The browser loads the full image, shifting the layout (CLS). +#### ✅ Best Practice +```html + +``` +#### 🚀 Solution +Use the `NgOptimizedImage` directive. It automatically handles lazy loading, preconnect, and srcset. + +### 🚨 41. Hydration Mismatch +**Context:** SSR / SSG +#### ❌ Bad Practice +Rendering `Date.now()` or random numbers (`Math.random()`) directly in the template. +#### ⚠️ Problem +The server generates one number, the client another. This causes "flickering" and a hydration error; Angular discards the server DOM and renders from scratch. +#### ✅ Best Practice +Use stable data or defer random generation until `afterNextRender`. +#### 🚀 Solution +Pay attention to template determinism with SSR. + +### 🚨 42. Synchronous `inject()` inside loops +**Context:** DI Performance +#### ❌ Bad Practice +Calling `inject()` inside a function that loops. +#### ⚠️ Problem +Although `inject` is fast, in hot paths these are unnecessary DI tree lookups. +#### ✅ Best Practice +Inject dependency once at the class/file constant level. + +### 🚨 43. Unused Signal Dependencies +**Context:** Signal Graph +#### ❌ Bad Practice +Reading a signal inside `computed` whose value doesn't affect the result (an unexecuted logical branch). +#### ⚠️ Problem +Angular dynamically builds the dependency graph. If you accidentally read a signal, it becomes a dependency. +#### ✅ Best Practice +Use `untracked()` to read signals whose changes should not trigger a recalculation. + +### 🚨 44. Excessive Wrappers (`div` soup) +**Context:** DOM Size +#### ❌ Bad Practice +```html +
    +``` +#### ⚠️ Problem +Increases DOM tree depth, slowing down Style Recalculation and Layout. +#### ✅ Best Practice +Use `` to group elements without creating extra DOM nodes. + +### 🚨 45. Neglecting `runOutsideAngular` for Events +**Context:** High-frequency events +#### ❌ Bad Practice +`@HostListener('window:scroll')` +#### ⚠️ Problem +Every scroll event triggers Change Detection. +#### ✅ Best Practice +Subscribe manually in `runOutsideAngular` and update the signal only when necessary. + +--- + +--- +[⬆️ Back to Top](#) + +## IV. Data & Forms (46-55) + +### 🚨 46. Template-Driven Forms without Types +**Context:** Form Safety +#### ❌ Bad Practice +`[(ngModel)]` without strict model typing. +#### ⚠️ Problem +Risk of assigning a string to a numeric field. +#### ✅ Best Practice +Use Reactive Forms with `FormControl` typing or new Signal-based Forms (when out of developer preview). + +### 🚨 47. Untyped `FormGroup` +**Context:** Reactive Forms +#### ❌ Bad Practice +```typescript +const form = new FormGroup({ ... }); // Untyped +``` +#### ⚠️ Problem +`form.value` returns `any`. +#### ✅ Best Practice +```typescript +const form = new FormGroup({ + email: new FormControl('', { nonNullable: true }), + ... +}); +``` +#### 🚀 Solution +Always type forms. Use `nonNullable: true` to avoid `string | undefined` hell. + +### 🚨 48. Subscribe inside Subscribe +**Context:** RxJS Patterns +#### ❌ Bad Practice +```typescript +this.route.params.subscribe(params => { + this.api.getUser(params.id).subscribe(user => ...); +}); +``` +#### ⚠️ Problem +Classic Race Condition. If parameters change rapidly, response order is not guaranteed. +#### ✅ Best Practice +```typescript +this.route.params.pipe( + switchMap(params => this.api.getUser(params.id)) +).subscribe(); +``` +#### 🚀 Solution +Use Flattening Operators (`switchMap`, `concatMap`, `mergeMap`). + +### 🚨 49. Ignoring `AbortSignal` in HTTP +**Context:** Network Efficiency +#### ❌ Bad Practice +Ignoring request cancellation when navigating away from the page. +#### ⚠️ Problem +Requests continue hanging, consuming traffic. +#### ✅ Best Practice +HttpClient automatically supports cancellation upon unsubscription. With signals: ensure `rxResource` or the effect correctly cancels the request. + +### 🚨 50. Mutating Inputs directly +**Context:** Unidirectional Data Flow +#### ❌ Bad Practice +```typescript +this.inputData.push(newItem); +``` +#### ⚠️ Problem +The parent component remains unaware of the change. Violates the One-Way Data Flow principle. +#### ✅ Best Practice +Emit event (`output`) upwards; the parent changes the data and passes the new object downwards. + +### 🚨 51. `ngModel` inside Reactive Form +**Context:** Form Mixing +#### ❌ Bad Practice +Using `formControlName` and `[(ngModel)]` on the same input. +#### ⚠️ Problem +Deprecated behavior. Causes form and model synchronization conflicts. +#### ✅ Best Practice +Use only one approach: either Reactive or Template-driven. + +### 🚨 52. Complex Validators in Template +**Context:** Form Logic +#### ❌ Bad Practice +Validation via HTML attributes for complex logic. +#### ⚠️ Problem +Hard to test, no reusability. +#### ✅ Best Practice +Custom Validator Functions or Async Validators in the component class. + +### 🚨 53. Forgetting `updateOn: 'blur'` +**Context:** Performance +#### ❌ Bad Practice +Validating a complex field on every keystroke (`change`). +#### ⚠️ Problem +Slows down user input. +#### ✅ Best Practice +```typescript +new FormControl('', { updateOn: 'blur' }); +``` +#### 🚀 Solution +Trigger validation/update only when the user has finished typing. + +### 🚨 54. Not handling API Errors +**Context:** UX +#### ❌ Bad Practice +`.subscribe(data => ...)` without an error callback. +#### ⚠️ Problem +On a 500 error, the application "hangs" in a loading state. +#### ✅ Best Practice +Global Error Handler or `catchError` in the pipe returning a safe value. + +### 🚨 55. Hardcoded API URLs +**Context:** Maintainability +#### ❌ Bad Practice +`http.get('https://api.com/users')` +#### ⚠️ Problem +Inability to switch environments (dev/prod). +#### ✅ Best Practice +Using InjectionToken `API_URL` and environment configuration. + +--- + +--- +[⬆️ Back to Top](#) + +## V. Expert/Niche (56-60) + +### 🚨 56. `untracked()` usage +**Context:** Fine-grained Reactivity +#### ❌ Bad Practice +Accidentally creating a cyclic dependency in `computed`. +#### ⚠️ Problem +`Error: Detected cycle in computations`. +#### ✅ Best Practice +```typescript +computed(() => { + const user = this.user(); + untracked(() => this.logger.log(user)); // Logging doesn't create dependency + return user.name; +}); +``` +#### 🚀 Solution +Use `untracked()` for side effects or reads that shouldn't affect recalculation. + +### 🚨 57. V8 Hidden Classes Optimization +**Context:** Micro-optimization +#### ❌ Bad Practice +```typescript +user = signal({}); +// later +user.set({ name: 'A', age: 10 }); // Shape change +``` +#### ⚠️ Problem +Initializing with an empty object and later adding fields changes the object "shape" (Hidden Class), breaking V8 JIT compiler optimization. +#### ✅ Best Practice +```typescript +interface User { name: string | null; age: number | null; } +user = signal({ name: null, age: null }); +``` +#### 🚀 Solution +Always initialize signals with the full object shape (even with null) to preserve property access monomorphism. + +### 🚨 58. Signal Glitch Freedom abuse +**Context:** Reactivity Theory +#### ❌ Bad Practice +Relying on `effect` to fire synchronously. +#### ⚠️ Problem +Signals guarantee "Glitch Freedom" (absence of intermediate inconsistent states), but effects are asynchronous (microtask timing). +#### ✅ Best Practice +Do not use effects to synchronize local state. Use `computed`. + +### 🚨 59. Memory leaks in `root` Effects +**Context:** Application Lifecycle +#### ❌ Bad Practice +Creating an effect in a service without `manualCleanup`. +#### ⚠️ Problem +Effects in `root` services live forever. If they subscribe to something global, it can leak. +#### ✅ Best Practice +Usually fine, but if the service is destroyed (rare lazy loading case), the effect must be cleaned up with `effectRef.destroy()`. + +### 🚨 60. `runInInjectionContext` +**Context:** Advanced DI +#### ❌ Bad Practice +Passing an `Injector` instance manually into functions. +#### ⚠️ Problem +Bulky code. +#### ✅ Best Practice +```typescript +runInInjectionContext(this.injector, () => { + // can use inject() here dynamically + const service = inject(MyService); +}); +``` +#### 🚀 Solution +Use this helper to execute functions requiring a DI context outside the constructor/initialization. + +--- +[⬆️ Back to Top](#) +======= ## 📚 Specialized Topics @@ -299,3 +946,4 @@ For further reading, please refer to the following specialized guides: - [🚀 Advanced Performance](./advanced-performance.md) - [📝 Data & Forms](./data-forms.md) - [🧠 Expert/Niche Topics](./expert-niche.md) +>>>>>>> main diff --git a/frontend/javascript/readme.md b/frontend/javascript/readme.md index 802f4be..74bf3b4 100644 --- a/frontend/javascript/readme.md +++ b/frontend/javascript/readme.md @@ -13,11 +13,14 @@ last_updated: 2026-03-22 ![JavaScript Logo](https://img.icons8.com/?size=100&id=108784&format=png&color=000000) +--- +[⬆️ Back to Top](#) + ## I. Fundamentals (The Basics) -## 1. `var` vs `const/let` +### 🚨 1. `var` vs `const/let` **Context:** Scoping and hoisting mechanisms in modern JavaScript. `var` is function-scoped and hoisted, leading to unpredictable behavior and accidental global leakage. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript var price = 100; if (true) { @@ -25,9 +28,9 @@ if (true) { } console.log(price); // 200 ``` -### ⚠️ Problem +#### ⚠️ Problem `var` does not respect block scope. Its hoisting behavior allows variables to be accessed before declaration (as `undefined`), which bypasses the Temporal Dead Zone (TDZ) safety mechanism, increasing cognitive load and bug density. -### ✅ Best Practice +#### ✅ Best Practice ```javascript const price = 100; if (true) { @@ -35,39 +38,39 @@ if (true) { } console.log(price); // 100 ``` -### 🚀 Solution +#### 🚀 Solution Use `const` by default to ensure immutability of the reference. Use `let` only when reassigning a variable is strictly necessary. This enforces block-level scoping and prevents accidental overrides. -## 2. Loose equality `==` +### 🚨 2. Loose equality `==` **Context:** JavaScript's type coercion rules are complex and often counter-intuitive. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript if (userCount == '0') { // Executes if userCount is 0 (number) or '0' (string) } ``` -### ⚠️ Problem +#### ⚠️ Problem The Abstract Equality Comparison Algorithm (`==`) performs implicit type conversion. This leads to edge cases like `[] == ![]` being `true` or `0 == ''` being `true`, which can cause silent logic failures. -### ✅ Best Practice +#### ✅ Best Practice ```javascript if (userCount === 0) { // Strict comparison } ``` -### 🚀 Solution +#### 🚀 Solution Always use strict equality `===` and inequality `!==`. This forces the developer to handle type conversions explicitly, making the code's intent clear and predictable. -## 3. Global Scope Pollution +### 🚨 3. Global Scope Pollution **Context:** The global namespace is shared. Overwriting global properties can break third-party libraries or browser APIs. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript // In a script file const config = { api: '/v1' }; function init() { /* ... */ } ``` -### ⚠️ Problem +#### ⚠️ Problem Variables declared in the top-level scope of a non-module script are attached to `window` (in browsers) or `global` (in Node). This increases the risk of name collisions and memory leaks. -### ✅ Best Practice +#### ✅ Best Practice ```javascript // use modules export const config = { api: '/v1' }; @@ -77,37 +80,37 @@ export const config = { api: '/v1' }; const config = { api: '/v1' }; })(); ``` -### 🚀 Solution +#### 🚀 Solution Use ES Modules (`import/export`) to encapsulate code. Modules have their own scope and do not leak to the global object. -## 4. String concatenation vs Template Literals +### 🚨 4. String concatenation vs Template Literals **Context:** Readability and handling of multi-line strings/expressions. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript const greeting = 'Hello, ' + user.firstName + ' ' + user.lastName + '! ' + 'Welcome to ' + siteName + '.'; ``` -### ⚠️ Problem +#### ⚠️ Problem Concatenation with `+` is error-prone, hard to read, and difficult to maintain for multi-line strings. It often leads to missing spaces and poor visual structure. -### ✅ Best Practice +#### ✅ Best Practice ```javascript const greeting = `Hello, ${user.firstName} ${user.lastName}! Welcome to ${siteName}.`; ``` -### 🚀 Solution +#### 🚀 Solution Use Template Literals (backticks). They allow for embedded expressions, multi-line strings, and superior readability. -## 5. Magic Numbers +### 🚨 5. Magic Numbers **Context:** Numbers with no context make the codebase hard to maintain. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript if (user.age >= 18) { grantAccess(); } ``` -### ⚠️ Problem +#### ⚠️ Problem "18" is a magic number. If the legal age changes, you must find and replace every instance, risking errors if the same number is used for different contexts elsewhere. -### ✅ Best Practice +#### ✅ Best Practice ```javascript const LEGAL_AGE = 18; @@ -115,53 +118,53 @@ if (user.age >= LEGAL_AGE) { grantAccess(); } ``` -### 🚀 Solution +#### 🚀 Solution Extract magic numbers into named constants. This provides semantic meaning and a single source of truth for configuration. -## 6. Boolean comparisons `(if x === true)` +### 🚨 6. Boolean comparisons `(if x === true)` **Context:** Redundancy in conditional logic. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript if (isValid === true) { /* ... */ } ``` -### ⚠️ Problem +#### ⚠️ Problem Comparing a boolean to `true` or `false` is redundant. It adds visual noise without increasing safety. -### ✅ Best Practice +#### ✅ Best Practice ```javascript if (isValid) { /* ... */ } if (!isPending) { /* ... */ } ``` -### 🚀 Solution +#### 🚀 Solution Leverage JavaScript's truthiness/falsiness or direct boolean evaluation. It makes the code more concise and idiomatic. -## 7. Array/Object literal vs `new` constructor +### 🚨 7. Array/Object literal vs `new` constructor **Context:** Object and Array instantiation. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript const list = new Array(1, 2, 3); const map = new Object(); ``` -### ⚠️ Problem +#### ⚠️ Problem The `Array` constructor is inconsistent: `new Array(3)` creates an empty array of length 3, while `new Array(3, 4)` creates `[3, 4]`. Literals are faster and more readable. -### ✅ Best Practice +#### ✅ Best Practice ```javascript const list = [1, 2, 3]; const map = {}; ``` -### 🚀 Solution +#### 🚀 Solution Use literals `[]` and `{}`. They are visually cleaner and perform slightly better as they don't involve a function call. -## 8. Function length/complexity +### 🚨 8. Function length/complexity **Context:** The Single Responsibility Principle (SRP). -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript function processOrder(order) { // 100 lines of validation, DB saving, email sending... } ``` -### ⚠️ Problem +#### ⚠️ Problem Large functions are hard to test, debug, and reuse. High cyclomatic complexity makes it difficult for the JIT compiler to optimize the function. -### ✅ Best Practice +#### ✅ Best Practice ```javascript function validateOrder(order) { /* ... */ } function saveToDatabase(order) { /* ... */ } @@ -173,12 +176,12 @@ function processOrder(order) { notifyUser(order); } ``` -### 🚀 Solution +#### 🚀 Solution Break functions into smaller, pure components. Aim for functions under 20 lines that do exactly one thing. -## 9. Deeply nested `if/else` (Arrow code) +### 🚨 9. Deeply nested `if/else` (Arrow code) **Context:** Cognitive load and code readability. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript function getData(user) { if (user) { @@ -190,9 +193,9 @@ function getData(user) { } } ``` -### ⚠️ Problem +#### ⚠️ Problem "Arrow code" (code that expands horizontally) is hard to follow. It forces the reader to keep track of multiple nesting levels in their mental stack. -### ✅ Best Practice +#### ✅ Best Practice ```javascript function getData(user) { if (!user || !user.isActive || !user.hasPermission) { @@ -201,28 +204,615 @@ function getData(user) { return fetchData(); } ``` -### 🚀 Solution +#### 🚀 Solution Use "Guard Clauses" to return early. This flattens the structure and handles edge cases first, leaving the happy path at the lowest nesting level. -## 10. Improper naming (Single letters) +### 🚨 10. Improper naming (Single letters) **Context:** Self-documenting code. -### ❌ Bad Practice +#### ❌ Bad Practice ```javascript const d = new Date(); const u = users.map(i => i.n); ``` -### ⚠️ Problem +#### ⚠️ Problem Single-letter variables (except for standard loop indices like `i` or `j`) provide no context. They make the code unsearchable and confusing for other developers. -### ✅ Best Practice +#### ✅ Best Practice ```javascript const today = new Date(); const userNames = users.map(user => user.name); ``` -### 🚀 Solution +#### 🚀 Solution Use descriptive, camelCase names that convey the intent and data type of the variable. --- +<<<<<<< feat/autonomous-vibe-coding-docs-10177351143416239543 +--- +[⬆️ Back to Top](#) + +## II. Modern Syntax & FP (ES6-ES2024) + +### 🚨 11. Manual object property assignment vs Shorthand +**Context:** Reducing boilerplate in object creation. +#### ❌ Bad Practice +```javascript +const name = 'Alice'; +const user = { + name: name, + age: age +}; +``` +#### ⚠️ Problem +Redundant repetition of keys and values increases file size and makes the code noisier. +#### ✅ Best Practice +```javascript +const name = 'Alice'; +const user = { name, age }; +``` +#### 🚀 Solution +Use Property Shorthand. When the key and variable name match, omit the value. + +### 🚨 12. Using `arguments` vs Rest parameters +**Context:** Handling variable numbers of arguments. +#### ❌ Bad Practice +```javascript +function sum() { + const args = Array.prototype.slice.call(arguments); + return args.reduce((a, b) => a + b); +} +``` +#### ⚠️ Problem +The `arguments` object is not a real array (it lacks methods like `map` or `reduce`). It is also incompatible with arrow functions and optimization in some V8 versions. +#### ✅ Best Practice +```javascript +const sum = (...args) => args.reduce((a, b) => a + b); +``` +#### 🚀 Solution +Use Rest Parameters (`...args`). They create a real array and are more explicit about the function's intent. + +### 🚨 13. Manual array copying vs Spread +**Context:** Immutability and array manipulation. +#### ❌ Bad Practice +```javascript +const original = [1, 2, 3]; +const copy = []; +for (let i = 0; i < original.length; i++) { + copy.push(original[i]); +} +``` +#### ⚠️ Problem +Manual loops for copying are verbose and imperative. They increase the surface area for bugs (off-by-one errors). +#### ✅ Best Practice +```javascript +const original = [1, 2, 3]; +const copy = [...original]; +``` +#### 🚀 Solution +Use the Spread Operator (`...`). It is concise, declarative, and highly optimized by modern engines. + +### 🚨 14. Nested Destructuring +**Context:** Extracting data from complex objects. +#### ❌ Bad Practice +```javascript +const city = user.location.address.city; +const zip = user.location.address.zip; +``` +#### ⚠️ Problem +Repetitive property access is verbose and risks "cannot read property of undefined" errors if any parent object is missing. +#### ✅ Best Practice +```javascript +const { location: { address: { city, zip } } } = user; +``` +#### 🚀 Solution +Use nested destructuring to extract deeply nested values in a single statement. (Note: Combine with optional chaining if path existence isn't guaranteed). + +### 🚨 15. Default Parameters +**Context:** Handling missing arguments. +#### ❌ Bad Practice +```javascript +function setRole(role) { + role = role || 'guest'; + // ... +} +``` +#### ⚠️ Problem +Using `||` for defaults is dangerous if the argument is a "falsy" but valid value (like `0`, `false`, or `''`). +#### ✅ Best Practice +```javascript +function setRole(role = 'guest') { + // ... +} +``` +#### 🚀 Solution +Use ES6 Default Parameters. They only apply if the argument is `undefined`. + +### 🚨 16. `forEach` for data transformation vs `map/filter` +**Context:** Declarative vs Imperative programming. +#### ❌ Bad Practice +```javascript +const double = []; +numbers.forEach(n => { + double.push(n * 2); +}); +``` +#### ⚠️ Problem +`forEach` relies on side effects (mutating an outer array). It is less expressive and harder to chain than functional alternatives. +#### ✅ Best Practice +```javascript +const double = numbers.map(n => n * 2); +``` +#### 🚀 Solution +Use `map`, `filter`, and `reduce` for data transformations. They return new arrays and promote immutability. + +### 🚨 17. Object mutation vs Immutability +**Context:** State management and predictability. +#### ❌ Bad Practice +```javascript +function updateAge(user) { + user.age = 30; // Mutates original object + return user; +} +``` +#### ⚠️ Problem +Mutating objects passed by reference can lead to side effects in other parts of the application that share the same reference, making debugging a nightmare. +#### ✅ Best Practice +```javascript +const updateAge = (user) => ({ ...user, age: 30 }); +``` +#### 🚀 Solution +Treat objects as immutable. Use the spread operator to create copies with updated properties. + +### 🚨 18. Switch statements vs Object Literals +**Context:** Simplifying conditional branching. +#### ❌ Bad Practice +```javascript +switch (action) { + case 'CREATE': return doCreate(); + case 'UPDATE': return doUpdate(); + default: return doNothing(); +} +``` +#### ⚠️ Problem +`switch` statements are verbose, require `break` to prevent fallthrough bugs, and have a non-standard block scope. +#### ✅ Best Practice +```javascript +const actions = { + CREATE: doCreate, + UPDATE: doUpdate +}; +return (actions[action] || doNothing)(); +``` +#### 🚀 Solution +Use an Object Literal (or Map) as a lookup table. It is cleaner, faster, and more extensible. + +### 🚨 19. Not using Optional Chaining `?.` +**Context:** Safe property access in nested objects. +#### ❌ Bad Practice +```javascript +const street = user && user.address && user.address.street; +``` +#### ⚠️ Problem +The "logical AND" chain is verbose and repetitive. It quickly becomes unreadable with deeper nesting. +#### ✅ Best Practice +```javascript +const street = user?.address?.street; +``` +#### 🚀 Solution +Use Optional Chaining (`?.`). It short-circuits to `undefined` if any part of the chain is nullish. + +### 🚨 20. Not using Nullish Coalescing `??` +**Context:** Providing fallback values safely. +#### ❌ Bad Practice +```javascript +const timeout = config.timeout || 5000; +``` +#### ⚠️ Problem +If `config.timeout` is `0`, the code will incorrectly fall back to `5000` because `0` is falsy. +#### ✅ Best Practice +```javascript +const timeout = config.timeout ?? 5000; +``` +#### 🚀 Solution +Use Nullish Coalescing (`??`). It only falls back if the value is `null` or `undefined`, allowing `0`, `false`, and `''` to be valid. + +--- + +--- +[⬆️ Back to Top](#) + +## III. Asynchronous & Logic + +### 🚨 21. Callback Hell vs Promises +**Context:** Managing asynchronous execution flow. +#### ❌ Bad Practice +```javascript +getData(url, (err, res) => { + getDetails(res.id, (err, details) => { + saveData(details, (err, ok) => { + // Callback Hell + }); + }); +}); +``` +#### ⚠️ Problem +Deeply nested callbacks (the "Pyramid of Doom") make error handling extremely difficult and code unreadable. +#### ✅ Best Practice +```javascript +fetchData(url) + .then(res => fetchDetails(res.id)) + .then(details => saveData(details)) + .catch(err => handleError(err)); +``` +#### 🚀 Solution +Use Promises to flatten the structure and centralize error handling with `.catch()`. + +### 🚨 22. Promise.then() nesting vs Async/Await +**Context:** Modern syntax for asynchronous code. +#### ❌ Bad Practice +```javascript +function load() { + return api.get().then(res => { + return api.process(res).then(processed => { + return processed; + }); + }); +} +``` +#### ⚠️ Problem +Even with Promises, `.then()` nesting can occur. It still feels like "callback style" logic. +#### ✅ Best Practice +```javascript +async function load() { + const res = await api.get(); + const processed = await api.process(res); + return processed; +} +``` +#### 🚀 Solution +Use `async/await`. It allows asynchronous code to be written and read like synchronous code, improving maintainability. + +### 🚨 23. Sequential `await` in loops vs `Promise.all` +**Context:** Parallelizing independent asynchronous operations. +#### ❌ Bad Practice +```javascript +for (const id of ids) { + await fetchItem(id); // Pauses loop for each request +} +``` +#### ⚠️ Problem +Sequential `await` in a loop causes a "waterfall" effect, where each request waits for the previous one to finish, significantly increasing total execution time. +#### ✅ Best Practice +```javascript +const promises = ids.map(id => fetchItem(id)); +await Promise.all(promises); +``` +#### 🚀 Solution +Use `Promise.all` to execute independent promises in parallel. This utilizes the full network/IO bandwidth. + +### 🚨 24. Missing `try/catch` in async +**Context:** Handling failures in async functions. +#### ❌ Bad Practice +```javascript +async function getData() { + const data = await fetch(url); // If this fails, the process might crash + return data; +} +``` +#### ⚠️ Problem +Unhandled exceptions in `async` functions result in unhandled promise rejections, which can lead to silent failures or process termination in Node.js. +#### ✅ Best Practice +```javascript +async function getData() { + try { + const data = await fetch(url); + return data; + } catch (error) { + logError(error); + } +} +``` +#### 🚀 Solution +Wrap `await` calls in `try/catch` blocks or use a higher-order function to catch errors. + +### 🚨 25. Floating point math errors (`0.1 + 0.2`) +**Context:** Precision issues in IEEE 754 arithmetic. +#### ❌ Bad Practice +```javascript +if (0.1 + 0.2 === 0.3) { /* False! */ } +``` +#### ⚠️ Problem +$\text{0.1} + \text{0.2} = \text{0.30000000000000004}$ due to binary representation limits. This leads to critical bugs in financial or scientific applications. +#### ✅ Best Practice +```javascript +const EPSILON = Number.EPSILON; +const areEqual = (a, b) => Math.abs(a - b) < EPSILON; + +// Or for money: +const totalCents = (10 + 20); // 30 cents +``` +#### 🚀 Solution +Use `Number.EPSILON` for comparisons or represent decimals as integers (e.g., cents instead of dollars) to avoid floating point drift. + +### 🚨 26. Multiple Boolean flags vs State Machine +**Context:** Managing complex component logic. +#### ❌ Bad Practice +```javascript +const [isLoading, setIsLoading] = useState(false); +const [isError, setIsError] = useState(false); +const [isSuccess, setIsSuccess] = useState(false); +``` +#### ⚠️ Problem +Multiple flags allow for "impossible states" (e.g., `isLoading` and `isError` both being `true`). This makes logic branches exponentially complex. +#### ✅ Best Practice +```javascript +const [status, setStatus] = useState('IDLE'); // IDLE, LOADING, ERROR, SUCCESS +``` +#### 🚀 Solution +Use a single state variable or a state machine. This ensures only one state is active at a time and simplifies transitions. + +### 🚨 27. Sync logic in Event Loop +**Context:** Keeping the UI responsive. +#### ❌ Bad Practice +```javascript +function processLargeArray(arr) { + // Blocks the main thread for 2 seconds + arr.sort().forEach(item => complexCalc(item)); +} +``` +#### ⚠️ Problem +JavaScript is single-threaded. Heavy synchronous computation blocks the Event Loop, causing the UI to freeze and preventing user interaction. +#### ✅ Best Practice +```javascript +// Use Web Workers or break into chunks +function processInChunks(arr) { + if (arr.length === 0) return; + const chunk = arr.splice(0, 100); + process(chunk); + setTimeout(() => processInChunks(arr), 0); +} +``` +#### 🚀 Solution +Offload heavy tasks to Web Workers or use `requestIdleCallback`/`setTimeout` to break long tasks into smaller chunks, allowing the browser to render between frames. + +### 🚨 28. Overusing `classes` where functions suffice +**Context:** Paradigm choice (OOP vs FP). +#### ❌ Bad Practice +```javascript +class Calculator { + add(a, b) { return a + b; } +} +const calc = new Calculator(); +``` +#### ⚠️ Problem +Classes introduce unnecessary overhead (prototype chain, `this` binding issues) and make tree-shaking harder for bundlers. +#### ✅ Best Practice +```javascript +export const add = (a, b) => a + b; +``` +#### 🚀 Solution +Use simple functions and modules for logic. Use classes only when you need to manage complex stateful instances with shared behavior. + +### 🚨 29. Hard-coded Error messages vs Error Classes +**Context:** Robust error handling and debugging. +#### ❌ Bad Practice +```javascript +throw new Error('User not found'); +``` +#### ⚠️ Problem +Parsing error messages in `catch` blocks is brittle. If the string changes, the error handling logic breaks. +#### ✅ Best Practice +```javascript +class UserNotFoundError extends Error { + constructor(userId) { + super(`User ${userId} not found`); + this.name = 'UserNotFoundError'; + this.code = 404; + } +} +``` +#### 🚀 Solution +Extend the `Error` class to create custom error types. Use `instanceof` check in catch blocks to handle specific errors differently. + +### 🚨 30. Unhandled Rejections +**Context:** Reliability of asynchronous flows. +#### ❌ Bad Practice +```javascript +// No .catch() or try/catch +fetch('/api/data'); +``` +#### ⚠️ Problem +Unhandled rejections create silent failures. In production environments, this can lead to memory leaks as the promise state stays pending or rejected without being cleared. +#### ✅ Best Practice +```javascript +window.addEventListener('unhandledrejection', event => { + reportToSentry(event.reason); +}); +``` +#### 🚀 Solution +Always handle promise rejections. Implement a global unhandled rejection listener as a safety net for monitoring. + +--- + +--- +[⬆️ Back to Top](#) + +## IV. Professional & Niche (Senior Level) + +### 🚨 31. Memory Leaks: Unremoved Event Listeners +**Context:** Long-lived applications (SPAs). +#### ❌ Bad Practice +```javascript +window.addEventListener('resize', () => this.handleResize()); +// Component unmounts, but listener remains +``` +#### ⚠️ Problem +The event listener keeps a reference to the component/context, preventing garbage collection even after the component is destroyed. +#### ✅ Best Practice +```javascript +const handler = () => this.handleResize(); +window.addEventListener('resize', handler); +// Cleanup: +window.removeEventListener('resize', handler); +``` +#### 🚀 Solution +Always remove event listeners in cleanup phases (e.g., `componentWillUnmount` or `useEffect` return). Use `AbortController` for an even more modern approach to listener cleanup. + +### 🚨 32. Memory Leaks: Forgotten Intervals/Timeouts +**Context:** Managing temporal background tasks. +#### ❌ Bad Practice +```javascript +setInterval(() => { + fetchStatus(); +}, 1000); +``` +#### ⚠️ Problem +Intervals continue to run indefinitely until the page is closed, even if the data they process is no longer needed, consuming CPU and memory. +#### ✅ Best Practice +```javascript +const intervalId = setInterval(fetchStatus, 1000); +// Later: +clearInterval(intervalId); +``` +#### 🚀 Solution +Store the ID returned by `setTimeout` or `setInterval` and clear it when the task is no longer relevant. + +### 🚨 33. Closures inside loops (Memory/Scope issues) +**Context:** Understanding the Event Loop and closure capture. +#### ❌ Bad Practice +```javascript +for (var i = 0; i < 5; i++) { + setTimeout(() => console.log(i), 100); // Prints '5' five times +} +``` +#### ⚠️ Problem +`var` is function-scoped. By the time the `setTimeout` executes, the loop has finished and `i` is 5. Each closure shares the same reference to `i`. +#### ✅ Best Practice +```javascript +for (let i = 0; i < 5; i++) { + setTimeout(() => console.log(i), 100); // Prints 0, 1, 2, 3, 4 +} +``` +#### 🚀 Solution +Use `let` in loop headers. It creates a new binding for each iteration, ensuring the closure captures the value of `i` at that specific moment. + +### 🚨 34. Throwing Strings instead of `new Error()` +**Context:** Ensuring useful stack traces. +#### ❌ Bad Practice +```javascript +throw 'Something went wrong'; +``` +#### ⚠️ Problem +Throwing a string provides no stack trace. It makes it nearly impossible to determine where the error originated in a complex call stack. +#### ✅ Best Practice +```javascript +throw new Error('Something went wrong'); +``` +#### 🚀 Solution +Always throw an instance of `Error` (or a subclass). This captures the `stack` property, which is vital for debugging. + +### 🚨 35. Modifying Built-in Prototypes +**Context:** Ecosystem compatibility and stability. +#### ❌ Bad Practice +```javascript +Array.prototype.last = function() { + return this[this.length - 1]; +}; +``` +#### ⚠️ Problem +"Monkey patching" built-ins can lead to collisions if a future ECMAScript version implements a method with the same name but different behavior. It also breaks for-in loops if not handled carefully. +#### ✅ Best Practice +```javascript +const last = (arr) => arr[arr.length - 1]; +``` +#### 🚀 Solution +Use utility functions or wrapper classes instead of modifying global prototypes. + +### 🚨 36. Premature Optimization (e.g., bitwise for rounding) +**Context:** Readability vs Micro-benchmarks. +#### ❌ Bad Practice +```javascript +const floor = ~~x; // Double bitwise NOT to floor +``` +#### ⚠️ Problem +While `~~` is slightly faster in some engines, it makes the code cryptic. It also only works for numbers within the 32-bit integer range. +#### ✅ Best Practice +```javascript +const floor = Math.floor(x); +``` +#### 🚀 Solution +Prioritize readability. Modern JIT compilers are smart enough to optimize `Math.floor`. Only use bitwise tricks if profiling proves it's a critical bottleneck in a hot path. + +### 🚨 37. V8 Hidden Classes: Changing object shape after initialization +**Context:** V8 JIT optimization. +#### ❌ Bad Practice +```javascript +function User(name) { + this.name = name; +} +const u1 = new User('Alice'); +u1.age = 25; // Dynamically adding property +``` +#### ⚠️ Problem +V8 creates "Hidden Classes" to optimize object property access. Adding properties after initialization changes the "shape" of the object, causing V8 to drop to a slower "Dictionary Mode" for that object. +#### ✅ Best Practice +```javascript +function User(name, age) { + this.name = name; + this.age = age; +} +const u1 = new User('Alice', 25); +``` +#### 🚀 Solution +Initialize all object properties in the constructor or a factory function. Maintain a consistent object "shape" to keep V8 in the optimized path. + +### 🚨 38. Array Hole (Sparse Arrays) performance +**Context:** Memory allocation and JIT optimization. +#### ❌ Bad Practice +```javascript +const arr = new Array(100); +arr[50] = 'val'; +``` +#### ⚠️ Problem +Creating "holes" in arrays makes them "sparse". Sparse arrays are stored differently (as hash maps) which is much slower for iteration and access than "packed" arrays. +#### ✅ Best Practice +```javascript +const arr = Array.from({ length: 100 }, () => null); +``` +#### 🚀 Solution +Initialize arrays with default values (like `null` or `0`) instead of leaving empty slots. This keeps the array in "packed" mode. + +### 🚨 39. Using `eval()` or `new Function()` +**Context:** Security and performance. +#### ❌ Bad Practice +```javascript +const result = eval('2 + 2'); +``` +#### ⚠️ Problem +`eval()` executes strings as code, opening a massive XSS security vulnerability if the string contains user input. It also prevents the JIT compiler from optimizing the surrounding scope. +#### ✅ Best Practice +```javascript +const result = new Function('a', 'b', 'return a + b')(2, 2); // Slightly better, but still risky +// Better: +const operations = { '+': (a, b) => a + b }; +``` +#### 🚀 Solution +Avoid `eval()`. Use lookup tables, JSON parsing, or safe math libraries to handle dynamic logic. + +### 🚨 40. Micro-optimizations that hurt readability +**Context:** Maintaining a healthy codebase. +#### ❌ Bad Practice +```javascript +for (let i = 0, len = arr.length; i < len; i++) { /* ... */ } +``` +#### ⚠️ Problem +Caching `arr.length` was necessary 15 years ago. Today, modern engines optimize this automatically. Adding extra variables for micro-gains makes the code harder to read. +#### ✅ Best Practice +```javascript +for (const item of arr) { /* ... */ } +``` +#### 🚀 Solution +Focus on "Big O" complexity and clean code. Only micro-optimize after profiling identifies a specific performance hotspot. +======= ## 📚 Specialized Topics @@ -231,3 +821,4 @@ For further reading, please refer to the following specialized guides: - [✨ Modern Syntax & Functional Programming](./modern-syntax.md) - [⏳ Asynchronous & Logic](./async-logic.md) - [🧠 Professional & Niche Topics](./professional-niche.md) +>>>>>>> main