julien bba1703622
CI / check (push) Successful in 3m15s
CI / commits (push) Has been skipped
CI / scan (push) Successful in 1m25s
CI / a11y (push) Successful in 2m31s
Docs site / build (push) Successful in 4m2s
CI / perf (push) Successful in 5m0s
fix(deps): scope the vite < 7 override to vitepress so @angular/build keeps vite 8 (#163)
## Summary

Hotfix on the override added in [#161](#161). The unconditional `"vite": ">=6.4.2 <7"` was too broad — it downgraded **every** vite consumer in the workspace to vite 6.4.2, including `@angular/build@21.2.11`. Angular's dev-server plugin (`angular-memory-plugin.js > loadViteClientCode`) monkey-patches Vite's client error-overlay code; the patch targets vite 8.x's internal layout, fails against vite 6, and the home page blank-screens with:

```
[vite] Internal server error: Failed to update Vite client error overlay text.
  at loadViteClientCode (angular-memory-plugin.js:140:31)
```

…on the very first request to `pnpm nx serve portal-shell`.

## Fix

One-line change in [`package.json`](package.json) → `pnpm.overrides`:

```diff
- "vite":          ">=6.4.2 <7",
+ "vitepress>vite": ">=6.4.2 <7",
```

pnpm's `parent>child` selector syntax scopes the override to vitepress's transitive resolution only. Other vite consumers (Angular, Nx, Vitest, the analog plugin) follow their own peer constraints and resolve to vite 8.0.13 again.

## Resolution after the fix

| Consumer | vite version | Why |
| --- | --- | --- |
| `vitepress 1.6.4` | **6.4.2** | Override target — keeps VitePress 1.x off rolldown-vite |
| `@angular/build 21.2.11` | **8.0.13** | Restored; its dev-server plugin needs vite 8's client layout |
| `@nx/vite`, `@analogjs/vite-plugin-angular`, Vitest | **8.0.13** | Restored |
| `@vitejs/plugin-basic-ssl` (analog transitive) | 7.3.2 | Its own peer range; HTTPS-cert helper only, not the dev-server host. Doesn't affect us. |

## Why this regression didn't surface in #161's CI

The `docs-site.yml` workflow and `pnpm exec nx run-many -t lint test build` exercise the **production build** paths. Vite 6 ↔ Angular-build 21.2's monkey-patch incompatibility is a **dev-server-only** failure (the prod Rollup pipeline doesn't go through `loadViteClientCode`). CI couldn't have caught it; manual `nx serve portal-shell` is the only repro path. Lesson logged.

## Test plan

- [x] `pnpm install` — clean. Lockfile diff confirms: vite 6.4.2 only under vitepress, vite 8.0.13 restored everywhere else.
- [x] `pnpm audit --audit-level=moderate` — no known vulnerabilities.
- [x] `pnpm docs:build` — ~9.5 s, Mermaid still renders in ADR-0009's HTML (regression fence passes).
- [x] `pnpm exec nx run-many -t lint test build --projects=portal-shell,portal-admin,portal-bff,shared-ui,shared-state,feature-auth` — green.
- [x] **`pnpm nx serve portal-shell`** — boots cleanly, `curl http://localhost:4200/` returns HTTP 200 with the SPA shell, no `loadViteClientCode` error in the dev log. (This is the path that broke.)
- [ ] **Manual smoke (the user's repro)** — `pnpm nx serve portal-shell`, open the home page in a browser, confirm:
  - No "Failed to update Vite client error overlay text" in the browser DevTools console.
  - Page renders; navigating to `/accessibility`, `/profile` works.
  - Theme switcher in the footer toggles light / dark / system; locale switcher likewise.

## Notes for the reviewer

- **Lesson on override scoping**: the version-selector form (`"package@<vuln-range>": "patched"`) is the safest default — it only kicks in for the vulnerable range. The unconditional form (`"package": "<range>"`) is a sledgehammer and should be reserved for cases where the version-selector form genuinely can't express the intent (as was the case in #161 where the resolved version was already past the vulnerable range, so the selector was a no-op). When the unconditional form is needed, **always scope to a parent** (`"parent>package": …`) to avoid the workspace-wide blast radius.
- **No documentation change in this PR**: development.md's "Transitive vulnerabilities — `pnpm.overrides`" subsection (from #160) is still accurate. A follow-up edit could add a "scope to a parent when possible" sentence; not blocking.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #163
2026-05-16 02:07:43 +02:00

Documentation index

This is the entry point to all project documentation. It is maintained automatically: any addition, rename, or removal of a .md file under docs/ must be reflected here in the same change.

Conventions

  • Documentation is written in English.
  • One topic per file. Group related files into a folder when there are three or more.
  • Cross-reference with relative links so they keep working in GitHub, IDEs, and exported sites.
  • For architectural decisions, do not add them here — they belong in decisions/ as MADR 4.0.0 ADRs.

Sections

Daily development

  • development.md — repo layout, prerequisites, initial setup, daily commands, observability dev-loop (Jaeger UI, log ↔ trace correlation), dependency updates (Renovate), conventional commit cycle. Day-to-day reference for working on the project.

Architecture

  • architecture.md — cross-cutting Mermaid diagrams: C4 system context, C4 containers, Nx module boundaries, CI/CD pipeline. Single-decision diagrams (auth sequence, ERD, etc.) live inline in their ADR.

Onboarding & environment

Setup guides for new contributors:

Operations & runbooks

Empty — to be populated when we deploy.

Security, performance, accessibility

Empty — placeholders to be filled with rationale docs alongside their corresponding ADRs.

S
Description
No description provided
Readme 42 MiB
Languages
TypeScript 85.3%
JavaScript 5.4%
SCSS 4.3%
HTML 3.9%
Shell 0.8%
Other 0.3%