Skip to content

Bumped vite and vitest in signup-form and comments-ui#27873

Merged
9larsons merged 1 commit into
mainfrom
security/vite-bump-step4
May 13, 2026
Merged

Bumped vite and vitest in signup-form and comments-ui#27873
9larsons merged 1 commit into
mainfrom
security/vite-bump-step4

Conversation

@9larsons
Copy link
Copy Markdown
Contributor

@9larsons 9larsons commented May 13, 2026

Why

The final two public/UMD apps move from vite@5.4.21 + vitest@1.6.1 to vite@7.3.2 + vitest@4.1.2, finishing the apps/* unification that started with PR #27731 and continued through #27867 (shade + admin-x-design-system) and #27869 (portal + sodo-search + announcement-bar). Every workspace under apps/ now runs the same vite + vitest pair.

@vitest/coverage-v8 in comments-ui jumped from 0.34.64.1.2 — it had been pinned to a vitest 0.x compatible version and was years out of date.

Substantive changes beyond the bumps

1. SVG migration (vite-plugin-svgr v3 → v4)

v3 exposed both default (URL) and named ReactComponent on every .svg import; v4 splits them — ./foo.svg is the URL, ./foo.svg?react is the React component (as default export). Migrated 16 imports:

  • 14 in comments-ui (12 files)
  • 2 in signup-form (2 files)

Both typings.d.ts files split into *.svg (URL default) and *.svg?react (component default), using import type instead of the legacy import React = require('react') pattern.

2. vitest 1 → 4 test-side fixes (comments-ui)

a. Constructable mock in setup-tests.tsglobal.ResizeObserver = vi.fn().mockImplementation(() => ({...})) used an arrow function. Vitest 4 enforces that mocks called with new have constructable implementations. Switched to function expression form.

b. Persistent spy in test/unit/utils/api.test.ts — three tests each called vi.spyOn(window, 'fetch') with no teardown. Under vitest 4 the spy persists across tests, so the second and third tests saw accumulated call counts. Added an afterEach that calls vi.restoreAllMocks().

3. vite 7 build performance — commonjsOptions.dynamicRequireTargets

The first CI run on this branch exposed a vite 7 regression that also affected portal and sodo-search from PR #27869 (their tests didn't surface it because they have no playwright webServer):

Each app's vite config had:

commonjsOptions: {
    dynamicRequireRoot: '../../',
    dynamicRequireTargets: SUPPORTED_LOCALES.map(locale =>
        `../../ghost/i18n/locales/${locale}/X.json`)
}

That produces ~60 explicit paths (one per locale). Under vite 7's bundled @rollup/plugin-commonjs, every entry in that array triggers a full directory crawl from dynamicRequireRoot (= repo root, including node_modules) at the start of the build. The result: ~58 seconds of file-walker work before rollup's buildStart hook even fires. The bundle itself takes <1s after that.

For signup-form and comments-ui, the playwright webServer runs pnpm dev:test = vite build && vite preview --port XXXX, then waits for http://localhost:XXXX/<bundle>.min.js. The build's 58s startup meant the preview server didn't bind before the 10s/20s webServer.timeout fired.

Fix: replace the N-entries-per-locale array with a single glob:

dynamicRequireTargets: ['../../ghost/i18n/locales/*/X.json']

The plugin resolves this with one directory crawl. Bundle output is byte-identical (verified for portal, sodo-search, comments-ui; signup-form size unchanged at 301,817 bytes). Build time drops from ~60s to ~2s.

Applied the same fix to portal and sodo-search even though their PR is already merged — they were shipping the slow pattern on main and the savings apply.

