diff --git a/frontend/angular/advanced-performance.md b/frontend/angular/advanced-performance.md index d6b21fe..6312986 100644 --- a/frontend/angular/advanced-performance.md +++ b/frontend/angular/advanced-performance.md @@ -2,7 +2,7 @@ technology: Angular domain: frontend level: Senior/Architect -version: "20" +version: 20+ tags: [performance, advanced, angular, best-practices, clean-code, scalable-code] ai_role: Senior Angular Performance Expert last_updated: 2026-03-22 diff --git a/frontend/angular/architecture.md b/frontend/angular/architecture.md index 33d28e7..a656043 100644 --- a/frontend/angular/architecture.md +++ b/frontend/angular/architecture.md @@ -2,7 +2,7 @@ technology: Angular domain: frontend level: Senior/Architect -version: "20" +version: 20+ tags: [architecture, dependency-injection, angular, best-practices, clean-code, scalable-code] ai_role: Senior Angular Architecture Expert last_updated: 2026-03-22 diff --git a/frontend/angular/data-forms.md b/frontend/angular/data-forms.md index 0367a79..5d52000 100644 --- a/frontend/angular/data-forms.md +++ b/frontend/angular/data-forms.md @@ -2,7 +2,7 @@ technology: Angular domain: frontend level: Senior/Architect -version: "20" +version: 20+ tags: [forms, data, angular, best-practices, clean-code, scalable-code] ai_role: Senior Angular Data Expert last_updated: 2026-03-22 diff --git a/frontend/angular/expert-niche.md b/frontend/angular/expert-niche.md index 7c57dee..a481931 100644 --- a/frontend/angular/expert-niche.md +++ b/frontend/angular/expert-niche.md @@ -2,7 +2,7 @@ technology: Angular domain: frontend level: Senior/Architect -version: "20" +version: 20+ tags: [expert, niche, angular, best-practices, clean-code, scalable-code] ai_role: Senior Angular Expert last_updated: 2026-03-22 diff --git a/frontend/angular/readme.md b/frontend/angular/readme.md index 8421e90..01d81fd 100644 --- a/frontend/angular/readme.md +++ b/frontend/angular/readme.md @@ -2,8 +2,11 @@ technology: Angular domain: frontend level: Senior/Architect -version: "20" -tags: [best-practices, clean-code, architecture-patterns, vibe-coding, cursor-rules, typescript, software-architecture, system-design, solid-principles, production-ready, programming-standards, react-best-practices, node-js, design-patterns, scalable-code, windsurf-rules, ai-coding, fsd, ddd, enterprise-patterns] +version: 20+ +tags: [best-practices, clean-code, architecture-patterns, vibe-coding, cursor-rules, + typescript, software-architecture, system-design, solid-principles, production-ready, + programming-standards, react-best-practices, node-js, design-patterns, scalable-code, + windsurf-rules, ai-coding, fsd, ddd, enterprise-patterns] ai_role: Senior Angular Performance Expert last_updated: 2026-03-22 --- @@ -24,67 +27,67 @@ last_updated: 2026-03-22 ### 🚨 1. Using `@Input()` Decorator > [!NOTE] > **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 > [!NOTE] > **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()` > [!NOTE] > **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`) > [!NOTE] > **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) { @@ -94,54 +97,54 @@ 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`) > [!NOTE] > **Context:** Data Fetching -#### ❌ Bad Practice +### ❌ Bad Practice ```typescript data: unknown; 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 > [!NOTE] > **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` > [!NOTE] > **Context:** Reactivity -#### ❌ Bad Practice +### ❌ Bad Practice ```typescript ngOnChanges(changes: SimpleChanges) { if (changes['firstName']) { @@ -149,38 +152,38 @@ 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 > [!NOTE] > **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`) > [!NOTE] > **Context:** App Architecture -#### ❌ Bad Practice +### ❌ Bad Practice ```typescript @NgModule({ declarations: [AppComponent], @@ -188,130 +191,130 @@ 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 > [!NOTE] > **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 > [!NOTE] > **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`) > [!NOTE] > **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 > [!NOTE] > **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`) > [!NOTE] > **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 > [!NOTE] > **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. --- [⬆️ Back to Top](#) diff --git a/frontend/angular/state-management.md b/frontend/angular/state-management.md index 843c539..bc71d15 100644 --- a/frontend/angular/state-management.md +++ b/frontend/angular/state-management.md @@ -2,7 +2,7 @@ technology: Angular domain: frontend level: Senior/Architect -version: "20" +version: 20+ tags: [state-management, signals, zoneless, angular, best-practices, clean-code, scalable-code] ai_role: Senior Angular State Management Expert last_updated: 2026-03-29 @@ -49,7 +49,7 @@ graph TD ### 🚨 1. Managing Component State with Signals > [!NOTE] > **Context:** Synchronous local state. -#### ❌ Bad Practice +### ❌ Bad Practice ```typescript isLoading: boolean = false; data: unknown[] = []; @@ -62,9 +62,9 @@ fetchData() { }); } ``` -#### ⚠️ Problem +### ⚠️ Problem Relying on raw primitive properties means Angular relies on `zone.js` to run Change Detection globally whenever an event completes. -#### ✅ Best Practice +### ✅ Best Practice ```typescript isLoading = signal(false); data = signal([]); @@ -77,7 +77,7 @@ fetchData() { }); } ``` -#### 🚀 Solution +### 🚀 Solution Use `signal()`. It forces the developer to explicitly use `.set()` or `.update()`, signaling to the framework exactly when and where the change occurred. --- ## ⚙️ II. Derived State @@ -85,7 +85,7 @@ Use `signal()`. It forces the developer to explicitly use `.set()` or `.update() ### 🚨 2. Computing Values > [!NOTE] > **Context:** Creating derived state based on other state values. -#### ❌ Bad Practice +### ❌ Bad Practice ```typescript items = signal([1, 2, 3]); total = 0; @@ -94,14 +94,14 @@ updateTotal() { this.total = this.items().reduce((a, b) => a + b, 0); } ``` -#### ⚠️ Problem +### ⚠️ Problem Manually syncing state variables is error-prone. If you update `items` but forget to call `updateTotal()`, the state becomes inconsistent. -#### ✅ Best Practice +### ✅ Best Practice ```typescript items = signal([1, 2, 3]); total = computed(() => this.items().reduce((a, b) => a + b, 0)); ``` -#### 🚀 Solution +### 🚀 Solution Use `computed()`. The calculated value is memoized and only re-evaluates when its specific signal dependencies (in this case, `items`) change. --- ## ⚡ III. Side Effects @@ -109,11 +109,11 @@ Use `computed()`. The calculated value is memoized and only re-evaluates when it ### 🚨 3. Handling Side Effects Safely > [!NOTE] > **Context:** Executing logic when a signal changes. -#### ❌ Bad Practice +### ❌ Bad Practice Using getters or Angular lifecycle hooks like `ngDoCheck` to monitor value changes and trigger side effects like logging or generic HTTP calls. -#### ⚠️ Problem +### ⚠️ Problem This causes severe performance degradation as the logic is run on every change detection cycle, regardless of whether the specific state actually changed. -#### ✅ Best Practice +### ✅ Best Practice ```typescript constructor() { effect(() => { @@ -122,7 +122,7 @@ constructor() { }); } ``` -#### 🚀 Solution +### 🚀 Solution Use `effect()`. Effects track dependencies automatically and ensure the side effect runs solely when required. Always define them within an injection context (like a constructor). --- ## 🔗 IV. Component Communication @@ -130,14 +130,14 @@ Use `effect()`. Effects track dependencies automatically and ensure the side eff ### 🚨 4. Modern Data Passing > [!NOTE] > **Context:** Passing data between parent and child components. -#### ❌ Bad Practice +### ❌ Bad Practice ```typescript @Input() user: User; @Output() userUpdate = new EventEmitter(); ``` -#### ⚠️ Problem +### ⚠️ Problem Requires boilerplate, depends on decorators which are less ideal for dynamic composition, and heavily couples the components to legacy Zone-based tracking. -#### ✅ Best Practice +### ✅ Best Practice ```typescript // For one-way data flow user = input.required(); @@ -145,7 +145,7 @@ user = input.required(); // For two-way data binding synchronization userProfile = model(); ``` -#### 🚀 Solution +### 🚀 Solution Use the `input()` and `model()` functional APIs. They return signals that can be directly used in `computed()` properties within the child component. --- diff --git a/frontend/javascript/readme.md b/frontend/javascript/readme.md index 6e013e3..4fdb9e9 100644 --- a/frontend/javascript/readme.md +++ b/frontend/javascript/readme.md @@ -18,7 +18,7 @@ last_updated: 2026-03-22 ### 🚨 1. `var` vs `const/let` > [!NOTE] > **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) { @@ -26,9 +26,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) { @@ -36,43 +36,43 @@ 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 `==` > [!NOTE] > **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 > [!NOTE] > **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' }; @@ -82,41 +82,41 @@ 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 > [!NOTE] > **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 > [!NOTE] > **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; @@ -124,59 +124,59 @@ 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)` > [!NOTE] > **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 > [!NOTE] > **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 > [!NOTE] > **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) { /* ... */ } @@ -188,14 +188,14 @@ 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) > [!NOTE] > **Context:** Cognitive load and code readability. -#### ❌ Bad Practice +### ❌ Bad Practice ```javascript function getData(user) { if (user) { @@ -207,9 +207,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) { @@ -218,26 +218,26 @@ 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) > [!NOTE] > **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. --- ## 📚 Specialized Topics diff --git a/frontend/react/performance.md b/frontend/react/performance.md index 075af0b..d80ac86 100644 --- a/frontend/react/performance.md +++ b/frontend/react/performance.md @@ -20,7 +20,7 @@ last_updated: 2026-03-22 ### 🔹 1. Manual Memoization vs React Compiler > [!NOTE] > **Context:** Avoiding unnecessary re-renders. -#### ❌ Bad Practice +### ❌ Bad Practice ```tsx import { useMemo, useCallback } from 'react'; @@ -35,9 +35,9 @@ function UserList({ users }) { ); } ``` -#### ⚠️ Problem +### ⚠️ Problem Adding manual `useMemo` and `useCallback` clutters the codebase, introduces dependency array bugs, and makes code harder to refactor. -#### ✅ Best Practice +### ✅ Best Practice ```tsx function UserList({ users }) { const sortedUsers = users.sort(); @@ -50,7 +50,7 @@ function UserList({ users }) { ); } ``` -#### 🚀 Solution +### 🚀 Solution Rely on the **React Compiler** (introduced in React 19+). The compiler automatically memoizes values and functions, meaning manual hooks are largely obsolete and code becomes purely declarative. - **Performance Note:** The React Compiler analyzes your component structure and injects optimal memoization (similar to SolidJS's granular updates), eliminating the overhead of manual dependency tracking. - **Security Note:** While the React Compiler does not directly impact security, it ensures components render exactly when their inputs change, reducing side effects that might otherwise expose temporary or stale data to users. @@ -58,7 +58,7 @@ Rely on the **React Compiler** (introduced in React 19+). The compiler automatic ### 🔹 2. Resolving Promises During Render > [!NOTE] > **Context:** Conditionally handling promises without `useEffect` or `useState`. -#### ❌ Bad Practice +### ❌ Bad Practice ```tsx import { useEffect, useState } from 'react'; @@ -73,9 +73,9 @@ function Profile({ profilePromise }) { return
    {data.name}
    ; } ``` -#### ⚠️ Problem +### ⚠️ Problem Using `useEffect` to unwrap promises leads to "waterfalls", unnecessary rendering cycles, and race conditions. -#### ✅ Best Practice +### ✅ Best Practice ```tsx import { use, Suspense } from 'react'; @@ -89,7 +89,7 @@ function Profile({ profilePromise }) { // // ``` -#### 🚀 Solution +### 🚀 Solution Use the `use()` API inside components combined with ``. - **Performance Note:** `use()` suspends the component rendering if the promise is not resolved. This seamlessly integrates with ``, providing a highly optimized rendering fallback behavior. - **Security Note:** `use()` can also resolve context, mitigating prop-drilling vulnerabilities and ensuring components securely consume data directly from contexts they are explicitly authorized for. Always sanitize any text coming from external APIs before rendering. diff --git a/frontend/react/readme.md b/frontend/react/readme.md index 343507f..34fa17b 100644 --- a/frontend/react/readme.md +++ b/frontend/react/readme.md @@ -25,7 +25,7 @@ last_updated: 2026-03-22 ### 🔹 1. Direct DOM Manipulation > [!NOTE] > **Context:** Updating elements in a React component. -#### ❌ Bad Practice +### ❌ Bad Practice ```tsx function Component() { const handleClick = () => { @@ -34,9 +34,9 @@ function Component() { return
    Click me
    ; } ``` -#### ⚠️ Problem +### ⚠️ Problem Direct DOM manipulation bypasses React's virtual DOM, causing inconsistencies between the actual DOM and React's internal state. -#### ✅ Best Practice +### ✅ Best Practice ```tsx function Component() { const [isActive, setIsActive] = useState(false); @@ -50,7 +50,7 @@ function Component() { ); } ``` -#### 🚀 Solution +### 🚀 Solution Always use state and props to drive the UI. React uses a virtual DOM to efficiently update the real DOM based on state changes. - **Performance Note:** React's virtual DOM diffing algorithm is highly optimized. Bypassing it can lead to forced synchronous layouts and jank. - **Security Note:** Direct DOM manipulation can open up Cross-Site Scripting (XSS) vulnerabilities if user input is not properly sanitized before being inserted into the DOM. @@ -58,13 +58,13 @@ Always use state and props to drive the UI. React uses a virtual DOM to efficien ### 🔹 2. Large Component Files > [!NOTE] > **Context:** Managing component complexity. -#### ❌ Bad Practice +### ❌ Bad Practice A single 2000-line file containing the entire page's logic and UI. -#### ⚠️ Problem +### ⚠️ Problem Massive components are difficult to read, test, and maintain. They often violate the Single Responsibility Principle. -#### ✅ Best Practice +### ✅ Best Practice Break down the UI into smaller, reusable components, each with a single responsibility. -#### 🚀 Solution +### 🚀 Solution Extract logic into custom hooks and presentational elements into separate files. ## 📚 Specialized Topics diff --git a/frontend/react/state-management.md b/frontend/react/state-management.md index c97a8b9..2a873d5 100644 --- a/frontend/react/state-management.md +++ b/frontend/react/state-management.md @@ -20,7 +20,7 @@ last_updated: 2026-03-22 ### 🔹 1. Handling Async Actions (Forms) > [!NOTE] > **Context:** Managing state updates triggered by form submissions or asynchronous operations. -#### ❌ Bad Practice +### ❌ Bad Practice ```tsx import { useState } from 'react'; @@ -44,9 +44,9 @@ function Form() { return
    ...
    ; } ``` -#### ⚠️ Problem +### ⚠️ Problem Manually managing `isPending` and error states is repetitive and prone to race conditions, especially when multiple requests are fired. -#### ✅ Best Practice +### ✅ Best Practice ```tsx import { useActionState } from 'react'; import { saveAction } from './actions'; @@ -62,7 +62,7 @@ function Form() { ); } ``` -#### 🚀 Solution +### 🚀 Solution Use the `useActionState` Hook (React 19+) for seamless action state management. - **Performance Note:** `useActionState` effectively handles race conditions by ensuring only the latest action state is applied to the UI, optimizing rendering cycles. - **Security Note:** Form actions seamlessly interact with Server Actions. Ensure that `saveAction` strictly validates input server-side to prevent malicious payloads, and use CSRF tokens if required by your framework. @@ -70,13 +70,13 @@ Use the `useActionState` Hook (React 19+) for seamless action state management. ### 🔹 2. Using Global State Naively > [!NOTE] > **Context:** Storing local component UI state in a global store (e.g., Redux, Zustand). -#### ❌ Bad Practice +### ❌ Bad Practice Putting a dropdown's `isOpen` state into the global Redux store. -#### ⚠️ Problem +### ⚠️ Problem Unnecessary global re-renders and bloated global state size. -#### ✅ Best Practice +### ✅ Best Practice Use `useState` or `useReducer` for UI state that belongs locally to a component tree. -#### 🚀 Solution +### 🚀 Solution Only elevate state to a global store when it is shared across multiple disjoint component branches. - **Performance Note:** Global state updates trigger broad change detection and React reconciliation. Minimizing global state keeps updates localized and fast. - **Security Note:** Do not store sensitive access tokens (e.g., JWT) in unencrypted global state (like localStorage/Redux state) that may persist across sessions or expose them to XSS attacks. Prefer HttpOnly cookies. diff --git a/frontend/typescript/readme.md b/frontend/typescript/readme.md index 159e3be..c4dceae 100644 --- a/frontend/typescript/readme.md +++ b/frontend/typescript/readme.md @@ -2,7 +2,7 @@ technology: TypeScript domain: frontend level: Senior/Architect -version: "5.0+" +version: 5.5+ tags: [typescript, type-safety, clean-code, best-practices, architecture] ai_role: Senior TypeScript Architecture Expert last_updated: 2026-03-22