Frontend Tools

website·Indexed 30 days ago

https://lehoczky.github.io/frontend-tools/

A collection of web development utilities including a PX to REM converter, a Fluid CSS calculator with @lehoczky/postcss-fluid support, a timer, and a Web Style Guide for maintaining consistent codebase standards.

Tokens
3.3K
Snippets
31
Records
31
Agent score
25%

What's inside Frontend Tools

  1. Use explanatory variables for intermediate values

    When dealing with complex expressions or regex matches, use intermediate variables to give meaning to the values before passing them to functions.
    const address = "One Infinite Loop, Cupertino 95014"
    const cityZipCodeRegex = /^[^,\]+[,\\]s]+(.+?)\\s*(\d{5})?$/
    
    // Good: Use explanatory variables
    const [_, city, zipCode] = address.match(cityZipCodeRegex) || []
    saveCityZipCode(city, zipCode)
  2. Declare variables using const and let

    Avoid using var because it is function-scoped, which can lead to bugs. Use const and let as they are block-scoped. Prefer const for variables that are never reassigned to reduce cognitive load and improve maintainability.
    // Bad
    var value = 42
    
    // Good
    const foo = 42 // Use if "foo" never changes
    let bar = 42    // Use if "bar" is ever assigned into later
  3. Name variables for clarity and readability

    Use meaningful, pronounceable, and complete words for variable names to avoid 'mental mapping' and confusion. Avoid abbreviations unless they are conventional (e.g., i and j for loop indexes, or req, res, ctx in Express.js). Additionally, avoid adding redundant context to variable names if the parent object already provides that context.
    // Bad: Abbreviation/Non-pronounceable
    const yyyymmdstr = moment().format("YYYY/MM/DD")
    
    // Good: Meaningful
    const currentDate = moment().format("YYYY/MM/DD")
    
    // Bad: Unneeded context
    const car = {
      carMake: "Honda",
      carModel: "Accord"
    }
    
    // Good: Clean context
    const car = {
      make: "Honda",
      model: "Accord"
    }
  4. Encapsulate complex conditionals in functions

    Avoid placing complex logic directly within if statements. Instead, encapsulate the conditional logic into a named function that describes the intent of the check. This improves readability and makes the code easier to maintain.
    // Bad
    if (fsm.state === "fetching" && isEmpty(listNode)) {
      // ...
    }
    
    // Good
    function shouldShowSpinner(fsm, listNode) {
      return fsm.state === "fetching" && isEmpty(listNode);
    }
    
    if (shouldShowSpinner(fsm, listNode)) {
      // ...
    }
  5. Avoid using wrapper classes for organization

    Do not use wrapper classes or namespaces solely to group utility functions or constants. Wrapper classes increase cognitive complexity without providing structural improvements, as modules already provide organization. Additionally, wrapper classes hinder IDE auto-completion for static properties and make it more difficult for static analysis tools to identify unused variables. As an alternative, use import * as ... to group module exports into a single object. This practice is enforced via the no-extraneous-class ESLint rule.
    // Instead of a wrapper class, use named exports in a module
    // and import them as a namespace:
    import * as Utils from './utils';
  6. Handle long strings and interpolation

    Avoid breaking long strings across multiple lines using concatenation or backslashes, as this hinders searchability. When building strings programmatically, use template literals instead of the + operator or .join().
    // Bad: Concatenation
    function sayHi(name: string) {
      return "How are you, " + name + "?"
    }
    
    // Good: Template string
    function sayHi(name: string) {
      return `How are you, ${name}?`
    }
  7. Define single-purpose functions without boolean flags

    Avoid using boolean flags as function parameters to control different code paths. Instead, split the logic into separate, specialized functions to ensure each function does only one thing.
    // Good
    function createFile(name: string) {
      fs.create(name)
    }
    
    function createTemporaryFile(name: string) {
      createFile(`./temp/${name}`)
    }
  8. Use Number.isNaN() for strict NaN checking

    Prefer Number.isNaN() over the global isNaN(). The global isNaN() function checks if a value cannot be coerced to a number, which leads to false positives for strings, undefined, and objects. Number.isNaN() only returns true if the value is exactly NaN.
    isNaN("blabla") // true (coerced to NaN)
    Number.isNaN("blabla") // false (not actually the value NaN)
  9. Generate fluid typography using CSS clamp()

    Use the Fluid CSS calculator to generate a clamp() function that allows font sizes or spacing to scale fluidly between a minimum and maximum value based on the viewport width. The calculator takes the following inputs:

    • Units: REM or PX
    • Range: The minimum and maximum target values (e.g., from 1rem to 1.5rem)
    • Viewport: The viewport width range where the scaling should occur.

    The resulting output is a CSS clamp() function, such as clamp(1rem, 0.75rem + 0.625vw, 1.5rem), which ensures the value never drops below the minimum or exceeds the maximum.

    /* Example of a fluid value generated by the calculator */
    font-size: clamp(1rem, 0.75rem + 0.625vw, 1.5rem);
  10. Avoid magic numbers using explanatory constants

    Do not use numeric literals (magic numbers) without explanation. Assign them to named constants to make the code maintainable. For array indexing, while 0 or -1 are acceptable, using utility functions like those from lodash-es is preferred.
    // Bad
    function getTotal(subtotal: number) {
      const total = subtotal + 9.95
      return total + total * 0.1
    }
    
    // Good
    const SHIPPING_FEE = 9.95
    const SALES_TAX = 0.1
    
    function getTotal(subtotal: number) {
      const total = subtotal + SHIPPING_FEE
      return total + total * SALES_TAX
    }