Test plan

  • pnpm --filter @tryghost/comments-ui test:unit — 207/207 across 12 files
  • pnpm --filter @tryghost/comments-ui build — 2.7s (was 60s); UMD wrapper intact (~860KB)
  • pnpm --filter @tryghost/comments-ui lint — 0 errors
  • pnpm --filter @tryghost/signup-form build — 2.0s (was 60s); UMD wrapper intact (~302KB)
  • pnpm --filter @tryghost/signup-form lint — clean
  • pnpm --filter @tryghost/portal build — 3.6s (was 60s+); bundle byte-identical
  • pnpm --filter @tryghost/sodo-search build — 4.7s (was 60s+); bundle byte-identical
  • Local repro: dev:test webServer ready in 4s (was timing out at 10s/20s)
  • CI confirms against the canonical environment

Followup

Once this lands, every workspace under apps/* is on the same five-package vite/vitest pin. The natural follow-up is lifting those into a pnpm catalog so future bumps are a one-line edit — see docs/pnpm-catalog-support.md for the CI publish-step prerequisite.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ed495a6f-be85-4048-8815-86a99a291d9b

📥 Commits

Reviewing files that changed from the base of the PR and between 5eb6018 and 8b6b8ed.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (25)
  • apps/comments-ui/package.json
  • apps/comments-ui/src/components/content/avatar.tsx
  • apps/comments-ui/src/components/content/buttons/like-button.tsx
  • apps/comments-ui/src/components/content/buttons/like-count.tsx
  • apps/comments-ui/src/components/content/buttons/more-button.tsx
  • apps/comments-ui/src/components/content/buttons/reply-button.tsx
  • apps/comments-ui/src/components/content/forms/form.tsx
  • apps/comments-ui/src/components/content/forms/sorting-form.tsx
  • apps/comments-ui/src/components/content/loading.tsx
  • apps/comments-ui/src/components/popups/close-button.tsx
  • apps/comments-ui/src/components/popups/delete-popup.tsx
  • apps/comments-ui/src/components/popups/report-popup.tsx
  • apps/comments-ui/src/setup-tests.ts
  • apps/comments-ui/src/typings.d.ts
  • apps/comments-ui/test/unit/utils/api.test.ts
  • apps/comments-ui/vite.config.mts
  • apps/portal/package.json
  • apps/portal/vite.config.mjs
  • apps/signup-form/package.json
  • apps/signup-form/src/components/pages/form-view.tsx
  • apps/signup-form/src/components/pages/success-view.tsx
  • apps/signup-form/src/typings.d.ts
  • apps/signup-form/vite.config.mts
  • apps/sodo-search/package.json
  • apps/sodo-search/vite.config.mjs
✅ Files skipped from review due to trivial changes (11)
  • apps/sodo-search/package.json
  • apps/portal/package.json
  • apps/comments-ui/src/components/content/avatar.tsx
  • apps/comments-ui/src/components/content/buttons/like-button.tsx
  • apps/comments-ui/src/components/popups/delete-popup.tsx
  • apps/comments-ui/src/components/popups/close-button.tsx
  • apps/comments-ui/src/components/content/buttons/more-button.tsx
  • apps/comments-ui/src/components/content/loading.tsx
  • apps/signup-form/package.json
  • apps/comments-ui/src/components/content/buttons/like-count.tsx
  • apps/comments-ui/src/components/popups/report-popup.tsx
🚧 Files skipped from review as they are similar to previous changes (10)
  • apps/comments-ui/src/components/content/forms/form.tsx
  • apps/signup-form/src/components/pages/form-view.tsx
  • apps/sodo-search/vite.config.mjs
  • apps/comments-ui/test/unit/utils/api.test.ts
  • apps/comments-ui/src/components/content/buttons/reply-button.tsx
  • apps/comments-ui/src/setup-tests.ts
  • apps/comments-ui/package.json
  • apps/signup-form/src/typings.d.ts
  • apps/portal/vite.config.mjs
  • apps/comments-ui/vite.config.mts

Walkthrough

This PR migrates SVG icon imports across multiple apps from SVGR's ReactComponent named-export pattern to Vite's ?react default-export pattern, updates TypeScript SVG module declarations to split *.svg and *.svg?react typings, updates component imports accordingly, bumps several package versions and dev tooling, replaces per-locale dynamicRequireTargets with glob patterns in several Vite configs, and adjusts test setup (ResizeObserver mock and vitest cleanup).

Possibly related PRs

  • TryGhost/Ghost#27867: Migrates SVG imports and typings to the Vite *.svg?react pattern in other packages, paralleling the same transformation here.
  • TryGhost/Ghost#27869: Performs the same SVG icon import migration (SVGR v3→v4 style) across related components.

Suggested labels

ok to merge for me

Suggested reviewers

  • weylandswart
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: bumping vite and vitest in signup-form and comments-ui apps.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the why, substantive changes, and test plan.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch security/vite-bump-step4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/comments-ui/package.json (1)

25-25: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add Playwright reporter env var in e2e script.

test:e2e should include PLAYWRIGHT_REPORTER=list for AI-agent parsing consistency.

Proposed fix
-    "test:e2e": "NODE_OPTIONS='--experimental-specifier-resolution=node --no-warnings' VITE_TEST=true playwright test",
+    "test:e2e": "NODE_OPTIONS='--experimental-specifier-resolution=node --no-warnings' VITE_TEST=true PLAYWRIGHT_REPORTER=list playwright test",

As per coding guidelines, "Set PLAYWRIGHT_REPORTER=list environment variable when running Playwright e2e tests as an AI agent for better parsing".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/comments-ui/package.json` at line 25, Update the npm script named
"test:e2e" to export the PLAYWRIGHT_REPORTER=list environment variable when
invoking Playwright; specifically modify the "test:e2e" script entry so it
includes PLAYWRIGHT_REPORTER=list alongside NODE_OPTIONS and VITE_TEST so
Playwright runs with the list reporter for AI-agent parsing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/comments-ui/package.json`:
- Line 25: Update the npm script named "test:e2e" to export the
PLAYWRIGHT_REPORTER=list environment variable when invoking Playwright;
specifically modify the "test:e2e" script entry so it includes
PLAYWRIGHT_REPORTER=list alongside NODE_OPTIONS and VITE_TEST so Playwright runs
with the list reporter for AI-agent parsing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7d8a5137-470a-45e4-b8ac-bb84587edeea

📥 Commits

Reviewing files that changed from the base of the PR and between 3b19f78 and 60276f5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • apps/comments-ui/package.json
  • apps/comments-ui/src/components/content/avatar.tsx
  • apps/comments-ui/src/components/content/buttons/like-button.tsx
  • apps/comments-ui/src/components/content/buttons/like-count.tsx
  • apps/comments-ui/src/components/content/buttons/more-button.tsx
  • apps/comments-ui/src/components/content/buttons/reply-button.tsx
  • apps/comments-ui/src/components/content/forms/form.tsx
  • apps/comments-ui/src/components/content/forms/sorting-form.tsx
  • apps/comments-ui/src/components/content/loading.tsx
  • apps/comments-ui/src/components/popups/close-button.tsx
  • apps/comments-ui/src/components/popups/delete-popup.tsx
  • apps/comments-ui/src/components/popups/report-popup.tsx
  • apps/comments-ui/src/setup-tests.ts
  • apps/comments-ui/src/typings.d.ts
  • apps/comments-ui/test/unit/utils/api.test.ts
  • apps/signup-form/package.json
  • apps/signup-form/src/components/pages/form-view.tsx
  • apps/signup-form/src/components/pages/success-view.tsx
  • apps/signup-form/src/typings.d.ts

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.74%. Comparing base (17f2ba2) to head (8b6b8ed).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #27873   +/-   ##
=======================================
  Coverage   73.74%   73.74%           
=======================================
  Files        1519     1519           
  Lines      127726   127726           
  Branches    15291    15291           
=======================================
  Hits        94186    94186           
+ Misses      32613    32589   -24     
- Partials      927      951   +24     
Flag Coverage Δ
admin-tests 53.46% <ø> (ø)
e2e-tests 73.74% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@9larsons 9larsons force-pushed the security/vite-bump-step4 branch from 60276f5 to 5eb6018 Compare May 13, 2026 19:14
The final two public/UMD apps move from vite@5.4.21 + vitest@1.6.1 to
vite@7.3.2 + vitest@4.1.2, finishing the unification across apps/* that
started with PR #27731 and continued through #27867 and #27869. Every
workspace under apps/ now runs the same vite + vitest pair.

@vitest/coverage-v8 in comments-ui jumped from 0.34.6 to 4.1.2 - it had
been pinned to a version compatible with vitest 0.x and was years out
of date.

Substantive changes beyond the bumps:

1. vite-plugin-svgr v3 -> v4 changed the SVG import API (./foo.svg
   now gives the URL, ./foo.svg?react gives the React component as
   default export). Migrated 16 imports across:
   - 14 in comments-ui (12 files)
   - 2 in signup-form (2 files)
   Both typings.d.ts files were split into *.svg (URL default) and
   *.svg?react (component default), using `import type` instead of
   the legacy `import React = require('react')` pattern.

2. vitest 1 -> 4 had two test-side issues in comments-ui:

   a. setup-tests.ts: `global.ResizeObserver = vi.fn()
      .mockImplementation(() => ({...}))` - vitest 4 enforces that
      mocks called with `new` have constructable implementations, and
      arrow functions are not constructable. Switched to function
      expression form.

   b. test/unit/utils/api.test.ts: three tests each called
      vi.spyOn(window, 'fetch') with no teardown. The spy persisted
      across tests, accumulating call counts. Added an afterEach
      with vi.restoreAllMocks().

3. vite 5 -> 7 build performance fix in all four public UMD apps
   (signup-form, comments-ui, plus portal and sodo-search already on
   vite 7 from #27869). Each app's vite.config used
   `commonjsOptions.dynamicRequireTargets: SUPPORTED_LOCALES.map(
   locale => '../../ghost/i18n/locales/' + locale + '/X.json')`,
   producing an array of ~60 explicit paths. Under vite 7's bundled
   @rollup/plugin-commonjs, each entry in that array triggers a full
   directory crawl from `dynamicRequireRoot` (= repo root, including
   node_modules) at the start of every build. The result was a ~58s
   delay before rollup's buildStart hook fired, which under
   `vite build && vite preview` blew playwright's webServer timeout
   (10s for signup-form, 20s for comments-ui).

   Replaced the N-entries-per-locale array with a single glob -
   `['../../ghost/i18n/locales/*/X.json']` - which the plugin
   resolves with one crawl. Same bundle output (verified byte-for-byte
   for portal/sodo-search/comments-ui; signup-form bundle size
   unchanged at 301817 bytes). Build time drops from ~60s to ~2s.

   Also fixed for portal and sodo-search in this PR even though
   they're not on the failing branch - they were already shipping
   the slow pattern on main via #27869 and the savings apply.

Patch version bumps on both new packages (CI version-bump check
requires this whenever source files change in a monitored app).

Verification:
- comments-ui: 207/207 unit tests, build (2.7s, was 60s), lint
- signup-form: build (2.0s, was 60s), lint
- portal: build (3.6s, was 60s+) - bundle byte-identical
- sodo-search: build (4.7s, was 60s+) - bundle byte-identical
- Local repro: dev:test webServer ready in 4s (was timing out)
@9larsons 9larsons force-pushed the security/vite-bump-step4 branch from 5eb6018 to 8b6b8ed Compare May 13, 2026 19:16
@9larsons 9larsons enabled auto-merge (squash) May 13, 2026 19:23
@9larsons 9larsons disabled auto-merge May 13, 2026 19:32
@9larsons 9larsons enabled auto-merge (squash) May 13, 2026 19:42
@9larsons 9larsons merged commit ac600b4 into main May 13, 2026
45 checks passed
@9larsons 9larsons deleted the security/vite-bump-step4 branch May 13, 2026 19:43
EvanHahn pushed a commit that referenced this pull request May 13, 2026
no ref

Final bump to unify the vite/vitest tooling versions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant