Skip to content

Caso real: verticals-subscription-ecommerce

Esta página analiza la implementación real de las seis herramientas en verticals-subscription-ecommerce, un front-end Nuxt 4 en producción. Sirve como referencia de “cómo queda esto montado de verdad” y como plantilla para proyectos nuevos.

ConceptoDetalle
FrameworkNuxt 4.2.1 / Vue 3.5.25
Gestor de paquetespnpm 10.11.0
EstilosTailwind CSS 3
TestsVitest 4
CMSStrapi (@nuxtjs/strapi)
  • Directory.husky/
    • Directory_/ generado por Husky
      • …
    • pre-commit typecheck + lint-staged
    • commit-msg commitlint
    • install.mjs legacy, ya no se usa
  • .lintstagedrc qué comando por extensión
  • .prettierrc reglas de formato
  • .stylelintrc.json reglas de CSS
  • eslint.config.js reglas de JS/TS/Vue (flat config)
  • commitlint.config.ts 3 líneas: importa la config compartida
  • package.json scripts y dependencias
  • Directory.vscode/
    • settings.json ajustes del editor
    • extensions.json extensiones recomendadas

Todas en devDependencies, como corresponde a herramientas que no llegan al bundle de producción:

package.json (extracto)
{
"devDependencies": {
"@alebat/default-alebat-config": "^1.1.0",
"@commitlint/cli": "20.1.0",
"@commitlint/config-conventional": "20.0.0",
"eslint": "9.36.0",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-prettier": "5.5.4",
"eslint-plugin-vue": "10.6.2",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "^8.49.0",
"vue-eslint-parser": "^10.2.0",
"husky": "9.1.7",
"lint-staged": "16.2.7",
"prettier": "3.7.3",
"stylelint": "16.26.1",
"stylelint-config-recommended-vue": "1.6.1",
"stylelint-config-standard": "39.0.1"
}
}
package.json
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"styles": "stylelint \"**/*.{vue,css}\"",
"styles:fix": "stylelint \"**/*.{vue,css}\" --fix",
"format": "prettier --write \"**/*.{js,ts,vue,json,css,md}\"",
"analyze": "nuxi typecheck",
"prepare": "husky"
}
}
ComandoQué hace
pnpm lintPasa ESLint por todo el proyecto y solo reporta.
pnpm lint:fixIgual, pero arregla lo que puede (incluido el formato de Prettier).
pnpm stylesPasa Stylelint por los .vue y .css.
pnpm styles:fixIgual, arreglando lo posible.
pnpm formatPrettier sobre todo el proyecto, incluidos .json y .md (que ESLint no toca).
pnpm analyzeComprobación de tipos con nuxi typecheck.
prepareAutomático tras pnpm install: instala los hooks de Husky.

Este es el archivo más particular de la implementación: no se limita a llamar a lint-staged, sino que antes ejecuta un typecheck completo del proyecto.

.husky/pre-commit
#!/bin/sh
# CONFIGURACIÓN OPTIMIZADA PARA TYPECHECK SIN SIGKILL
export NODE_OPTIONS="--max-old-space-size=24576 --max-semi-space-size=2048 --expose-gc"
export NUXT_TELEMETRY_DISABLED=1
# Crear archivo temporal usando mktemp o alternativa Windows
if command -v mktemp > /dev/null 2>&1; then
TEMP_FILE=$(mktemp)
else
TEMP_FILE="/tmp/typecheck_$$.txt"
fi
# TYPECHECK
echo "🔍 Ejecutando typecheck optimizado..."
npx nuxi typecheck 2>&1 | tee "$TEMP_FILE"
if grep -q "error" "$TEMP_FILE"; then
# imprime un banner ASCII gigante con la palabra ERROR
printf "Please execute the next command to see the errors in more detail: 'npx nuxi typecheck'\n\n"
printf "❌ Typecheck failed! Commit aborted. ❌\n\n"
rm "$TEMP_FILE" 2>/dev/null || true
exit 1
fi
rm "$TEMP_FILE" 2>/dev/null || true
# LINT-STAGED
echo "🔧 Ejecutando lint-staged..."
npx lint-staged --concurrent false --relative
echo "✅ Pre-commit completado exitosamente"
  1. NODE_OPTIONS — reserva hasta 24 GB de heap para Node (--max-old-space-size=24576, en megabytes). El typecheck de un Nuxt grande consume muchísima memoria y, sin este ajuste, el proceso muere con SIGKILL a mitad de camino. --expose-gc habilita el recolector de basura manual y --max-semi-space-size amplía el espacio de objetos jóvenes.

  2. NUXT_TELEMETRY_DISABLED=1 — evita la llamada de telemetría de Nuxt en cada commit.

  3. El archivo temporal — mktemp no existe en Git Bash de Windows en todas las instalaciones, así que hay un fallback a /tmp/typecheck_$$.txt ($$ es el PID, para que dos commits simultáneos no se pisen).

  4. npx nuxi typecheck | tee — tee cumple una doble función: muestra la salida en pantalla y la guarda en el archivo, para poder inspeccionarla después.

  5. grep -q "error" — si la salida contiene la palabra error, se aborta con exit 1, y Git cancela el commit.

  6. npx lint-staged --concurrent false --relative — solo si el typecheck ha pasado. Los dos flags están explicados en Husky y lint-staged: secuencial para que ESLint y Stylelint no escriban el mismo .vue a la vez, y rutas relativas por compatibilidad con Windows.

install.mjs: un archivo que ya no se usa legacy

Section titled “install.mjs: un archivo que ya no se usa ”
.husky/install.mjs
if (process.env.NODE_ENV === 'production' || process.env.CI === 'true') {
process.exit(0)
}
const husky = (await import('husky')).default
console.log(husky())

Este script existe para evitar que Husky se instale en producción o en CI, donde no hay commits que validar y husky puede no estar disponible. Pero el package.json tiene "prepare": "husky", no "prepare": "node .husky/install.mjs", así que el archivo no se ejecuta nunca. Es un resto de una configuración anterior; se puede borrar sin efecto alguno.

.husky/commit-msg
npx --no -- commitlint --edit "$1"

Y la configuración que valida, en tres líneas:

commitlint.config.ts
import { commitLintFront } from '@alebat/default-alebat-config'
export default commitLintFront

Al ser un front, usa commitLintFront: ámbito obligatorio pero libre. Ejemplos válidos en este proyecto:

✅ feat(checkout): añadido el resumen de suscripción
✅ fix(stripe): corregido el redirect tras el pago
✅ chore(release): release 1.1.0

El detalle de las reglas está en default-alebat-config.

El proyecto versiona su propio .vscode/, de modo que quien clone el repositorio recibe los ajustes ya hechos.

{
"recommendations": [
"Vue.volar",
"sdras.vue-vscode-snippets",
"usernamehw.errorlens",
"dbaeumer.vscode-eslint",
"xabikos.JavaScriptSnippets",
"esbenp.prettier-vscode",
"cipchk.cssrem",
"sibiraj-s.vscode-scss-formatter",
"stylelint.vscode-stylelint",
"YoavBls.pretty-ts-errors"
]
}

VS Code ofrece instalarlas al abrir el proyecto. Las tres imprescindibles para lo que cubre esta sección son dbaeumer.vscode-eslint, esbenp.prettier-vscode y stylelint.vscode-stylelint.

cipchk.cssrem merece mención aparte: convierte px a rem mientras escribes, que es justo lo que hace falta con la regla unit-allowed-list de Stylelint.

Resumen: dónde interviene cada herramienta

Section titled “Resumen: dónde interviene cada herramienta”
MomentoQué se ejecutaQué revisa
Al guardar en el editorExtensiones de ESLint / Stylelint (subrayado)Errores visibles al escribir
git commit → pre-commitnuxi typecheck, luego lint-stagedTipos de todo el proyecto; ESLint y Stylelint de los archivos en staging
git commit → commit-msgcommitlint --editEl mensaje del commit
A mano, cuando quieraspnpm lint, pnpm styles, pnpm formatTodo el proyecto
  1. Clonar el repositorio.

  2. Crear el .env a partir de .env.example y ejecutar pnpm configure:pkg, que genera el .npmrc necesario para descargar @alebat-education/ecom-components de GitHub Packages.

  3. pnpm install — instala dependencias y, mediante el script prepare, configura los hooks de Husky automáticamente.

  4. Verificar que los hooks están activos:

    .husky/_
    git config core.hooksPath
  5. Instalar las extensiones recomendadas cuando VS Code lo ofrezca.