64 lines
5.4 KiB
Markdown
64 lines
5.4 KiB
Markdown
# Proposal — Migrate @suaveplan/test-vite to genesis
|
|
|
|
- **Design**: ./design.md
|
|
- **Spec delta**: ./specs/test-vite/spec.md
|
|
|
|
## Why
|
|
|
|
Upstream `@suaveplan/test-vite` (`/mnt/s/web/suaveplan/packages/browser/test-vite/`) ships as a one-symbol stub (`export const test = "hi"`) despite extensive README copy describing planned factories (`createViteLibraryConfig`, `createVitestConfig`, `setupBrowserEnvironment`, tree-shake validator, bundle-size snapshot, custom matchers). The genesis `enterprise/test-vite.md` audit calls this "the kind of scaffolding CLAUDE.md explicitly forbids" and lays out the full enterprise scope. Every genesis browser-tier package currently rewrites a near-identical `vite.config.ts`/`vitest.config.ts` pair by hand; this package owns those factories and the WSL2 safety defaults documented in `CLAUDE.md` ("Vitest / WSL2").
|
|
|
|
## What
|
|
|
|
Land `@suaveplan/test-vite@0.1.0` at `packages/devtools/tooling/test-vite/` with these feature modules (one folder per feature, sibling `.md` per implementation file):
|
|
|
|
- `vite-library-config/` — `createViteLibraryConfig(opts)` factory producing a `UserConfig` for internal library packages: `vite-plugin-dts`, ESM-first output, `preserveModules: true` tree-shaking, `external` auto-extended with `@suaveplan/*` + `/^node:/` + `tslib`.
|
|
- `vite-app-config/` — `createViteAppConfig(opts)` factory for consumer apps: hashed asset names, env-prefix declaration, optional framework plugin slot.
|
|
- `vitest-config/` — `createVitestConfig(opts)` factory: `pool: 'forks'`, Istanbul provider, `setupFiles`, 100/100/100/100 thresholds, `fileParallelism` switch.
|
|
- `vitest-browser-config/` — `createVitestBrowserConfig(opts)` factory: Playwright provider, `fileParallelism: false`, multi-browser matrix.
|
|
- `browser-environment/` — `setupBrowserEnvironment(opts)` runtime helper installing happy-dom / jsdom shims (`localStorage`, `matchMedia`, `ResizeObserver`, `IntersectionObserver`, `crypto.webcrypto`).
|
|
- `tree-shake-validator/` — `verifyTreeShake({ entry, expectedSymbols, bundle })` that statically parses a bundle (Rollup-emitted text) and asserts the emitted exports match the allow-list.
|
|
- `bundle-size-snapshot/` — `snapshotBundleSize({ entry, snapshot, fs })` that compares a bundle byte-size against a snapshot file and enforces a configurable budget tolerance.
|
|
- `port-allocator/` — `allocatePort` / `releasePort` backed by an injectable lock-file store; fixes WSL2 parallel-Storybook/Playwright collisions.
|
|
- `hmr-tester/` — `withHMR({ server, edit, expectEvents })` round-trips a Vite HMR cycle via an injectable server adapter (no real network).
|
|
- `matchers/` — `expect.extend` matchers: `toBeAccessibleNode`, `toMatchDataURL`, `toHaveValidCSSVars`. Universal (work in node + jsdom + happy-dom).
|
|
- `error-codes/` — `TEST_VITE_CODES` via `defineCodes("TEST_VITE", […])` + `TestViteError`.
|
|
- `telemetry/` — OTel counters + histograms for factory invocations and validator runs.
|
|
- `types/` — shared option/result types.
|
|
|
|
## Parity Checklist
|
|
|
|
| Capability | Upstream | Migrated | Notes |
|
|
|---|---|---|---|
|
|
| `export const test = "hi"` placeholder | ✅ | 🚫 | Removed — explicit goal of the enterprise plan. |
|
|
| `createViteLibraryConfig` | 📝 (README only) | ✅ | New implementation per enterprise plan §4. |
|
|
| `createViteAppConfig` | 📝 (README only) | ✅ | New implementation. |
|
|
| `createVitestConfig` (WSL2-safe) | 📝 (README only) | ✅ | New; defaults: `pool: 'forks'`, Istanbul, `setupFiles`. |
|
|
| `createVitestBrowserConfig` | 📝 (README only) | ✅ | New; Playwright provider. |
|
|
| `setupBrowserEnvironment` | 📝 (README only) | ✅ | New. |
|
|
| Tree-shake validator | 📝 | ✅ | New. |
|
|
| Bundle-size snapshot | 📝 | ✅ | New. |
|
|
| Custom matchers | 📝 | ✅ | New. |
|
|
| Port allocator | 📝 | ✅ | New. |
|
|
| HMR tester | 📝 | ✅ | New. |
|
|
| Error-code registry | 🚫 | ⬆️ | Enhanced — required by genesis. |
|
|
| OTel self-telemetry | 🚫 | ⬆️ | Enhanced — required by genesis. |
|
|
| Subpath exports | 🚫 | ⬆️ | Enhanced — every feature is its own subpath. |
|
|
|
|
The "Upstream 📝" rows track features that existed only as README copy upstream; they are net-new implementations on genesis.
|
|
|
|
## Scope split vs `@suaveplan/testing`
|
|
|
|
`@suaveplan/testing/config` already owns the *generic* `createTestConfig({ environment })` used across packages. This package, `@suaveplan/test-vite`, owns the **Vite-specific build factories and Vitest configurations** that surface Vite/Rollup-specific options (`vite-plugin-dts`, `preserveModules`, Playwright browser-mode, HMR round-trip). They are complementary: `@suaveplan/testing` is runner-agnostic; `@suaveplan/test-vite` is Vite-aware.
|
|
|
|
## Impact
|
|
|
|
### Affected dependents
|
|
|
|
Net-new package — no current consumers. Downstream browser-tier packages MAY opt into the factories incrementally; the enterprise plan flags `react-tour` as the first migration target.
|
|
|
|
## Risks
|
|
|
|
- **Vite/Vitest type surface drift.** The factories return `UserConfig` from the pinned Vite / Vitest catalog versions. Mitigated by importing config types directly from those packages.
|
|
- **WSL2 fork-pool requirement.** `createVitestConfig` defaults MUST stay `pool: 'forks'`; deviation will silently re-break `vmThreads` consumers. Pinned by explicit test + spec requirement.
|
|
- **Bundle-size snapshot file IO.** The validator accepts an injectable `fs` adapter so tests don't touch the real filesystem; production callers pass `node:fs/promises`.
|