## 2. Configuración del Entorno

### Herramienta de Formato

Para que el código de los proyectos en JS/TS/React/CualquierCompliantConEcmaScript tenga siempre el mismo formato sin importar quién lo escriba, usamos Prettier. Prettier es una herramienta opinionada, lo que significa que tiene su propio criterio para el formato del código, y como equipo, decidimos adoptarlo y respetarlo al pie de la letra

Aquí no hay debate: si a Linus Torvalds le gusta la indentación de 8 espacios y a ti te gusta la de 4, pero Prettier dice que 2, nos vamos con 2. No hay discusión, Prettier es palabra sagrada. Esto nos libera de discusiones sobre estilo y nos permite enfocarnos en lo que importa.

Puedes integrarlo en tu editor con los plugins oficiales. Si no, de seguro habremos dispuesto de un script dentro del package.json para darle formato al código: usualmente `<npm/pnpm/yarn/administrador de paquetes> format` harán ese trabajo.

### La seguridad antes que la policía

Prettier es nuestra brújula de estilo y ESLint es quien evita que la caguemos antes de tiempo con pendejadas. Su propósito es detectar problemas de calidad, consistencia y posibles errores antes de que lleguen al código. Nuestra configuración combina las recomendaciones estándar de Airbnb, las de react y la ultima palabra la da prettier para evitar conflictos en las reglas...

```typescript
extends: [
    "airbnb",
    "airbnb-typescript",
    "plugin:react-hooks/recommended",
    "plugin:prettier/recommended",
],
```

Pero en esta área nuestro equipo si tiene opiniones y acuerdos que modifican las reglas base y responden a cómo vemos el código y las experiencias que hemos tenido.

#### Algunas de nuestras reglas clave

**Evitamos la anidación excesiva**. La regla `no-nested-ternary` nos prohíbe usar operadores ternarios dentro de otros, ya que reducen la legibilidad y aumentan la carga cognitiva.

**Corchetes, siempre**, `curly` nos obliga a usar llaves en todos los bloques de control, como en los `if` y `for`. Así, evitamos errores al añadir más líneas de código en el futuro.

**¡Exportaciones nombradas, siempre!** Con `import/no-default-export` nos aseguramos de que cada archivo solo tenga exportaciones con nombre. Esto facilita el autocompletado y reduce los conflictos de nombres.

**En React, componentes declarativos, funciones internas de flecha,** los componentes de React deben ser declaraciones de función (`function Componente() {}`), lo que ayuda a la legibilidad y la depuración. Sin embargo, para callbacks y funciones internas del componente, preferimos las funciones flecha (`() => {}`) por su sintaxis concisa y su manejo más predecible de `this`.

**En TypeScript...** funciones de flecha, para evitarnos dolores de cabeza con el this, aunque function sea más idiomática.

#### Nuestro ruleset

```typescript
"rules": {
    // === REGLAS DE REACT Y HOOKS ===
    // Desactiva la regla que requiere importar 'React' en cada archivo con JSX. Esto es estándar en React 17+.
    "react/react-in-jsx-scope": "off",
    // Desactiva la restricción de 'prop spreading' (ej. <Componente {...props} />).
    "react/jsx-props-no-spreading": "off",
    // Define el estilo de los componentes: `function declaration` para los nombrados y `arrow function` para los anónimos.
    "react/function-component-definition": [
      "error",
      {
        "namedComponents": "function-declaration",
        "unnamedComponents": "arrow-function"
      }
    ],
    // Desactiva la regla que exige definir valores por defecto para props opcionales. Esto lo manejamos con TypeScript, acá lo desactivamos para evitar conflicto de reglas
    "react/require-default-props": "off",

    // === REGLAS DE IMPORTACIÓN ===
    // Evita ciclos de importación (dependencias circulares).
    "import/no-cycle": "error",
    // Asegura que las importaciones de módulos locales no tengan extensión de archivo.
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "ts": "never",
        "tsx": "never",
        "js": "never",
        "jsx": "never"
      }
    ],
    // Prohíbe todas las exportaciones 'default' en la base de código.
    "import/no-default-export": "error",
    // Desactiva la preferencia por exportaciones default que asigna Airbnb para evitar conflictos.
    "import/prefer-default-export": "off",
    // Solo permite dependencias de desarrollo en archivos de configuración y test.
    "import/no-extraneous-dependencies": [
      "error",
      {
        "devDependencies": [
          "**/*.test.{ts,tsx}",
          "**/*.spec.{ts,tsx}",
          "vite.config.ts",
          "jest.config.{js,ts}"
        ]
      }
    ],

    // === REGLAS DE TYPESCRIPT ===
    // Prefiere la sintaxis concisa para los tipos de función.
    "@typescript-eslint/prefer-function-type": "error",
    // Muestra un error si una variable no es usada, ignorando las que empiezan con un guion bajo '_'.
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "argsIgnorePattern": "^_",
        "varsIgnorePattern": "^_"
      }
    ],
    // Prefiere las importaciones de tipo (`import type`) para claridad.
    "@typescript-eslint/consistent-type-imports": [
      "error",
      {
        "prefer": "type-imports"
      }
    ],
    // Desactiva la exigencia de comas colgantes para evitar conflicto con Prettier.
    "@typescript-eslint/comma-dangle": "off",
    // Desactiva las comillas específicas para evitar conflicto con Prettier.
    "@typescript-eslint/quotes": "off",

    // === REGLAS DE ESTILO Y LÓGICA GENERAL ===
    // Prohíbe el uso de importaciones con rutas relativas (`./` o `../`), forzando el uso de alias de ruta.
    "no-restricted-imports": [
        "error",
        {
          "patterns": [
            {
              "group": ["./", "../"],
              "message": "The relative imports are not allowed. Please use path aliases instead."
            }
          ]
        }
    ],
    // Define el estilo de las funciones.
    "func-style": [
      "error",
      "declaration",
      {
        "allowArrowFunctions": true
      }
    ],
    // Obliga a usar `arrow functions` para callbacks.
    "prefer-arrow-callback": [
      "error",
      {
        "allowNamedFunctions": true,
        "allowUnboundThis": true
      }
    ],
    // Prohíbe el uso de operadores ternarios anidados.
    "no-nested-ternary": "error",
    // Obliga a usar llaves en todos los bloques de control, (if, for and shit)
    "curly": "error",
    // Permite `console.warn` y `console.error` pero no `console.log`.
    "no-console": [
      "warn",
      {
        "allow": ["warn", "error"]
      }
    ],
    // Prohíbe `var` y exige `const` o `let`.
    "no-var": "error",
    // Exige `const` si la variable no se reasigna.
    "prefer-const": "error"
  }
```

---
[Anterior: Introducción](./1-introduccion.md) | [Volver al menú principal](../frontend-structure.md) | [Siguiente: Convenciones Generales](./3-convenciones-generales.md)
