Extracted shared vite config helper for public UMD apps#28976
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
WalkthroughA new shared Vite configuration factory Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run-many --target=build --projects=tag:publi... |
✅ Succeeded | 1s | View ↗ |
nx run-many -t test:unit -p @tryghost/admin-too... |
✅ Succeeded | 1m 7s | View ↗ |
nx run @tryghost/comments-ui:test:acceptance |
✅ Succeeded | 48s | View ↗ |
nx run-many -t lint -p ghost-monorepo,@tryghost... |
✅ Succeeded | 24s | View ↗ |
nx run @tryghost/signup-form:test:acceptance |
✅ Succeeded | 11s | View ↗ |
nx run @tryghost/admin:build |
✅ Succeeded | 5s | View ↗ |
nx run ghost:build:assets |
✅ Succeeded | 2s | View ↗ |
nx run ghost:build:tsc |
✅ Succeeded | 6s | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-06-29 21:46:42 UTC
no ref Each of the 6 public UMD apps (portal, comments-ui, sodo-search, announcement-bar, signup-form, admin-toolbar) hand-rolled ~90% of the same vite config: outDir, lib block, optional i18n locale glob, baseline plugins, test config. Drift had crept in across them (plugin order, define entries, test setup keys, NODE_ENV resolution). `publicAppViteConfig` lives at apps/_shared/vite-public-app.mjs and takes the dimensions that legitimately vary per app (framework='react'|'preact', svgr, libFormat, sourcemap, cssCodeSplit, i18nNamespace, libName) plus an `overrides` slot that flows through Vite's `mergeConfig` for anything app-specific (extra plugins, resolve.dedupe, rollupOptions.output, preview block). Plugin imports are dynamic so apps can opt out of dependencies they don't use (admin-toolbar runs Preact and never installs @vitejs/plugin-react). Followup commits migrate each of the 6 apps onto this helper, byte-diff gated against the bundle output on origin/main.
no ref Replaced the hand-rolled 30-line vite.config.mjs with a 10-line call to publicAppViteConfig. Behavior is unchanged: IIFE format, Preact runtime, no SVGR, sourcemap off. Verified: emitted umd/admin-toolbar.min.js is byte-identical to the PR1 baseline.
no ref Replaced the 38-line vite.config.mjs with a 13-line call to publicAppViteConfig. All defaults (React, SVGR, UMD, sourcemap on, cssCodeSplit on) apply; only `test.setupFiles` passes through overrides. Verified: emitted umd/announcement-bar.min.js + .map byte-identical to baseline.
no ref Replaced the 56-line vite.config.mjs with a 33-line call to publicAppViteConfig. Per-app divergence flows through overrides: - `cssCodeSplit: false` (sodo-search emits a single CSS file) - `i18nNamespace: 'search'` wires the locale glob - `resolve.dedupe: ['@tryghost/debug']` - `build.rollupOptions.output.assetFileNames` keeps the CSS sibling named umd/main.css (theme templates reference it by that name; see ghost/core defaults.json → sodoSearch.styles) - `test.setupFiles` for the per-app jsdom setup Verified: emitted umd/sodo-search.min.js + main.css + map are byte-identical to baseline.
no ref Replaced the 62-line vite.config.mjs with a 33-line call. Per-app divergence in overrides: - `i18nNamespace: 'portal'` - `cssCodeSplit: false` (portal emits a single CSS file) - `plugins: [cssInjectedByJsPlugin()]` — inlines CSS into the JS bundle (appended after react+svgr; plugin operates at the render hook, not transform, so order doesn't change output) - `define.REACT_APP_VERSION` from npm_package_version - `resolve.dedupe: ['@tryghost/debug']` - `build.rollupOptions.output.manualChunks: false` - `test.setupFiles` + `test.coverage.reporter` Verified: emitted umd/portal.min.js + map byte-identical to baseline.
no ref
Replaced the 78-line vite.config.mts with a 35-line call. Per-app
divergence in overrides:
- `i18nNamespace: 'signup-form'`
- `define.VITEST_SEGFAULT_RETRY` (vitest segfault retry env var)
- `preview` block (still consumed by the dev:test script)
- `optimizeDeps.include` ('@tryghost/i18n', '@tryghost/debug')
- `resolve.dedupe: ['@tryghost/debug']`
- `build.rollupOptions.output: {}` (empty, preserved for parity)
- `test` extras: `include`, env-driven `testTimeout`, CI thread caps
Verified: emitted umd/signup-form.min.js + map byte-identical to
baseline.
no ref
Last of the 6 public apps onto publicAppViteConfig. The 96-line
vite.config.mts shrinks to 48 lines. Per-app divergence in overrides:
- `plugins: [stripFingerprintingPlugin()]` — Safari 26+ / DDG
tracker mitigation for ProseMirror/tiptap
- `define.VITEST_SEGFAULT_RETRY`
- `preview` block (dev:test still uses `vite preview --port 7175`,
takes the override on port but inherits host/allowedHosts)
- `server` block (port 5368)
- `resolve.dedupe + alias` for React-17 hoist-avoidance (load-bearing)
- `i18nNamespace: 'comments'`
- `build.rollupOptions.output: {}` (empty, preserved)
- `test.setupFiles` + `test.include` + `test.server.deps.inline`
(the tiptap/headlessui inline rule that keeps Vite's alias applying
to their React imports)
- `test.testTimeout` from env + CI thread caps
The unused multi-format `fileName` function dropped — formats only
contains 'umd', the helper's default fileName produces the same
`comments-ui.min.js` output.
Verified: emitted umd/comments-ui.min.js + map byte-identical to
baseline.
no ref The helper-based vite.config in each of the 6 public apps triggers the app-version-bump CI check. MAJOR.MINOR unchanged across all six, so ghost/core/core/shared/config/defaults.json does not need updates. - admin-toolbar: 0.1.10 → 0.1.11 - announcement-bar: 1.1.27 → 1.1.28 - comments-ui: 1.5.21 → 1.5.22 - portal: 2.69.14 → 2.69.15 - signup-form: 0.3.33 → 0.3.34 - sodo-search: 1.8.30 → 1.8.31
e8e7f4e to
8772484
Compare

Summary
Extracts a shared
publicAppViteConfigfactory atapps/_shared/vite-public-app.mjs, then migrates all 6 public UMD apps onto it. Pure refactor: bundle output byte-identical to current main (verified post-rebase against #28974). Total vite-config code shrinks from ~360 → ~150 lines.Now rebased onto
mainafter #28973 and #28974 merged. The 4 apps #28974 setsourcemap: falsefor pass that through as a top-level helper arg (sourcemap: false).How the helper carves up "common" vs "per-app"
Helper covers what every app shares —
logLevel,clearScreen,outDir, thelibblock (entry, formats, name, fileName frompackageName),build.{emptyOutDir,reportCompressedSize,minify}, optional i18n locale glob, baselinetestblock.Per-app divergence flows through an
overridesslot that's deep-merged via Vite'smergeConfig(appends plugin arrays, deep-merges objects, override-wins primitives). First-class knobs cover the dimensions that legitimately vary:framework: 'react' | 'preact'svgr: booleanlibFormat: 'umd' | 'iife'libName(e.g.'GhostAdminToolbar'for admin-toolbar's IIFE global)sourcemap(false for 5 of 6 post-Removed sourcemap generation for four public apps #28974),cssCodeSpliti18nNamespace(4 of 6 apps wire a locale glob)Plugin imports are dynamic (
await import(...)inside the factory) so apps can opt out of deps they don't use — admin-toolbar uses Preact and never installs@vitejs/plugin-react.Per-app config shrink
Verification
main(post-Removed sourcemap generation for four public apps #28974) for all 6 apps — verified viasha256sumover emittedumd/*after rebuilding both states.test:acceptance).Notes
apps/_shared/(underscore-prefix = not a published workspace package)..mjs+ JSDoc (not.ts) to avoid an import-edge case with the 4.mjscallers and 2.mtscallers.overridesget appended after base plugins (reactPlugin(),svgrPlugin()); confirmed no order-sensitive output drift via byte-diff (portal'scssInjectedByJsPluginoperates at the render hook, not transform — order doesn't matter).comments-uidropped its unused multi-formatfileNamefunction (formats only contains'umd'; helper default produces the samecomments-ui.min.js).Test plan
pnpm dev(portal sign-in, comments-ui post, sodo-search query)