@moon791017/neo-skills 1.0.24 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/GEMINI.md CHANGED
@@ -107,3 +107,5 @@ When interacting with this codebase or using the extension, the agent follows th
107
107
  * **Swift 專家:** 支援 Swift 5.0 至 6.0+ 的現代開發模式,涵蓋 SwiftUI、Structured Concurrency 與記憶體安全。
108
108
 
109
109
  * **SwiftUI 專家:** 支援 iOS 16.0+ 與 Swift 5.0+ 的現代開發模式,專注於 NavigationStack、Observation 框架、資料流架構及高效能視圖設計。
110
+
111
+ * **JavaScript 現代語法專家:** 跨版本 JavaScript 專家 (ES6-ES2025+),專注於現代化語法、模組系統與高效能開發模式。
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Neo Skills
2
2
 
3
3
  [![test-on-develop](https://github.com/Benknightdark/neo-skills/actions/workflows/test-on-develop.yml/badge.svg)](https://github.com/Benknightdark/neo-skills/actions/workflows/test-on-develop.yml)
4
+ [![npm version](https://img.shields.io/npm/v/@moon791017/neo-skills.svg)](https://www.npmjs.com/package/@moon791017/neo-skills)
4
5
 
5
6
  ![Neo Skills banner](https://raw.githubusercontent.com/Benknightdark/neo-skills/refs/heads/develop/images/banner.png)
6
7
 
@@ -52,10 +53,13 @@
52
53
  * **Swift 5.0+ 專家 (`skills/neo-swift`)**:支援從基礎語法到 Swift 6 的現代開發模式,涵蓋 SwiftUI、Structured Concurrency、記憶體安全以及高效能 App 開發指引。
53
54
  * **SwiftUI 專家 (`skills/neo-swift-ui`)**:支援 iOS 16.0+ 與 Swift 5.0+ 的現代開發模式,專注於 NavigationStack、Observation 框架、資料流架構及高效能視圖設計。
54
55
 
55
- ### 8. 需求釐清助手
56
+ ### 8. JavaScript 開發專家
57
+ * **JavaScript 現代語法專家 (`skills/neo-javascript`)**:跨版本 JavaScript 專家 (ES6 - ES2025+),專注於現代化語法、模組系統與高效能開發模式。
58
+
59
+ ### 9. 需求釐清助手
56
60
  * **需求釐清**:系統化引導用戶釐清模糊需求,並將其轉化為結構化的規格文件(背景、功能、約束、驗收標準)。
57
61
 
58
- ### 9. 安全守衛 (Security Guard)
62
+ ### 10. 安全守衛 (Security Guard)
59
63
  * **主動防護 (`secret-guard.ts`)**:作為 CLI 的中介軟體 (Hook),自動攔截並掃描所有工具執行的參數。若偵測到敏感資訊(如環境設定檔、私鑰、雲端憑證等)將強制阻擋執行,防止機密外洩。
60
64
 
61
65
  ## 📂 系統架構
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "neo-skills",
3
3
  "description": "A universal capability extension for Gemini CLI",
4
- "version": "0.50.0",
4
+ "version": "0.51.0",
5
5
  "mcpServers": {
6
6
  "neo-skills": {
7
7
  "command": "node",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moon791017/neo-skills",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "type": "module",
5
5
  "description": "Neo Skills: A Universal Expert Agent Extension",
6
6
  "homepage": "https://neo-blog-iota.vercel.app/",
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: neo-javascript
3
+ version: "1.0.0"
4
+ category: "Core"
5
+ description: "跨版本 JavaScript 專家技能 (ES6 - ES2025+)。支援現代前端與純 JavaScript 開發模式,涵蓋 Arrow Functions 到 Iterator Helpers 的全方位演進。"
6
+ compatibility: "Supports ES6 (ES2015) through ES2025 and Stage 3+ proposals. Adaptive to modern browser environments and pure JS runtimes."
7
+ ---
8
+
9
+ # Modern JavaScript (ES6+) Expert Skill
10
+
11
+ ## Trigger On
12
+ - The user asks to write, debug, refactor, or review JavaScript code.
13
+ - The project directory contains `*.js`, `*.mjs`, or JavaScript configuration files (e.g., `eslint.config.js`, `vite.config.js`).
14
+ - HTML files (`*.html`) or Razor views (`*.cshtml`) contain inline `<script>` blocks or reference external `.js` files via `<script src="...">`.
15
+ - The target runtime is a modern browser (Chrome 80+, Firefox 78+, Safari 14+) or a pure JS environment.
16
+ - Code modernization is needed (e.g., converting `var` to `const`/`let`, callbacks to `async`/`await`, legacy scripts to ESM).
17
+
18
+ ## Workflow
19
+ 1. **Perceive (Environment Awareness):**
20
+ - Inspect ESLint / Biome configuration to identify the project's `ecmaVersion` and coding conventions.
21
+ - Determine runtime target: browser (check for DOM APIs, bundler config like `vite.config.js`, `webpack.config.js`).
22
+ - Detect JavaScript embedded in HTML (`*.html`) or Razor views (`*.cshtml`): identify inline `<script>` blocks and external `<script src="...">` references. For `.cshtml` files, note the interplay with Razor syntax (`@` directives, `@section Scripts`).
23
+ - Identify the effective ES version upper limit based on the runtime/transpiler configuration (e.g., Babel targets, TypeScript `target`, browserslist). For inline scripts without a build pipeline, default to the browser's native ES support.
24
+ 2. **Reason (Planning Phase):**
25
+ - Evaluate the modernization level of the current code to determine the refactoring strategy.
26
+ - In environments targeting older runtimes (e.g., IE11 via Babel), avoid using features without polyfill support, but prioritize using `const`/`let`, arrow functions, and template literals.
27
+ - In modern environments (modern browsers), actively adopt new features to reduce boilerplate code.
28
+ - Be aware of browser-specific concerns (DOM manipulation, Web APIs, rendering performance).
29
+ 3. **Act (Execution Phase):**
30
+ - Write high-quality code using modern syntax to improve readability and maintainability.
31
+ - Implement immutable data patterns (spread operators, `Object.freeze`, `structuredClone`, immutable array methods).
32
+ - Utilize `async`/`await` and `Promise` composition for asynchronous operations.
33
+ - Prefer ESM (`import`/`export`) as the standard module system.
34
+ 4. **Validate (Standard Validation):**
35
+ - Validate strict equality (`===`) usage and absence of `var` declarations.
36
+ - Check if asynchronous operations correctly handle errors (`try`/`catch` around `await`, `.catch()` on Promises).
37
+ - Ensure code avoids common security pitfalls (no `eval()`, no prototype pollution, no `innerHTML` with unsanitized input).
38
+ - Verify naming conventions follow community standards (camelCase for variables/functions, PascalCase for classes).
39
+
40
+ ## Feature Roadmap (ES6 - ES2025+)
41
+
42
+ ### ES6 & ES2016-ES2019 (Origin)
43
+ - **Arrow Functions:** `(a, b) => a + b` concise function syntax with lexical `this` binding.
44
+ - **`let` / `const`:** Block-scoped variable declarations replacing `var`.
45
+ - **Template Literals:** `` `Hello, ${name}!` `` for string interpolation and multi-line strings.
46
+ - **Destructuring:** `const { id, name } = user;` extract values from objects and arrays.
47
+ - **Default / Rest / Spread:** Default parameters, `...rest` parameters, and `...spread` for arrays/objects.
48
+ - **Classes:** `class` syntax for prototype-based inheritance with `constructor`, `extends`, and `super`.
49
+ - **Promises:** `new Promise((resolve, reject) => ...)` for asynchronous flow control.
50
+ - **Modules:** `import` / `export` for modular code organization (ES Modules).
51
+ - **Symbol / Map / Set:** New primitive type and collection data structures.
52
+ - **String Methods (ES6):** `includes()`, `startsWith()`, `endsWith()` for easier string searching.
53
+ - **Array Methods (ES6):** `Array.from()`, `Array.of()`, `find()`, `findIndex()` for enhanced array manipulation.
54
+ - **Number/Math Methods (ES6):** `Number.isInteger()`, `Number.isNaN()`, `Math.trunc()`, `Math.sign()`.
55
+ - **Generators & Iterators:** `function*` and `for...of` for lazy iteration.
56
+ - **`async` / `await` (ES2017):** Syntactic sugar for Promise-based asynchronous code.
57
+ - **Object.values / Object.entries (ES2017):** Iterate over object values and key-value pairs.
58
+ - **Rest / Spread Properties (ES2018):** `{ ...obj }` for object shallow cloning and rest extraction.
59
+ - **`Promise.finally` (ES2018):** Execute cleanup logic regardless of fulfillment or rejection.
60
+ - **Async Iteration (ES2018):** `for await...of` for consuming async iterables.
61
+ - **`Array.flat` / `flatMap` (ES2019):** Flatten nested arrays and map-then-flatten in one step.
62
+ - **`Object.fromEntries` (ES2019):** Convert key-value pairs back into an object.
63
+ - **Optional Catch Binding (ES2019):** `catch { }` without requiring the error parameter.
64
+
65
+ ### ES2020 & ES2021 (Foundation)
66
+ - **Optional Chaining (`?.`):** Safely access deeply nested properties without manual null checks.
67
+ - **Nullish Coalescing (`??`):** Provide defaults only for `null`/`undefined`, unlike `||` which also catches `0`, `""`, `false`.
68
+ - **`BigInt`:** Arbitrary-precision integer arithmetic via `123n` literal syntax.
69
+ - **`Promise.allSettled()`:** Wait for all promises to complete regardless of rejection.
70
+ - **`globalThis`:** Universal reference to the global object across all environments.
71
+ - **Dynamic `import()`:** Load modules conditionally or lazily at runtime.
72
+ - **Logical Assignment (`&&=`, `||=`, `??=`):** Combine logical operators with assignment for concise state updates.
73
+ - **`String.prototype.replaceAll()`:** Replace all occurrences without regex.
74
+ - **`Promise.any()`:** Resolve with the first fulfilled promise, reject only if all reject.
75
+ - **Numeric Separators:** `1_000_000` for readable large numbers.
76
+
77
+ ### ES2022 & ES2023 (Productivity)
78
+ - **Top-level `await`:** Use `await` directly in ESM modules without wrapping in an async function.
79
+ - **Error Cause (`{ cause }`):** Chain errors to preserve root cause context.
80
+ - **`Array.at()`:** Negative indexing for arrays, e.g., `arr.at(-1)` for the last element.
81
+ - **`Object.hasOwn()`:** Safer, prototype-independent property check replacing `hasOwnProperty`.
82
+ - **Class Fields:** Public and private (`#field`) instance fields and methods.
83
+ - **RegExp Match Indices (`/d` flag):** Get start/end positions of captured groups.
84
+ - **Immutable Array Methods:** `toSorted()`, `toReversed()`, `toSpliced()`, `with()` — return new arrays without mutation.
85
+ - **`Array.findLast()` / `findLastIndex()`:** Search arrays from the end.
86
+
87
+ ### ES2024 & ES2025+ (Cutting Edge)
88
+ - **`Promise.withResolvers()`:** Destructure `{ promise, resolve, reject }` for cleaner deferred patterns.
89
+ - **`Object.groupBy()` / `Map.groupBy()`:** Group array elements by a classifier function.
90
+ - **Set Methods:** `union()`, `intersection()`, `difference()`, `symmetricDifference()`, `isSubsetOf()`, `isSupersetOf()`, `isDisjointFrom()`.
91
+ - **Iterator Helpers:** `.map()`, `.filter()`, `.take()`, `.drop()`, `.flatMap()`, `.toArray()` on iterators.
92
+ - **`RegExp.escape()`:** Safely escape special characters for use in RegExp construction.
93
+ - **Import Attributes:** `import data from './data.json' with { type: 'json' }`.
94
+ - **Decorators (Stage 3):** Class and method decorators for cross-cutting concerns.
95
+ - **`Promise.try()`:** Safely start a promise chain from a synchronous or asynchronous function.
96
+ - **Well-formed Unicode Strings:** `String.prototype.isWellFormed()` and `toWellFormed()`.
97
+ - **Temporal API (Stage 3):** A modern replacement for the `Date` object, providing robust date/time arithmetic.
98
+ - **Explicit Resource Management (Stage 3):** `using` keyword with `Symbol.dispose` for deterministic cleanup.
99
+
100
+ ## Coding Standards
101
+ - **Variable Declarations:** Always use `const` by default; use `let` only when reassignment is necessary. Never use `var`.
102
+ - **Modules:** Use ESM (`import`/`export`) as the default module system. Use `import()` for dynamic/lazy loading.
103
+ - **Immutability:** Prefer non-mutating array methods (`toSorted`, `toReversed`, `with`), spread operators, and `structuredClone` for deep copies.
104
+ - **Async Safety:** Always wrap `await` in `try`/`catch` or chain `.catch()`. Never leave Promises unhandled. Use `AbortController` for cancellable operations.
105
+
106
+ ## Deliver
107
+ - **Runtime-Optimized Code:** Provide the most appropriate modern syntax code based on the target runtime and ES version.
108
+ - **Modernization Insights:** Provide specific refactoring suggestions for upgrading from older JavaScript syntax to new features (e.g., from callbacks to `async`/`await`, from `var` to `const`/`let`).
109
+ - **Syntax Explanations:** Clearly explain the design intent and advantages behind the modern JavaScript features used.
110
+
111
+ ## Validate
112
+ - Ensure the provided code complies with the syntax specifications of the target ES version and runtime.
113
+ - Validate whether the code follows JavaScript best practices for error handling, null safety, and immutability.
114
+ - Confirm the code has good readability and modern conventions (e.g., proper use of destructuring, template literals, ESM).
115
+
116
+ ## Documentation
117
+ ### Official References
118
+ - [ECMAScript 2025 Language Specification](https://tc39.es/ecma262/)
119
+ - [TC39 Proposals (Stage 3+)](https://github.com/tc39/proposals/blob/main/README.md)
120
+ - [MDN Web Docs - JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
121
+
122
+ ### Internal References
123
+ - [JavaScript Coding Style and Naming Conventions Guide](reference/coding-style.md)
124
+ - [JavaScript Anti-Patterns and Best Practices](reference/anti-patterns.md)
125
+ - [Modern JavaScript Patterns Guide](reference/patterns.md)
@@ -0,0 +1,296 @@
1
+ # JavaScript Anti-Patterns & Best Practices
2
+
3
+ This document lists common mistakes (Anti-Patterns) in JavaScript development and their corresponding correct practices (Best Practices).
4
+
5
+ ## 1. Variable Declarations and Scoping
6
+
7
+ ### 1.1 Avoid `var` — Use `const` and `let`
8
+
9
+ **Problem**: `var` is function-scoped and hoisted, leading to unexpected behavior and bugs in loops and closures.
10
+
11
+ - **Bad**:
12
+
13
+ ```javascript
14
+ for (var i = 0; i < 5; i++) {
15
+ setTimeout(() => console.log(i), 100); // Prints 5, 5, 5, 5, 5
16
+ }
17
+ ```
18
+
19
+ - **Good**:
20
+
21
+ ```javascript
22
+ for (let i = 0; i < 5; i++) {
23
+ setTimeout(() => console.log(i), 100); // Prints 0, 1, 2, 3, 4
24
+ }
25
+ ```
26
+
27
+ ### 1.2 Avoid Loose Equality (`==`)
28
+
29
+ **Problem**: `==` performs type coercion, leading to surprising comparisons (e.g., `0 == ''` is `true`, `null == undefined` is `true`).
30
+
31
+ - **Bad**:
32
+
33
+ ```javascript
34
+ if (value == null) { ... } // Catches both null and undefined — unclear intent
35
+ if (count == '0') { ... } // true due to type coercion
36
+ ```
37
+
38
+ - **Good**:
39
+
40
+ ```javascript
41
+ if (value === null || value === undefined) { ... } // Explicit intent
42
+ if (count === 0) { ... } // No coercion surprises
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2. Asynchronous Programming
48
+
49
+ ### 2.1 Avoid Callback Hell
50
+
51
+ **Problem**: Deeply nested callbacks make code unreadable and error handling fragile.
52
+
53
+ - **Bad**:
54
+
55
+ ```javascript
56
+ getUser(id, (err, user) => {
57
+ if (err) return handleError(err);
58
+ getOrders(user.id, (err, orders) => {
59
+ if (err) return handleError(err);
60
+ getDetails(orders[0].id, (err, details) => {
61
+ // Deeply nested...
62
+ });
63
+ });
64
+ });
65
+ ```
66
+
67
+ - **Good**:
68
+
69
+ ```javascript
70
+ try {
71
+ const user = await getUser(id);
72
+ const orders = await getOrders(user.id);
73
+ const details = await getDetails(orders[0].id);
74
+ } catch (err) {
75
+ handleError(err);
76
+ }
77
+ ```
78
+
79
+ ### 2.2 Avoid Unhandled Promise Rejections
80
+
81
+ **Problem**: A Promise without `.catch()` or `try`/`catch` around `await` causes unhandled rejection warnings and unpredictable application states.
82
+
83
+ - **Bad**:
84
+
85
+ ```javascript
86
+ async function fetchData() {
87
+ const data = await api.get('/data'); // No error handling
88
+ return data;
89
+ }
90
+ ```
91
+
92
+ - **Good**:
93
+
94
+ ```javascript
95
+ async function fetchData() {
96
+ try {
97
+ const data = await api.get('/data');
98
+ return data;
99
+ } catch (err) {
100
+ throw new Error('Failed to fetch data', { cause: err });
101
+ }
102
+ }
103
+ ```
104
+
105
+ ---
106
+
107
+ ## 3. Memory & Performance
108
+
109
+ ### 3.1 Avoid Event Listener and Timer Leaks
110
+
111
+ **Problem**: Adding event listeners or `setInterval` without cleanup leads to memory leaks, especially in single-page applications.
112
+
113
+ - **Bad**:
114
+
115
+ ```javascript
116
+ function setup() {
117
+ window.addEventListener('resize', handleResize);
118
+ // Never removed — leaks when component is destroyed
119
+ }
120
+ ```
121
+
122
+ - **Good**:
123
+
124
+ ```javascript
125
+ const controller = new AbortController();
126
+ window.addEventListener('resize', handleResize, { signal: controller.signal });
127
+ // Cleanup: controller.abort();
128
+ ```
129
+
130
+ ### 3.2 Avoid Blocking the Main Thread
131
+
132
+ **Problem**: CPU-intensive synchronous operations (huge loops, massive DOM updates, or heavy JSON parsing) block the main thread, freezing the UI and making the browser unresponsive.
133
+
134
+ - **Bad**:
135
+
136
+ ```javascript
137
+ function processLargeData(items) {
138
+ // Blocks the UI thread completely for a long time
139
+ return items.map(item => expensiveComputation(item));
140
+ }
141
+ ```
142
+
143
+ - **Good**:
144
+
145
+ ```javascript
146
+ // Use Web Workers for heavy computation, or chunking via setTimeout/requestAnimationFrame
147
+ function processDataInChunks(items) {
148
+ let index = 0;
149
+ function chunk() {
150
+ const end = Math.min(index + 100, items.length);
151
+ for (; index < end; index++) {
152
+ expensiveComputation(items[index]);
153
+ }
154
+ if (index < items.length) {
155
+ requestAnimationFrame(chunk); // Yield back to the browser
156
+ }
157
+ }
158
+ chunk();
159
+ }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 4. Security
165
+
166
+ ### 4.1 Avoid `eval()` and `innerHTML` with Untrusted Input
167
+
168
+ **Problem**: `eval()` executes arbitrary code; `innerHTML` with user input enables XSS attacks.
169
+
170
+ - **Bad**:
171
+
172
+ ```javascript
173
+ element.innerHTML = userComment; // XSS vulnerability
174
+ eval(userInput); // Remote code execution
175
+ ```
176
+
177
+ - **Good**:
178
+
179
+ ```javascript
180
+ element.textContent = userComment; // Safe
181
+ // For HTML rendering, use a sanitization library (e.g., DOMPurify)
182
+ ```
183
+
184
+ ### 4.2 Avoid Mutating Function Parameters (Immutability)
185
+
186
+ **Problem**: Directly mutating input arguments causes hard-to-trace side effects. The caller's data is changed unexpectedly.
187
+
188
+ - **Bad**:
189
+
190
+ ```javascript
191
+ const addNewTag = (tags, newTag) => {
192
+ tags.push(newTag); // Mutates the original array
193
+ return tags;
194
+ };
195
+ ```
196
+
197
+ - **Good**:
198
+
199
+ ```javascript
200
+ const addNewTag = (tags, newTag) => {
201
+ return [...tags, newTag]; // Returns a new array, keeps original data intact
202
+ };
203
+ ```
204
+
205
+ ### 4.3 Avoid Prototype Pollution
206
+
207
+ **Problem**: Merging untrusted objects into existing objects can overwrite `Object.prototype` properties, leading to security vulnerabilities.
208
+
209
+ - **Bad**:
210
+
211
+ ```javascript
212
+ function merge(target, source) {
213
+ for (const key in source) {
214
+ target[key] = source[key]; // '__proto__' can be injected
215
+ }
216
+ }
217
+ ```
218
+
219
+ - **Good**:
220
+
221
+ ```javascript
222
+ function merge(target, source) {
223
+ for (const key of Object.keys(source)) {
224
+ if (key === '__proto__' || key === 'constructor') continue;
225
+ target[key] = source[key];
226
+ }
227
+ }
228
+ // Or use structuredClone / Object.assign with null-prototype objects
229
+ ```
230
+
231
+ ---
232
+
233
+ ## 5. Modern JavaScript Patterns
234
+
235
+ ### 5.1 Variable Declarations (ES6+)
236
+
237
+ - **Legacy**: `var name = 'Alice';`
238
+ - **Modern**: `const name = 'Alice';` (Block-scoped, no hoisting surprises)
239
+
240
+ ### 5.2 Async Flow (ES2017+)
241
+
242
+ - **Legacy**:
243
+
244
+ ```javascript
245
+ fetch('/api/data')
246
+ .then(res => res.json())
247
+ .then(data => console.log(data))
248
+ .catch(err => console.error(err));
249
+ ```
250
+
251
+ - **Modern**:
252
+
253
+ ```javascript
254
+ try {
255
+ const res = await fetch('/api/data');
256
+ const data = await res.json();
257
+ console.log(data);
258
+ } catch (err) {
259
+ console.error(err);
260
+ }
261
+ ```
262
+
263
+ ### 5.3 Default Values (ES2020+)
264
+
265
+ - **Legacy**: `const name = obj && obj.user && obj.user.name || 'default';`
266
+ - **Modern**: `const name = obj?.user?.name ?? 'default';` (Optional chaining + nullish coalescing)
267
+
268
+ ### 5.4 Array Mutation (ES2023+)
269
+
270
+ - **Legacy**: `const sorted = [...arr].sort(compareFn);` (Manual copy to avoid mutation)
271
+ - **Modern**: `const sorted = arr.toSorted(compareFn);` (Returns a new sorted array)
272
+
273
+ ### 5.5 Object Property Checking (ES2022+)
274
+
275
+ - **Legacy**: `if (obj.hasOwnProperty('key'))` (Can be overridden on the object)
276
+ - **Modern**: `if (Object.hasOwn(obj, 'key'))` (Static method, safe from prototype overriding)
277
+
278
+ ### 5.6 Module System (ES6+)
279
+
280
+ - **Legacy**: `var cloneDeep = require('lodash/cloneDeep');` (CommonJS / Script tags)
281
+ - **Modern**: `import { cloneDeep } from 'lodash-es';` (ESM)
282
+
283
+ ### 5.7 Logical Assignment (ES2021+)
284
+
285
+ - **Legacy**: `if (!obj.prop) { obj.prop = value; }` (Verbose and repetitive)
286
+ - **Modern**: `obj.prop ??= value;` (Concise nullish assignment)
287
+
288
+ ### 5.8 String & Array Searching (ES6+)
289
+
290
+ - **Legacy**: `if (str.indexOf('text') !== -1)` (Returns index, requires `!== -1` check)
291
+ - **Modern**: `if (str.includes('text'))` (Returns boolean directly, clearer intent)
292
+
293
+ ### 5.9 Object Grouping (ES2024+)
294
+
295
+ - **Legacy**: `users.reduce((acc, user) => { (acc[user.role] ||= []).push(user); return acc; }, {});` (Verbose reduce logic)
296
+ - **Modern**: `Object.groupBy(users, user => user.role);` (Clear intent, native support)
@@ -0,0 +1,112 @@
1
+ # JavaScript Coding Conventions
2
+
3
+ This guide follows community-established conventions from [MDN JavaScript Guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide), [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), and [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html), aimed at improving development efficiency and maintaining project consistency.
4
+
5
+ ## 1. Naming Conventions
6
+
7
+ Good naming is the core of self-documenting code and reduces communication overhead.
8
+
9
+ ### 1.1 camelCase
10
+ Used for **variables**, **functions**, and **object properties**.
11
+ - **Variable**: `const userName = 'Alice';`
12
+ - **Function**: `function getUserById(id) { ... }`
13
+ - **Object Property**: `{ firstName: 'Bob', lastName: 'Smith' }`
14
+
15
+ ### 1.2 PascalCase
16
+ Used for **classes**, **constructors**, and **components**.
17
+ - **Class**: `class UserManager { ... }`
18
+ - **React/UI Component**: `function NavBar() { ... }`
19
+
20
+ ### 1.3 UPPER_SNAKE_CASE
21
+ Used for **module-level constants** and **configuration values**.
22
+ - **Constant**: `const MAX_RETRIES = 3;`
23
+ - **Config**: `const API_BASE_URL = 'https://api.example.com';`
24
+
25
+ ### 1.4 Private Fields
26
+ Use the `#` prefix for **private class fields** (ES2022+).
27
+ - **Private field**: `#count = 0;`
28
+ - **Private method**: `#validate() { ... }`
29
+
30
+ ---
31
+
32
+ ## 2. File Organization
33
+
34
+ - **File naming**: Use `kebab-case` for file names (e.g., `user-service.js`, `auth-utils.mjs`).
35
+ - **Module type**: Use `.mjs` extension or `"type": "module"` in `package.json` for ESM.
36
+ - **Single responsibility**: One primary export per module file to facilitate tree-shaking and code navigation.
37
+ - **Import order**: External packages first, then internal modules. Separate groups with blank lines.
38
+ ```javascript
39
+ // 1. External packages
40
+ import React, { useState } from 'react';
41
+ import { debounce } from 'lodash-es';
42
+
43
+ // 2. Internal modules
44
+ import { validateInput } from './utils/validation.js';
45
+ import { UserCard } from './components/user-card.js';
46
+ ```
47
+
48
+ ---
49
+
50
+ ## 3. Formatting
51
+
52
+ ### 3.1 K&R Style (Opening brace on same line)
53
+ The opening brace `{` stays on the same line as the statement. This is the standard JavaScript style.
54
+ ```javascript
55
+ // Correct approach
56
+ function process() {
57
+ if (isReady) {
58
+ doWork();
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### 3.2 Indentation and Spacing
64
+ - **Indentation**: Fixed at **2 spaces**. The use of Tab characters is prohibited to ensure consistent display across platforms.
65
+ - **Semicolons**: Be consistent within a project. If using semicolons, use them everywhere. If omitting (relying on ASI), do so consistently and understand the pitfalls.
66
+ - **Blank lines**: Leave one blank line between function declarations; use a single blank line to separate logical blocks within a function.
67
+
68
+ ---
69
+
70
+ ## 4. Asynchronous Programming
71
+
72
+ - **Async/Await**: Prefer `async`/`await` over `.then()` chains for readability.
73
+ - **Error Handling**: Always wrap `await` calls in `try`/`catch` or use a utility wrapper.
74
+ - **AbortController**: Use `AbortController` for cancellable fetch requests, timers, and event listeners.
75
+ ```javascript
76
+ async function getUserById(id, signal) {
77
+ const response = await fetch(`/api/users/${id}`, { signal });
78
+ if (!response.ok) {
79
+ throw new Error(`HTTP ${response.status}`, { cause: response });
80
+ }
81
+ return response.json();
82
+ }
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 5. Modern JavaScript Best Practices
88
+
89
+ - **Variable Declarations (`const`/`let`)**: Use `const` by default. Use `let` only when the binding will be reassigned. Never use `var`.
90
+ - Recommended: `const users = [];`
91
+ - **Null/Undefined Checks**: Use nullish coalescing (`??`) and optional chaining (`?.`) instead of `||` and manual checks.
92
+ - Recommended: `const name = user?.profile?.name ?? 'Anonymous';`
93
+ - **Object/Array Initialization**: Use destructuring, spread operators, and shorthand property names.
94
+ - Recommended: `const { id, name } = user;`
95
+ - **Equality**: Always use `===` and `!==`. Never use `==` or `!=`.
96
+
97
+ ---
98
+
99
+ ## 6. Commenting Conventions
100
+
101
+ - **JSDoc**: Public APIs and exported functions should use `/** ... */` JSDoc comments for IDE IntelliSense and documentation generation.
102
+ ```javascript
103
+ /**
104
+ * Fetches a user by their unique identifier.
105
+ * @param {number} id - The user's ID.
106
+ * @param {AbortSignal} [signal] - Optional signal to cancel the request.
107
+ * @returns {Promise<User>} The user object.
108
+ */
109
+ export async function getUserById(id, signal) { ... }
110
+ ```
111
+ - **Logical Comments**: Comments should explain "Why" the processing is done this way, not repeat "What" the code does.
112
+ - **TODO/FIXME**: Use `// TODO:` for planned improvements and `// FIXME:` for known issues.
@@ -0,0 +1,280 @@
1
+ # Modern JavaScript Patterns Guide
2
+
3
+ This document introduces recommended development patterns in ES6 through ES2025+, aiming to simplify code and improve reliability using modern syntax.
4
+
5
+ ## 1. Module and Declaration Patterns
6
+
7
+ ### 1.1 ESM Modules (ES6+)
8
+ **Recommendation**: Use `import`/`export` with named exports for tree-shaking compatibility.
9
+ ```javascript
10
+ // Named exports (preferred for libraries)
11
+ export function formatDate(date) { ... }
12
+ export function parseDate(str) { ... }
13
+
14
+ // Default export (preferred for single-purpose modules)
15
+ export default class UserService { ... }
16
+ ```
17
+
18
+ ### 1.2 Dynamic Import (ES2020+)
19
+ **Recommendation**: Lazy-load modules for code splitting and conditional loading.
20
+ ```javascript
21
+ const { Chart } = await import('./chart.js');
22
+ ```
23
+
24
+ ### 1.3 Arrow Functions vs Function Declarations
25
+ **Recommendation**: Use arrow functions for callbacks and short expressions. Use function declarations for top-level named functions that benefit from hoisting.
26
+ ```javascript
27
+ // Arrow functions for callbacks
28
+ const doubled = numbers.map(n => n * 2);
29
+
30
+ // Function declarations for top-level definitions
31
+ function processOrder(order) {
32
+ // ...
33
+ }
34
+ ```
35
+
36
+ ### 1.4 Logical Assignment (ES2021+)
37
+ **Recommendation**: Use logical assignment operators (`??=`, `||=`, `&&=`) to concisely update variables only when specific conditions are met.
38
+ ```javascript
39
+ // ??= (Nullish coalescing assignment)
40
+ user.role ??= 'viewer'; // Assigns 'viewer' only if user.role is null or undefined
41
+
42
+ // ||= (Logical OR assignment)
43
+ config.timeout ||= 5000; // Assigns 5000 if config.timeout is falsy (e.g., 0, '', null)
44
+
45
+ // &&= (Logical AND assignment)
46
+ state.isReady &&= verifyStatus(); // Updates state.isReady only if it is already truthy
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 2. Data Structures and Immutability
52
+
53
+ ### 2.1 Destructuring and Spread (ES6+)
54
+ **Recommendation**: Use destructuring to extract values and spread to create shallow copies.
55
+ ```javascript
56
+ // Object destructuring with renaming and defaults
57
+ const { name: userName, role = 'viewer' } = user;
58
+
59
+ // Shallow clone with override
60
+ const updated = { ...config, timeout: 5000 };
61
+
62
+ // Array spread
63
+ const combined = [...listA, ...listB];
64
+ ```
65
+
66
+ ### 2.2 Immutable Array Operations (ES2023+)
67
+ **Recommendation**: Use non-mutating array methods to avoid side effects.
68
+ ```javascript
69
+ const sorted = items.toSorted((a, b) => a.name.localeCompare(b.name));
70
+ const reversed = items.toReversed();
71
+ const updated = items.with(2, 'newValue');
72
+ ```
73
+
74
+ ### 2.3 Object Grouping (ES2024+)
75
+ **Recommendation**: Use `Object.groupBy()` instead of manual reduce-based grouping.
76
+ ```javascript
77
+ const grouped = Object.groupBy(users, user => user.role);
78
+ // { admin: [...], editor: [...], viewer: [...] }
79
+ ```
80
+
81
+ ### 2.4 Structured Cloning
82
+ **Recommendation**: Use `structuredClone()` for deep copies instead of `JSON.parse(JSON.stringify())`.
83
+ ```javascript
84
+ const deepCopy = structuredClone(originalObject);
85
+ ```
86
+
87
+ ### 2.5 Modern Iterables & Array Creation (ES6+)
88
+ **Recommendation**: Use `Array.from()` to convert iterable objects (like NodeList or arguments) into true arrays, and utilize its built-in mapping capability.
89
+ ```javascript
90
+ // Convert NodeList to Array and extract text content
91
+ const elements = document.querySelectorAll('.item');
92
+ const texts = Array.from(elements, el => el.textContent);
93
+
94
+ // Create an array of a specific length filled with values
95
+ const range = Array.from({ length: 5 }, (_, i) => i + 1); // [1, 2, 3, 4, 5]
96
+ ```
97
+
98
+ ### 2.6 String & Array Searching (ES6+)
99
+ **Recommendation**: Replace verbose `indexOf()` checks with `includes()`, `startsWith()`, `endsWith()`, and replace `filter()[0]` with `find()`.
100
+ ```javascript
101
+ // String checking
102
+ const url = 'https://example.com';
103
+ const isHttps = url.startsWith('https'); // Preferred over url.indexOf('https') === 0
104
+
105
+ // Array searching
106
+ const targetUser = users.find(u => u.id === 123); // Preferred over users.filter(...)[0]
107
+ const hasAdmin = users.some(u => u.role === 'admin'); // Checking existence
108
+ ```
109
+
110
+ ---
111
+
112
+ ## 3. Async Patterns and Promise Composition
113
+
114
+ ### 3.1 async/await (ES2017+)
115
+ **Recommendation**: Prefer `async`/`await` over `.then()` chains for readability and maintainability.
116
+ ```javascript
117
+ async function loadUserProfile(id) {
118
+ try {
119
+ const user = await fetchUser(id);
120
+ const posts = await fetchPosts(user.id);
121
+ return { user, posts };
122
+ } catch (err) {
123
+ throw new Error('Failed to load profile', { cause: err });
124
+ }
125
+ }
126
+ ```
127
+
128
+ ### 3.2 Promise Composition
129
+ **Recommendation**: Choose the right Promise combinator for the use case.
130
+ ```javascript
131
+ // All must succeed
132
+ const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
133
+
134
+ // All settle, handle individually
135
+ const results = await Promise.allSettled([taskA(), taskB()]);
136
+
137
+ // First to succeed
138
+ const fastest = await Promise.any([mirrorA(), mirrorB()]);
139
+ ```
140
+
141
+ ### 3.3 Deferred Promise (ES2024+)
142
+ **Recommendation**: Use `Promise.withResolvers()` for externally controlled promises.
143
+ ```javascript
144
+ const { promise, resolve, reject } = Promise.withResolvers();
145
+ setTimeout(() => resolve('done'), 1000);
146
+ const result = await promise;
147
+ ```
148
+
149
+ ### 3.4 Async Generators and Iteration (ES2018+)
150
+ **Recommendation**: Use async generators for streaming data processing.
151
+ ```javascript
152
+ async function* fetchPages(url) {
153
+ let nextUrl = url;
154
+ while (nextUrl) {
155
+ const response = await fetch(nextUrl);
156
+ const data = await response.json();
157
+ yield data.items;
158
+ nextUrl = data.nextPage;
159
+ }
160
+ }
161
+
162
+ for await (const page of fetchPages('/api/users')) {
163
+ processItems(page);
164
+ }
165
+ ```
166
+
167
+ ---
168
+
169
+ ## 4. Class Patterns and Encapsulation
170
+
171
+ ### 4.1 ES6 Classes
172
+ **Recommendation**: Use `class` syntax with clear inheritance and `super` calls.
173
+ ```javascript
174
+ class Animal {
175
+ constructor(name) {
176
+ this.name = name;
177
+ }
178
+
179
+ speak() {
180
+ return `${this.name} makes a sound.`;
181
+ }
182
+ }
183
+
184
+ class Dog extends Animal {
185
+ speak() {
186
+ return `${this.name} barks.`;
187
+ }
188
+ }
189
+ ```
190
+
191
+ ### 4.2 Private Fields and Methods (ES2022+)
192
+ **Recommendation**: Use `#` prefix for true encapsulation, replacing the underscore convention.
193
+ ```javascript
194
+ class Counter {
195
+ #count = 0;
196
+
197
+ increment() { this.#count++; }
198
+ get value() { return this.#count; }
199
+ }
200
+ ```
201
+
202
+ ### 4.3 Error Cause Chaining (ES2022+)
203
+ **Recommendation**: Preserve error context with the `cause` option.
204
+ ```javascript
205
+ try {
206
+ await initializeService();
207
+ } catch (err) {
208
+ throw new Error('Service initialization failed', { cause: err });
209
+ }
210
+ ```
211
+
212
+ ### 4.4 Explicit Resource Management (ES2025+)
213
+ **Recommendation**: Use the `using` keyword for automatic and deterministic cleanup of resources (like file handles, database connections, or subscriptions).
214
+ ```javascript
215
+ function processFile() {
216
+ using file = openFile('data.txt'); // Automatically closed when function exits
217
+ const data = file.read();
218
+ return data;
219
+ }
220
+
221
+ // Async disposal
222
+ async function fetchAndProcess() {
223
+ await using connection = await db.connect();
224
+ return connection.query('SELECT * FROM users');
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 5. Set and Iterator Patterns (ES2025+)
231
+
232
+ ### 5.1 Set Operations
233
+ **Recommendation**: Use native Set methods instead of manual implementations.
234
+ ```javascript
235
+ const setA = new Set([1, 2, 3]);
236
+ const setB = new Set([2, 3, 4]);
237
+
238
+ const union = setA.union(setB); // Set {1, 2, 3, 4}
239
+ const intersection = setA.intersection(setB); // Set {2, 3}
240
+ const difference = setA.difference(setB); // Set {1}
241
+ ```
242
+
243
+ ### 5.2 Iterator Helpers
244
+ **Recommendation**: Use lazy iterator methods for memory-efficient data processing.
245
+ ```javascript
246
+ const firstFiveEven = Iterator.from(hugeArray)
247
+ .filter(n => n % 2 === 0)
248
+ .take(5)
249
+ .toArray();
250
+ ```
251
+
252
+ ---
253
+
254
+ ## 6. Security and Performance
255
+
256
+ ### 6.1 Input Sanitization
257
+ **Recommendation**: Never use `eval()`, `innerHTML` with unsanitized input, or `new Function()` with user input.
258
+ ```javascript
259
+ // Safe DOM manipulation
260
+ element.textContent = userInput; // not element.innerHTML
261
+ ```
262
+
263
+ ### 6.2 AbortController for Resource Management
264
+ **Recommendation**: Use `AbortController` to cancel fetch requests, timers, and event listeners.
265
+ ```javascript
266
+ const controller = new AbortController();
267
+ const response = await fetch(url, { signal: controller.signal });
268
+ // Cancel if needed: controller.abort();
269
+ ```
270
+
271
+ ### 6.3 Avoiding Memory Leaks
272
+ **Recommendation**: Use `WeakRef` and `WeakMap` for caches, and always clean up event listeners and intervals.
273
+ ```javascript
274
+ // Use AbortController signal for automatic listener cleanup
275
+ const controller = new AbortController();
276
+ window.addEventListener('resize', handleResize, { signal: controller.signal });
277
+
278
+ // Cleanup all listeners at once
279
+ controller.abort();
280
+ ```