chore(workbench): rebase onto main — Vite 8 (rolldown) upgrade#1220
chore(workbench): rebase onto main — Vite 8 (rolldown) upgrade#1220gu-stav wants to merge 52 commits into
Conversation
📦 Bundle Stats —
|
| Metric | Value | vs main (73eb7a2) |
|---|---|---|
| Internal (raw) | 2.6 KB | +483 B, +22.1% |
| Internal (gzip) | 1.0 KB | +238 B, +29.8% |
| Bundled (raw) | 11.28 MB | +148.9 KB, +1.3% |
| Bundled (gzip) | 2.12 MB | +28.0 KB, +1.3% |
| Import time | 885ms | -2ms, -0.2% |
bin:sanity
| Metric | Value | vs main (73eb7a2) |
|---|---|---|
| Internal (raw) | 1023 B | - |
| Internal (gzip) | 486 B | - |
| Bundled (raw) | 9.87 MB | - |
| Bundled (gzip) | 1.77 MB | - |
| Import time | 2.00s | -12ms, -0.6% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-core
Compared against main (73eb7a2a)
| Metric | Value | vs main (73eb7a2) |
|---|---|---|
| Internal (raw) | 103.7 KB | +7.4 KB, +7.7% |
| Internal (gzip) | 25.2 KB | +2.5 KB, +11.1% |
| Bundled (raw) | 21.71 MB | +6.7 KB, +0.0% |
| Bundled (gzip) | 3.45 MB | +3.0 KB, +0.1% |
| Import time | 767ms | -18ms, -2.3% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — create-sanity
Compared against main (73eb7a2a)
| Metric | Value | vs main (73eb7a2) |
|---|---|---|
| Internal (raw) | 908 B | - |
| Internal (gzip) | 483 B | - |
| Bundled (raw) | 931 B | - |
| Bundled (gzip) | 491 B | - |
| Import time | ❌ ChildProcess denied: node | - |
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
Coverage Delta
Comparing 49 changed files against main @ Overall Coverage
|
Preview this PR with pkg.pr.newRun the Sanity CLInpx https://pkg.pr.new/sanity-io/cli/@sanity/cli@cb7a6ff <command>...Or upgrade project dependencies📦
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 4 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f523e53. Configure here.
| if (mode === 'production') { | ||
| // Federation builds don't produce a client bundle — the federation | ||
| // plugin configures its own environment and build entry point. | ||
| if (mode === 'production' && !federation?.enabled) { |
There was a problem hiding this comment.
Federation build ignores minify
Medium Severity
Production rolldown settings (including build.minify from the CLI --minify flag) are only applied when federation is disabled. Federated sanity build calls still pass minify into getViteConfig, but that option is never written to the config for federation builds, so minify on/off may not match user flags or non-federation builds.
Reviewed by Cursor Bugbot for commit f523e53. Configure here.
| outputDir, | ||
| reactCompiler, | ||
| sourceMap, | ||
| }) |
There was a problem hiding this comment.
Federation build skips schema extraction
Medium Severity
When federation is enabled, buildStaticFiles calls getViteConfig without schemaExtraction even though the normal build path passes it. Studio builds can still log that schema extraction is enabled, but the federation Vite pipeline never receives that config, so extraction will not run on federated production builds.
Reviewed by Cursor Bugbot for commit f523e53. Configure here.
| sanityRuntimeRewritePlugin(), | ||
| sanityBuildEntries({autoUpdatesCssUrls, basePath, cwd, importMap, isApp}), | ||
| ...(additionalPlugins || []), | ||
| ]), |
There was a problem hiding this comment.
Federation omits additional Vite plugins
Medium Severity
With federation.enabled, the plugin list includes shared React/schema plugins and @sanity/federation, but not additionalPlugins. Dev startup still passes extras such as sanity/typegen via additionalPlugins, so those plugins never register when federation is on.
Reviewed by Cursor Bugbot for commit f523e53. Configure here.
| isApp: false as const, | ||
| // TODO: fix this non-null assertion | ||
| studioConfigPath: entries.relativeConfigLocation!, | ||
| }), |
There was a problem hiding this comment.
Null studio config path asserted
Low Severity
For federated studio builds, viteFederation receives studioConfigPath: entries.relativeConfigLocation! even though resolveEntries can set relativeConfigLocation to null when no studio config file is found. That forces a non-null path into the federation plugin and can fail at build time.
Reviewed by Cursor Bugbot for commit f523e53. Configure here.
Co-authored-by: Josh <joshua.ellis18@gmail.com> fix(workbench): allow for a dynamic port (#830)
) * feat(dev): forward CLI config organization id to workbench runtime * chore: update auto-generated changeset for PR #905 --------- Co-authored-by: ecospark[bot] <ecospark[bot]@users.noreply.github.com>
Co-authored-by: Gustav Hansen <gustav.hansen@sanity.io>
…913) Pass `reactRefreshHost` to `@vitejs/plugin-react` so federated Studio modules connect their react-refresh preamble to the workbench host, enabling component-level HMR across the module federation boundary. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(dev): disable strict ports for applications * chore: update auto-generated changeset for PR #930 * fix: format * fix: format * chore: update tests --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(workbench): propagate staging env to workbench dev server The workbench dev server was missing the `__SANITY_STAGING__` Vite define that the app/studio dev servers receive via `getViteConfig`. This meant `SANITY_INTERNAL_ENV=staging` had no effect on the workbench client bundle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: update auto-generated changeset for PR #964 --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* fix(workbench): externalize sanity and @sanity/workbench * chore: update auto-generated changeset for PR #971 * chore: exclude .github from oxfmt format check Co-authored-by: Gustav Hansen <gu-stav@users.noreply.github.com> * fix: revert update changeset --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Gustav Hansen <gu-stav@users.noreply.github.com>
Co-authored-by: Gustav Hansen <gu-stav@users.noreply.github.com> Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
* fix(init): do not resolve dist tags * chore: update auto-generated changeset for PR #1000 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* feat(dev): extract studio manifest and pass it for local applications * chore: update auto-generated changeset for PR #997 * fix: rework to use manifests for both * chore: update auto-generated changeset for PR #997 * fix: cleanup * chore: share cache dir constant * feat: extract manifest in background * fix: path resolution on windows * fix: pr feedback * fix: pr feedback --------- Co-Authored-By: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* fix(workbench): remove warmup for dependencies * chore: update auto-generated changeset for PR #1047 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Adds `--federation` / `--no-federation` flag to `sanity init` and wires it through `initAction` so the value is passed to `initApp` / `initStudio` alongside the federation prompt added in #988. The flag plumbing was previously part of the rebase merge that resolved feat/workbench against main, and was dropped in the latest rebase.
* fix(workbench): prune stale lock files * fix: add back * chore: update auto-generated changeset for PR #1057 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(workbench): detect PID reuse on Windows via PowerShell * chore: update auto-generated changeset for PR #1067 * chore(changeset): rewrite changeset summary as user-facing description Co-authored-by: Rune Botten <runeb@users.noreply.github.com> * chore: update auto-generated changeset for PR #1067 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Rune Botten <runeb@users.noreply.github.com>
After rebasing onto main: - buildStudio.ts: plumb `federation` through `InternalBuildOptions` so the `!options.federation?.enabled` guard and the `federation` prop passed to `buildStaticFiles` resolve. Mirrors the same plumbing already done in buildApp.ts during the rebase. - buildStaticFiles.test.ts: `copyDir`/`writeFavicons` moved to `@sanity/cli-build/_internal` in main's #1062 refactor — point the mock at the new path. - startStudioDevServer.test.ts: `checkStudioDependencyVersions` moved to `@sanity/cli-build/_internal`; `getLocalPackageVersion` moved to `@sanity/cli-core` (main's #1062 and #1053). Update mocks accordingly.
Fix stale plugin mock paths and align typegen test assertions with the app dev server output.
* refactor(workbench): drop reactRefreshHost plumbing now that federation owns HMR With `dev.remoteHmr: true` landing in `@module-federation/vite` (via workbench PR sanity-io/workbench#208), the federation plugin wires Fast Refresh through the host automatically. The workbench port no longer needs to leak from `devAction` down through `start{Studio,App}DevServer` → `startDevServer` → `getViteConfig` into `@vitejs/plugin-react`. Removing that field exposed `workbenchAvailable` as the last piece of workbench-derived state on `DevActionOptions`, used only to suppress a URL log suffix in the leaf starters. Hoisted that output into `devAction`, which already owns the "Workbench dev server started at …" line — all dev-server output formatting now lives in one place. Net: the build pipeline has zero awareness of whether a workbench host exists. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: remove .__mf__temp gitignore entry The federation pipeline no longer creates `.__mf__temp` directories, so the gitignore entry (and the test asserting it gets scaffolded) are obsolete. Removes the entry from the template gitignore, the federated fixture, and the bootstrap test, and drops the changeset that introduced the entry since the change is no longer shipping. * fix(workbench): restore dev-server startup log lines The reactRefreshHost cleanup also dropped the "App dev server started on port X" and "...ms and running at http://..." lines from the leaf starters and replaced them with a single "${label} dev server started at ${appUrl}" line in devAction. That changed user-visible text and broke dev.test.ts on every shard. Restore the original log lines (and the workbenchAvailable plumbing they depend on for the no-workbench branch). The reactRefreshHost removal stays untouched — build pipeline still has zero awareness of workbench hosts. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore(deps): bump @sanity/federation to 0.1.0-alpha.8 * test(cli): opt out of @module-federation/vite test-env guard in federated build test --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
The federation work was authored before `@sanity/cli` moved its build/schema vite logic into `@sanity/cli-build`. After rebasing onto main, the two designs collide: getViteConfig now lives in cli-build, so federation's plugin wiring, deps, and shared constants have to follow it across the package boundary. - move `@sanity/federation` dep to cli-build (only getViteConfig uses it) - export `SANITY_CACHE_DIR`/`resolveEntries` from cli-build for the dev server and manifest extraction - drop the inline typegen plugin from getViteConfig; dev already injects it via `additionalPlugins` (main's pattern) - point relocated test mocks at `_internal/build`
* fix(dev): canonicalize watch dirs to long path on Windows `fs.watch` aborts the process on Windows when handed an 8.3 short path (libuv `fs-event.c` assertion `!_wcsnicmp(filename, dir, dirlen)`): the OS reports long-form filenames that fail libuv's prefix check. CI's Windows runners hit this because temp dirs resolve through `RUNNER~1`, crashing the dev-server registry and manifest watchers' vitest worker. Resolve the directory with `realpathSync.native` before watching so the short name expands to its long form. Falls back to the raw path when it can't be resolved, which is no worse than before. * chore: update auto-generated changeset for PR #1156 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Main migrated rollup→rolldown (Vite 8) after the last workbench rebase, so the federation getViteConfig tests still asserted the old rollup API and the lockfile lacked @sanity/federation. Rebuild the vite-config tests on the rolldown assertions while keeping the federation cases, and align the dev-server reactStrictMode test with the branch's current behavior.
…in dev (US3 + US5) (#1149)
The reactStrictMode test from main assumed the './src/App' entry fallback, which #1149 replaced with a no-app-view stub when no entry is declared.
…defineApp (#1236) * feat(init): add --unstable-extension-api flag scaffolding unstable_defineApp * chore: update auto-generated changeset for PR #1236 * chore: update auto-generated changeset for PR #1236 * refactor(init): hide the unstable extension API flag from help while internal-only * refactor(init): rename the workbench opt-in flag to --unstable--workbench * chore: update auto-generated changeset for PR #1236 * chore: update auto-generated changeset for PR #1236 * chore: update auto-generated changeset for PR #1236 * chore: update auto-generated changeset for PR #1236 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
…ball Regenerating the lockfile from a warm cache dropped the integrity field, which breaks frozen installs in the test fixture setup.
f523e53 to
b11f59d
Compare
Move off the pkg.pr.new preview pin now that alpha.10 ships the same work from npm. Drop the pnpm override entirely — the only consumers are @sanity/cli and @sanity/cli-build, which now declare alpha.10 directly, so there's nothing transitive left to force. Also drop the @module-federation/vite release-age exemption it no longer needs.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|


Description
Rebases the workbench feature branch (federation dev server + local apps, #907) onto current
main.The headline of this rebase is the Vite 8 upgrade. Main moved from rollup to rolldown in #1150 (
feat!: upgrade vite to v8, plugin-react to v6) after the last workbench rebase, so the federation build path had to be rewoven onto the new config:getViteConfignow layers federation on top of the rolldown config —rolldownOptionsinstead ofrollupOptions,oxcminify,esmExternalRequirePluginfor import-map externals, and the@rolldown/plugin-babelreact-compiler preset.@sanity/federation@0.1.0-alpha.8, which resolves cleanly against Vite 8.Opened as a separate branch (not pushed onto
feat/workbench) so CI on the Vite 8 rebase can be reviewed first. Once it's green, the branch gets force-pushed ontofeat/workbench.reactStrictModealignment with main's studio pass-through behavior (#1147) is deferred to a separate follow-up PR.What to review
packages/@sanity/cli-build/src/actions/build/getViteConfig.ts— federation woven into the Vite 8 / rolldown config.packages/@sanity/cli-build/src/actions/build/__tests__/getViteConfig.test.ts— rebuilt on the rolldown assertions, federation cases kept.Testing
Build, typecheck, lint, depcheck and the affected
cli-build/cliunit suites pass locally; CI covers the rest.Note
High Risk
Large CLI/dev/build surface area: port splitting, filesystem locks/registry, and a new federation Vite path on rolldown—regressions could break
sanity dev/sanity buildfor both federated and non-federated projects.Overview
Rebases the workbench / federation feature onto current
main, including the Vite 8 (rolldown) toolchain from #1150.Federation in CLI config and builds:
sanity.cligains optionalfederation.enabled. When on,getViteConfigwires in@sanity/federation/vite, passes resolved studio/app entries fromwriteSanityRuntime/resolveEntries, and uses a slimmer plugin set for federation while normal dev still gets favicons/runtime/build-entries. Production federation builds go throughcreateBuilderinbuildStaticFiles(no full runtime/static copy), merge the user’s Vite config, and skip auto-updates import maps.sanity devorchestration:devActionstarts an optional workbench Vite server when federation is on, bumps the studio/app to the next port when workbench holds the default port, registers local apps in a dev-server registry (~/.sanity/.../dev-servers), and broadcasts manifests to workbench over WebSocket. Singleton workbench via lock file, PID-reuse checks (incl. Windows PowerShell), manifest watchers with uncached CLI config reload, and Windows watch-dir canonicalization are part of this pass.Supporting changes:
getCliConfigUncachedfor hot config reload; sharedgetSanityConfigDir/getSanityDataDir; dashboard URL fetch removed;federated-studiofixture; snapshot workflow temporarily targetsfeat/workbench/workbenchdist-tag; many unit tests for registry, workbench, and federation registration.Reviewed by Cursor Bugbot for commit f523e53. Bugbot is set up for automated code reviews on this repo. Configure here.