UNPKG

eslint-config-styleguidejs

Version:
249 lines (179 loc) 8.6 kB
# ESLint Configuration Best Practices This document explains how our ESLint configuration aligns with modern JavaScript and TypeScript best practices. ## Core Principles Our ESLint configuration is built around several core principles that reflect modern JavaScript and TypeScript development: 1. **Type Safety**: Leveraging TypeScript's static type system to catch errors at compile time 2. **Modern Syntax**: Encouraging ES6+ features and patterns 3. **Readability**: Prioritizing code that is easy to read and understand 4. **Consistency**: Enforcing consistent style and patterns across the codebase 5. **Maintainability**: Avoiding patterns that make code difficult to maintain or refactor ## Psychological Benefits of Our Spacing Rules Our configuration enforces no spaces inside object literals and array brackets. This approach offers several cognitive and psychological benefits: ### Visual Cohesion ```js // Without spaces - objects and arrays are perceived as cohesive units const user = {name: 'John', age: 30}; const points = [10, 20, 30]; // With spaces - creates visual fragmentation const user = { name: 'John', age: 30 }; const points = [ 10, 20, 30 ]; ``` When brackets and braces are treated as part of the data structure they contain (without spaces), the brain processes them as a single cohesive unit. This reduces cognitive load by treating objects and arrays as atomic entities rather than collections of separate elements. ### Alignment with Syntax Structures ```js // Consistent treatment of all bracket types function process({id, name}) { // object destructuring return [id, name]; // array literal } // Inconsistent visual treatment function process({ id, name }) { return [ id, name ]; } ``` Our no-space approach creates visual consistency with other bracket-like structures in JavaScript (function calls, control structures), strengthening the mental model of how code is structured. ### Reduced Visual Noise ```js // Less visual noise - easier to scan const config = { user: {name: 'John', role: 'admin'}, settings: {theme: 'dark', notifications: {email: true, push: false}} }; // More visual noise - harder to scan const config = { user: { name: 'John', role: 'admin' }, settings: { theme: 'dark', notifications: { email: true, push: false } } }; ``` Each space adds visual noise to the code. With nested structures, this noise compounds quickly, making it harder for the brain to filter out irrelevant information and focus on the content. ### Muscle Memory and Typing Efficiency Consistently typing without spaces between brackets builds muscle memory, making coding more fluid and reducing the cognitive overhead of style decisions. This consistency extends to IDEs and code formatters, creating a seamless experience across tools. ### Psychological Anchoring The absence of spaces creates stronger "anchoring points" for the eyes when scanning code. The brain can quickly identify the boundaries of data structures without having to process extra whitespace, making code navigation more efficient. ## Key Best Practices ### Modern JavaScript Features ```js // Prefer const for variables that aren't reassigned const user = {name: 'John'}; // ✅ let user = {name: 'John'}; //unless reassigned // Use arrow functions for cleaner syntax and lexical this const getName = () => user.name; // ✅ function getName() { return user.name; } // ❌ unless needed for specific reasons // Use template literals for string concatenation const greeting = `Hello, ${user.name}!`; // ✅ const greeting = 'Hello, ' + user.name + '!'; //``` Rules enforcing these practices: - `prefer-const`: Encourages using `const` for variables that aren't reassigned - `prefer-arrow-callback`: Promotes arrow functions over function expressions - `prefer-template`: Encourages template literals over string concatenation - `no-var`: Prevents using the outdated `var` keyword ### Object and Array Handling ```js // Use object shorthand const name = 'John'; const user = {name}; // ✅ const user = {name: name}; // ❌ // Use object destructuring const {name, age} = user; // ✅ const name = user.name; const age = user.age; // ❌ // Use spread for object copying const userCopy = {...user}; // ✅ const userCopy = Object.assign({}, user); //``` Rules enforcing these practices: - `object-shorthand`: Encourages object property shorthand - `prefer-destructuring`: Promotes destructuring for objects and arrays - `no-restricted-properties`: Discourages `Object.assign` in favor of spread syntax ### Error Prevention ```js // Use strict equality checks if (value === null) {} // ✅ if (value == null) {} // ❌ // Avoid unintentional type coercion const sum = 1 + Number(value); // ✅ const sum = 1 + +value; //``` Rules enforcing these practices: - `eqeqeq`: Requires strict equality operators (`===` and `!==`) - `no-implicit-coercion`: Prevents shorthand type conversions - `no-unused-vars`: Catches variables that are declared but never used ### TypeScript Best Practices ```ts // Use explicit return types for functions function getData(): Promise<Data> {} // ✅ function getData() {} // ❌ for public APIs // Consistent type assertions const user = data as User; // ✅ const user = <User>data; // ❌ // Proper spacing in type annotations const name: string = 'John'; // ✅ const name : string = 'John'; //``` Rules enforcing these practices: - `@typescript-eslint/consistent-type-assertions`: Enforces consistent type assertion style - `@typescript-eslint/naming-convention`: Ensures consistent naming for different types of symbols - `@stylistic/type-annotation-spacing`: Enforces consistent spacing in type annotations ### Module System ```js // Organized imports import React, {useState} from 'react'; import {debounce} from 'lodash'; import {User} from './types'; import {fetchUser} from './api'; // Explicit file extensions import {Button} from './components/Button.js'; import styles from './styles.css'; ``` Rules enforcing these practices: - `import/order`: Groups and sorts import statements - `import/no-cycle`: Prevents circular dependencies - `import/extensions`: Requires file extensions for certain file types ### Code Style and Formatting ```js // Consistent spacing function add(a, b) { // ✅ function add( a,b ){} // ❌ // Consistent quotes const name = 'John'; // ✅ const name = "John"; // ❌ // Consistent semicolons const value = 42; // ✅ const value = 42 // ❌ // No spaces inside object literals const user = {name: 'John'}; // ✅ const user = { name: 'John' }; // ❌ // No spaces inside array brackets const items = [1, 2, 3]; // ✅ const items = [ 1, 2, 3 ]; //``` Rules enforcing these practices: - `indent`: Ensures consistent indentation (2 spaces) - `quotes`: Enforces single quotes for strings - `semi`: Requires semicolons at the end of statements - `object-curly-spacing`: No spaces inside object literals - `array-bracket-spacing`: No spaces inside array brackets ## React Best Practices ```jsx // Functional components const Button = ({onClick, children}) => ( // ✅ <button onClick={onClick}>{children}</button> ); // Hooks dependencies useEffect(() => { fetchData(userId); }, [userId]); // ✅ including all dependencies ``` Rules enforcing these practices: - `react/jsx-uses-react`: Optimizes for the new JSX transform - `react/react-in-jsx-scope`: Allows omitting React import with new JSX transform - `react-hooks/rules-of-hooks`: Enforces Rules of Hooks - `react-hooks/exhaustive-deps`: Ensures all dependencies are properly declared ## Benefits of These Practices 1. **Improved Code Quality**: Catching potential bugs and anti-patterns early 2. **Enhanced Developer Experience**: Consistent codebase is easier to work with 3. **Better Performance**: Encouraging patterns that align with JavaScript engine optimizations 4. **Future-Proofing**: Aligning with the direction of JavaScript and TypeScript evolution 5. **Team Efficiency**: Reducing time spent on code reviews for style and formatting issues ## Conclusion Our ESLint configuration is designed to enforce modern best practices while maintaining a balance between strictness and flexibility. The rules are carefully chosen to encourage patterns that lead to more maintainable, readable, and robust code, while avoiding unnecessary restrictions that might impede development velocity. By following these practices, we ensure our codebase remains high-quality, consistent, and aligned with the evolving JavaScript and TypeScript ecosystems.