Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions docs/architecture/technical-debt.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,29 @@ What the gate had been hiding — each of these is a live defect, not a type-ann

## [TD-008] Two Major Versions of Vite in the Same Tree

- **Status**: Confirmed
- **Status**: **Resolved** (2026-08-10)
- **Severity**: Medium
- **Component**: `src/package-lock.json`, `src/apps/ums.web-app/package.json`
- **Description**: `npm ls vite` reports `vite@6.4.3` pinned locally by `app-web` and `vite@8.1.5` hoisted to the workspace root, pulled by `@vitejs/plugin-react`, `vitest@4.1.7` and the Storybook 10 builder. The build runs the local one (`npx vite --version` → 6.4.3) and the pairing with `@vitejs/plugin-react@5.2.0` is supported (its peer range covers `^6`), so this is not currently breaking anything at runtime.
- **How it surfaced**: TD-004. With the typecheck finally running, `tsconfig.node.json` failed because `@vitejs/plugin-react`'s types resolve `vite` to the hoisted 8.1.5 while `defineConfig` comes from the local 6.4.3, and `Plugin<any>` from one is not assignable to the other.
- **Interim measure**: `tsconfig.node.json` maps `vite` to the app's own copy — the one that actually builds — so the typecheck describes what runs. The mapping is a statement about resolution, not a silencer: it does not hide the duplication.
- **Impact**: the test runner and every plugin are compiled against a different major than the bundler that produces `dist/`. Nothing observable today; it is the kind of skew that produces an unreproducible failure later.
- **Suggested resolution**: converge on one major. `@vitejs/plugin-react@5.2.0` and `vitest@4.1.7` both accept 8, so raising the `app-web` pin is the smaller move — but it is a bundler major bump and deserves its own change, its own build verification and its own rollback story, not a corner of a type-cleanup branch.
- **Caveat**: this monorepo's `package-lock.json` must not be regenerated from scratch (it drops transitive deps); reconcile against the existing lock.
- **Description**: `npm ls vite` reported `vite@6.4.3` pinned locally by `app-web` and `vite@8.1.5` hoisted to the workspace root, pulled by `@vitejs/plugin-react`, `vitest@4.1.7` and the Storybook 10 builder. The build ran the local one (`npx vite --version` → 6.4.3), so the test runner and every plugin were compiled against a different major than the bundler that produced `dist/`.
- **How it surfaced**: TD-004. With the typecheck finally running, `tsconfig.node.json` failed because `@vitejs/plugin-react`'s types resolved `vite` to the hoisted 8.1.5 while `defineConfig` came from the local 6.4.3, and `Plugin<any>` from one is not assignable to the other.

### Resolution

`app-web` now pins `vite@8.1.5`, the version everything else had already converged on. One vite in the tree; the interim `paths` mapping in `tsconfig.node.json` is removed, so the typecheck once again describes the real resolution rather than a stated one.

Two things made the bump less mechanical than the version numbers suggest:

- **The lockfile kept replaying the old copy.** `apps/ums.web-app/node_modules/vite → 6.4.3` survived every `npm install`, including `npm install vite@8.1.5 --workspace=app-web`, which reported "up to date" and changed nothing. The stale entry had to be removed from `package-lock.json` by hand and the tree reinstalled. Regenerating the lock was not an option — this monorepo's lock drops transitive dependencies when rebuilt from scratch.
- **Vite 8 replaces rollup with rolldown.** The `manualChunks` function in `vite.config.ts` is a rollup-era option; it survives the swap and the named chunks (`vendor-react`, `zod`, the three schema bundles) still come out as declared. `build.target` was already pinned to `es2020`, so vite 7's default-target change never applied here.

### Storybook was already broken, and it is fixed here

Verifying the bump against Storybook — one of the packages that had pulled vite 8 in the first place — found `storybook build` failing. It fails **identically on vite 6**, checked by restoring the pre-bump tree: `.storybook/preview.ts` imported `../src/presentation/shared/theme/globals.css`, a path that does not exist anywhere in this repo (the global stylesheet is `src/index.css`). Storybook has been unbuildable since the resync and nothing in CI builds it, so nobody found out.

Fixed here rather than filed separately, because otherwise TD-008's verification would read "could not check the one pairing this change actually alters." Also removed from `.storybook/main.ts`: `@storybook/addon-essentials` and `@storybook/addon-interactions`, absorbed into the core in Storybook 9 and reported as unresolvable on every start since.

- **Verified**: typecheck 0, vitest 1697/1697, `vite build` OK with the chunk layout intact, dev server serves 200, `vite preview` serves the built bundle, `storybook build` OK (broken before this change, on both majors), eslint 0 errors.
- **Node floor**: vite 8 requires `^20.19.0 || >=22.12.0`. CI pins `node-version: 22`, which resolves well past 22.12.

---

Expand Down
1 change: 1 addition & 0 deletions src/apps/ums.web-app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
dist
dist-ssr
storybook-static
*.local

# Editor directories and files
Expand Down
4 changes: 3 additions & 1 deletion src/apps/ums.web-app/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-essentials', '@storybook/addon-interactions', '@storybook/addon-docs'],
// Storybook 10 absorbió `addon-essentials` y `addon-interactions` en el núcleo (v9);
// declararlos solo producía dos avisos de «no lo encuentro» en cada arranque.
addons: ['@storybook/addon-docs'],
framework: {
name: '@storybook/react-vite',
options: {},
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ums.web-app/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Preview } from '@storybook/react';
import '../src/application/i18n/translations';
import '../src/presentation/shared/theme/globals.css';
import '../src/index.css';

const preview: Preview = {
parameters: {
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ums.web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"tailwindcss": "3.4.19",
"typescript": "5.6.2",
"typescript-eslint": "8.60.1",
"vite": "6.4.3",
"vite": "8.1.5",
"vitest": "4.1.7"
},
"msw": {
Expand Down
17 changes: 1 addition & 16 deletions src/apps/ums.web-app/tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,7 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,

/*
* El árbol tiene DOS vite: esta app fija 6.4.3 en local y npm izó 8.1.5 a la raíz del
* workspace (lo arrastran Storybook y vitest). El binario que construye es el local —
* `npx vite --version` → 6.4.3— pero los tipos de @vitejs/plugin-react resolvían al izado, y
* `Plugin<any>` de un vite no es asignable al del otro: el typecheck de esta configuración
* fallaba por una discrepancia que no existe en ejecución.
*
* Aquí se le dice al comprobador cuál es el vite de esta app, que es el que corre.
* La duplicación en sí queda registrada como TD-008.
*/
"baseUrl": ".",
"paths": {
"vite": ["./node_modules/vite"]
}
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
Loading
Loading