chore(deps): modernize toolchain (Vite 8, TS 6, ESLint 10, Hono) + cut 14 direct deps (-139 pkgs) - #786
Conversation
a115c36 to
60ae054
Compare
CI note:
|
60ae054 to
a064942
Compare
Claudia-Anthropica
left a comment
There was a problem hiding this comment.
@FelixTJDietrich The dependency cleanup and Hono migration look solid, and CI is green. I left one small docs cleanup inline; approving.
c9efc2b to
24778da
Compare
Claudia-Anthropica
left a comment
There was a problem hiding this comment.
@FelixTJDietrich The dependency and Hono migration code generally looks solid, but the current e2e-tests check is failing on the changed Playwright readiness path. I left that as the blocking item inline, plus two small stale-doc cleanup notes.
fe8fbab to
8fc6563
Compare
194e204 to
f8a9905
Compare
…t 14 direct deps (-139 pkgs) Toolchain to the latest working majors: - Vite 6→8 (Rolldown/Oxc), @vitejs/plugin-react 4→6, vite-plugin-dts 4→5 (rollupTypes→bundleTypes via @microsoft/api-extractor), TypeScript 5.7→6.0. - ESLint 9→10. eslint-plugin-react has no v10 release (it calls the removed context.getFilename()), so React linting moves to @eslint-react/eslint-plugin (flat-config, v10-native); eslint-plugin-react-hooks stays the hooks authority and @eslint-react's overlapping hook rules are disabled so each is reported once. Server runtime majors: - zod 3→4, redis 5→6 (pinned RESP2 to preserve the raw sendCommand reply shapes this code parses), pino 9→10, dotenv 16→17, ulid 2→3. - Express 5 → Hono 4 + @hono/node-server (both zero-runtime-dep), dropping express/cors/cookie/pino-http and ~18 transitives. Routes, status codes, bodies, headers, owner-cookie HMAC, CORS policy, zod error envelopes and the yjs WS relay are preserved; buildApp still returns an unstarted http.Server. Cuts: - uuid → an embed-safe crypto.getRandomValues RFC-4122 v4 (works in any context, unlike crypto.randomUUID which needs a secure context an embed can't assume). - cmdk + the unused command component; @ionic/react → a 45-line vendored platform.ts (its Stencil runtime was in the initial bundle for UA checks only) — webapp initial bundle nearly halved. - packages/ui: drop dead @vitest/coverage-v8 (no coverage config/script there). ~50 deps bumped to latest (modulo the repo's >24h minimumReleaseAge). Verified: pnpm install --frozen-lockfile; pnpm lint 0 errors; pnpm knip clean; builds (library single-entry incl. rolled .d.ts, webapp, server, vscode, ui types + stories typecheck); size-limit within budget (webapp initial 34.65/35 kB); tests library 1222 / webapp 256 / server 150 (Docker) / ui 37. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> test(e2e): run CI against a bundled build with test seams enabled (root-cause fix for the flaky `.react-flow` canvas timeouts). The suite ran against the Vite dev server because it needs the `import.meta.env.DEV`-gated test seams (`window.apollonEditor`, `__apollonSafeArea`, `__apollonPerf`); the dev server serves the app as hundreds of unbundled native-ESM modules and compiles the heavy editor route on demand, so every test's fresh browser context refetched them — a slow, variable request waterfall that intermittently blew the canvas-ready budget, regardless of parallelism or timeout. Fix: gate the three seams on `DEV || VITE_E2E` (still statically stripped from real prod builds — verified), and in CI serve a `VITE_E2E=true` production build via `vite preview` — a handful of static files, so loads are fast and deterministic and the suite keeps `workers: "50%"` (short runs) without flake. Local runs keep the dev server. Verified locally: the e2e build ships the seams, a plain prod build strips all three, and preview serves the built app. docs: resolve review comments — README tech-stack table and the server Dockerfile image description now say Hono (not Express); the visual-tests contributor doc uses the v1.61.1-noble Playwright image to match CI. test(e2e): correct the landscape editor-chrome test to match the deliberate design. `editor.spec.ts` "keeps the phone layout in landscape" asserted the mobile compact pill (navbar ≤36px) at `PHONE_LANDSCAPE` (844px), but `constants/responsive.ts` deliberately keeps the FULL desktop action set in landscape (844px > NARROW_VIEW_QUERY's 767.95px — "wide enough … just shorter"). The assertion contradicted the app's documented intent and only ever "passed" because the dev-server canvas flake killed the test before it reached the assertion; with e2e now on a bundled build the test runs deterministically and exposed the mismatch. Corrected the navbar bound to the unified header height (≤52, same as the portrait sibling) and the palette overflow to the sub-pixel tolerance (≤4); the safe-area-inset assertions (logo/actions/controls/minimap clear the notch) are unchanged — that's the real regression guard. Verified locally against the e2e build: the full 139-test suite passes (workers=2). test(e2e): keep the library perf probe live in the e2e build so perf-firefox works against the bundled app. The perf suite reads `window.__apollonPerf`, which proxies the library's `ApollonEditor.__perf()` / perf-counters — both gated on `import.meta.env.DEV`, so they returned undefined in the prod-mode e2e build. The webapp consumes the library from source, so gating them on `DEV || VITE_E2E` (shared `PERF_PROBE_ENABLED`) compiles them live under the `VITE_E2E=true` e2e build while the standalone `build:lib` (no VITE_E2E) still strips them — verified: `check-no-perf-hooks` stays green, the probe is present in the e2e build and absent from a plain prod build, and the perf test passes locally.
f8a9905 to
0d49d51
Compare
Summary
A ruthless dependency-modernization pass over the whole monorepo: push the build toolchain to the latest working majors, migrate the server's runtime majors (including Express 5 → Hono 4), and cut dead/redundant packages — leaving the repo measurably leaner, more current, and behavior-identical.
Net
−139resolved packages (2667 → 2528), 14 direct dependencies removed vs 4 added, every runtime/published dependency at npm latest, and zero new vulnerabilities introduced (the one security-relevant bump,ws, actually fixes an advisory in the server runtime).Headline outcomes
@vitejs/plugin-react4→6 ·vite-plugin-dts4→5 (+@microsoft/api-extractor) · TypeScript 5.7→6.0 · ESLint 9→10 (→@eslint-react)@ionic/reactdrop)ws 8.18→8.21remediates GHSA ws-DoS in the WS relay; all residual crit/high are inherited dev/build/test transitivesminimumReleaseAge1. Build toolchain & shared dev tooling
vitedebuggeron minify, so the explicitesbuild: { drop }is gone.@vitejs/plugin-reactvite/internal; paired with the Vite bump.vite-plugin-dtsrollupTypes→bundleTypes; emits one rolled, self-contained.d.tsper entry via api-extractor.@microsoft/api-extractor@tumaet/uiin.typescriptbaseUrl(TS5101) and madepaths./-relative across all tsconfigs.typescript-eslinteslint@eslint/js@eslint/js(it versions independently ofeslint— 10.0.1 is the head, not 10.6.0).eslint-plugin-react@eslint-react/eslint-plugin5.9.3eslint-plugin-reacthas no ESLint-10 release (calls the removedcontext.getFilename()).@eslint-reactis flat-config + v10-native;recommended-typescriptpreserves coverage and disables the prop-types rules TS already enforces.eslint-plugin-react-hooks@eslint-react's overlapping hook rules are turned off so each concern is reported once.globalsjsdomsize-limit/@size-limit/*vitest/@vitest/*tailwindcss/@tailwindcss/*@types/node@playwright/test/playwrightplaywright-core+ browser set). CI image →v1.61.1-noble.@commitlint/*concurrentlykniplint-stagedprettier2. Server runtime majors + Express → Hono
express+cors+cookie+pino-httphono@hono/node-serverbuildAppstill returns an unstartedhttp.ServerviacreateAdaptorServer, soserver.ts+ all supertest tests are unchanged. The yjs WS relay (standalonewsonWS_PORT) is intentionally untouched (moving it would change the client URL contract).zodredissendCommandreply shapes this module parses; pinned the documented{ RESP: 2 }escape hatch to preserve wire shapes;Redistype derived from the factory.pinoulidws>=8.0.0 <8.21.0is vulnerable to a memory-exhaustion DoS (GHSA-3h5v-q93c-6h6q). This bump patches the server's WS-relay runtime.pdfmakeglobal-jsdomcanvas(@napi-rs/canvas)supertest/@types/supertesttestcontainerstsx@types/express*/@types/cors3. Cuts (dependency removals)
uuid+@types/uuidcrypto.getRandomValuesRFC-4122 v4 (works in any context, unlikecrypto.randomUUIDwhich needs a secure context an embed can't assume); webapp uses nativecrypto.randomUUID. New test asserts format/variant over 10k samples + uniqueness + CSPRNG.cmdkcommandcomponent had zero importers; removed it and the dep.@ionic/reactisPlatform()UA checks but dragged the entire Stencil runtime into the initial bundle and double-bundled the editor. Replaced by a 45-line MIT-attributedplatform.ts(UA detection reproduced byte-for-byte;isNativePlatform = Capacitor.isNativePlatform()). Initial bundle ≈ −47%.express,cors,cookie,pino-httpdotenvutil.parseEnv(stable since Node 20.12; the server targets Node ≥24.15). The side-effectenv.tsreads.envand merges it with the same semantics dotenv had — silent, no-override of pre-set vars, no-op when the file is absent. Parity unit-checked; one fewer runtime dependency.@vitest/coverage-v8test:coveragescript (onlyvitest run).library/serverkeep it (they do collect coverage).babel-plugin-react-compilerwebview-vite.config.ts(a root-workspace file re-exported by editor/menu) references it as a Babel plugin. An earlier pass wrongly cut it; restoring it keeps the dependency graph honest (no phantom dep resolved only via hoisting).4. Notable client bumps
@base-ui/react@xyflow/reactzustandlucide-reactreact-toastify@tanstack/react-router@capacitor/*@chenglou/pretext@easyops-cn/docusaurus-search-local·@mermaid-js/layout-elkyjs(13.6.31) +y-protocols(1.0.7) were promoted to the catalog: the library externalizes them as a CRDT singleton, so every client workspace must pin exactly one version.5. Security audit (
pnpm audit)No vulnerability is introduced by this PR. Every critical/high advisory is on a transitive package that is already present in
mainand lives in a dev / build / test toolchain — none in the published@tumaet/apollonruntime or the server's request-handling runtime. The one security-relevant change is a remediation:wsmemory-exhaustion DoS (GHSA-3h5v-q93c-6h6q)ws)ws 8.18.1 → 8.21.0)shell-quotenewline escapedocs > webpack-dev-server > launch-editorserialize-javascript,ws,lodash-es,linkify-itdocs > @docusaurus/*(webpack / mermaid / markdownlint)undici(TLS-bypass / WS-DoS / routing)library > vitest > jsdom > undici,docs > cheerio > undicijsdomuses no outboundundiciTLS path, so the advisory doesn't apply to that usage.tmppath traversalwebapp > @capacitor/assets > @trapezedev/projectform-dataCRLFserver > supertest > superagentRecommendation (gap, not done here): the remaining inherited transitives are backward-compatible patch bumps and could be force-floated via
pnpm.overrides(e.g.undici@>=7.28.0,form-data@>=4.0.6,tmp@>=0.2.6). They're left out of this PR because they're dev/build-only and belong with their respective Docusaurus/Capacitor/Vitest major updates rather than this toolchain pass — happy to add an overrides block if preferred.6. Compatibility ceilings (held with evidence, not guessed)
eslint-plugin-reacthas no v10 release (peer caps^9.7; calls removedcontext.getFilename())@eslint-react(v10-native, flat-config).d.tsJSX.Element@microsoft/api-extractor7.58.9 +bundleTypes@vitejs/plugin-react6vite/internal.d.tsis type-checked against real built types bycheck:doc-snippetsin CI. No newer api-extractor exists yet.7. Version-currency & intentional holds
Every runtime and published dependency is at npm latest. The only items behind latest are dev tooling and release-age holds:
viteminimumReleaseAgetypescript-eslint@eslint-react/eslint-plugintailwindcssknip·prettier·@commitlint/cli·testcontainers8. Verification
All commands run green on this branch (rebased on
main):pnpm install --frozen-lockfilepnpm lint(all workspaces)pnpm knip.d.ts), webapp (tsc -b), server, vscodebuild:all,@tumaet/uitypes@tumaet/uitypecheck (incl. 28 stories)9. Gaps & open follow-ups (honest)
pnpm.overridesblock (or the corresponding Docusaurus/Capacitor/Vitest major updates).knip/prettier/commitlint/testcontainers/@eslint-react/tailwindcsshave newer releases; each is a trivial, separable bump..d.ts.c.req.url(with query) rather thanc.req.path, take the lastX-Forwarded-Protosegment to match the oldtrust proxy=1, replace twoas/as neverescapes, and add explicit CORS-parity + body-limit-drain tests.update-visual-baselinesworkflow (image already bumped tov1.61.1-noble).How to test
Confirm
library/distemits onlyindex/internals/export.d.ts(noreact/external),packages/ui/disthas zero*.stories.d.ts, and@tumaet/apollonresolves as a single entry from the webapp.🤖 Generated with Claude Code