Skip to content

refactor: Move more build/schema logic to cli-build package#1130

Merged
snocorp merged 10 commits into
mainfrom
cli-build-render-document
May 28, 2026
Merged

refactor: Move more build/schema logic to cli-build package#1130
snocorp merged 10 commits into
mainfrom
cli-build-render-document

Conversation

@snocorp
Copy link
Copy Markdown
Contributor

@snocorp snocorp commented May 22, 2026

Description

This PR moves build and schema logic into the cli-build package in preparation for allowing runtime-cli to execute build logic during deployment.

Testing

Updated tests as needed.


Note

Medium Risk
Breaking change for any consumer of @sanity/cli-build/_internal; studio build, deploy, and schema flows are touched across many entry points, though behavior is largely a move with dependency injection for env vars.

Overview
@sanity/cli-build no longer exposes a single @sanity/cli-build/_internal entry. Public internals are split into @sanity/cli-build/_internal/build (Vite config, runtime HTML, favicons, vendor deps, build telemetry) and @sanity/cli-build/_internal/extract (schema extraction, validation formatting, pattern matching, extract telemetry). The package picks up the build stack it actually uses (Vite, React, chokidar, etc.) and TSX/JSX build support.

@sanity/cli now consumes those subpaths instead of owning duplicate build/schema modules: studio/app build, dev/preview servers, deploy, and schema/manifest/graphql commands import from cli-build. Env injection for Vite is passed in via a getEnvironmentVariables callback on getViteConfig (CLI still supplies app vs studio env helpers). Some telemetry types moved next to the logic in cli-build. A few CLI-only deps were dropped from @sanity/cli where logic moved.

Tests were updated to mock the new import paths; shared createMockHttpServer / createMockWatcher helpers moved from CLI test utils into @sanity/cli-test. E2e/tsconfig path mapping uses @sanity/cli-build/* for the split exports. Changeset marks a minor bump for @sanity/cli-build due to the export break.

Reviewed by Cursor Bugbot for commit 3b8e93c. Bugbot is set up for automated code reviews on this repo. Configure here.

@snocorp snocorp self-assigned this May 22, 2026
@snocorp snocorp requested a review from a team as a code owner May 22, 2026 19:29
@claude
Copy link
Copy Markdown

claude Bot commented May 22, 2026

Claude finished @snocorp's task in 4m 55s —— View job


Review

Mostly file moves with sensible package boundaries. A few items worth a look:

Issues

1. Bundle stats no longer tracks @sanity/cli-build (.github/workflows/bundle-stats.yml)
The TODO to add cli-build was removed and the package was excluded from the workflow. Given this PR moves Vite, React, node-html-parser, lodash-es, etc. into cli-build, the package is now large enough that untracked size regressions are a real risk. The tool fails with No "exports" or "bin" entries found in @sanity/cli-build because bundle-stats doesn't understand subpath exports without a top-level . entry. Worth opening a follow-up to either add a . entry that re-exports the internals or extend bundle-stats to understand subpaths.

2. _internal/build still transitively pulls in extract code (packages/@sanity/cli-build/src/actions/build/getViteConfig.ts:15)
The stated goal (per commit b023c56) is "to prevent importing vite during extract logic." The split achieves that one-direction (_internal/extract is vite-free), but _internal/build imports sanitySchemaExtractionPlugin from ../schema/vite/plugin-schema-extraction.js, which pulls in runSchemaExtraction. So _internal/build consumers still get the extract code. This is fine if the goal is "extract without vite," but if you also want "build without schema extraction" that's not realized here. Likely intentional — flagging in case it isn't.

3. Cursor bot's "leftover env var mocks" comment is already resolved (packages/@sanity/cli-build/src/actions/build/__tests__/getViteConfig.test.ts)
Verified — getAppEnvironmentVariables / getStudioEnvironmentVariables are not mocked in the current test file. No action needed.

Changeset

.changeset/fifty-sheep-strive.md is present with a minor bump. The bump type is appropriate (pre-v1 0.x minor acts like a major; existing @sanity/cli references via workspace:^ resolve to ^0.1.1 which won't accept 0.2.0). The summary "Split up exports into build and extract modules." is accurate but very terse — consider something more user-facing like:

The `@sanity/cli-build/_internal` entry point has been removed and split into `_internal/build` and `_internal/extract`. Update imports accordingly.

This better serves anyone (incl. runtime-cli) upgrading across the break.

Nits

  • packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/tryLoadDocumentComponent.ts:26: err.code !== 'ERR_MODULE_NOT_FOUND' assumes err has a code field — if the import fails with a non-Error rejection this throws on the access. Pre-existing, not introduced here, just noting it survived the move.
  • packages/@sanity/cli-test/src/test/createMockWatcher.ts and createMockHttpServer.ts are exported from the package root (src/index.ts). These are vitest-coupled (one imports vi from vitest) — since vitest is already a peerDep this works, but they're not test-runner-agnostic. Worth confirming you're OK with these being part of the public surface of @sanity/cli-test.
    · Branch

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

📦 Bundle Stats — @sanity/cli

Compared against main (cd110e7c)

@sanity/cli

Metric Value vs main (cd110e7)
Internal (raw) 2.1 KB -
Internal (gzip) 799 B -
Bundled (raw) 10.97 MB -
Bundled (gzip) 2.06 MB -
Import time 829ms +9ms, +1.2%

bin:sanity

Metric Value vs main (cd110e7)
Internal (raw) 1023 B -
Internal (gzip) 486 B -
Bundled (raw) 9.87 MB -
Bundled (gzip) 1.77 MB -
Import time 1.94s +217ms, +12.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 (cd110e7c)

Metric Value vs main (cd110e7)
Internal (raw) 96.3 KB -
Internal (gzip) 22.7 KB -
Bundled (raw) 21.64 MB -
Bundled (gzip) 3.43 MB -
Import time 800ms +11ms, +1.4%

🗺️ 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 (cd110e7c)

Metric Value vs main (cd110e7)
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.

Comment thread packages/@sanity/cli-build/src/actions/build/__tests__/getViteConfig.test.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

Coverage Delta

File Statements
packages/@sanity/cli-build/src/actions/build/buildVendorDependencies.ts 67.4% (new)
packages/@sanity/cli-build/src/actions/build/createExternalFromImportMap.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/decorateIndexWithAutoGeneratedWarning.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/decorateIndexWithBridgeScript.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/decorateIndexWithStagingScript.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/getEntryModule.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/getPossibleDocumentComponentLocations.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/getViteConfig.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/normalizeBasePath.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocument.ts 38.5% (new)
packages/@sanity/cli-build/src/actions/build/renderDocument.worker.ts 0.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/components/BasicDocument.tsx 25.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/components/DefaultDocument.tsx 40.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/components/Favicons.tsx 0.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/components/GlobalErrorHandler.tsx 50.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/components/NoJavascript.tsx 50.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/getDocumentComponent.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/getDocumentHtml.tsx 94.1% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/renderDocumentWorker.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/renderDocumentWorker/tryLoadDocumentComponent.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/build/vite/plugin-sanity-build-entries.ts 86.4% (new)
packages/@sanity/cli-build/src/actions/build/vite/plugin-sanity-favicons.ts 18.8% (new)
packages/@sanity/cli-build/src/actions/build/vite/plugin-sanity-runtime-rewrite.ts 50.0% (new)
packages/@sanity/cli-build/src/actions/build/writeSanityRuntime.ts 95.5% (new)
packages/@sanity/cli-build/src/actions/schema/formatSchemaValidation.ts 97.9% (new)
packages/@sanity/cli-build/src/actions/schema/matchSchemaPattern.ts 100.0% (new)
packages/@sanity/cli-build/src/actions/schema/vite/plugin-schema-extraction.ts 91.3% (new)
packages/@sanity/cli-build/src/constants.ts 100.0% (new)
packages/@sanity/cli-build/src/telemetry/build.telemetry.ts 100.0% (new)
packages/@sanity/cli-build/src/telemetry/extractSchema.telemetry.ts 100.0% (new)
packages/@sanity/cli/src/actions/build/buildApp.ts 95.3% (±0%)
packages/@sanity/cli/src/actions/build/buildStaticFiles.ts 96.7% (+ 0.1%)
packages/@sanity/cli/src/actions/build/buildStudio.ts 96.7% (±0%)
packages/@sanity/cli/src/actions/deploy/deployStudio.ts 92.5% (±0%)
packages/@sanity/cli/src/actions/deploy/deployStudioSchemasAndManifests.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/deploy/deployStudioSchemasAndManifests.worker.ts 0.0% (±0%)
packages/@sanity/cli/src/actions/dev/startStudioDevServer.ts 95.0% (±0%)
packages/@sanity/cli/src/actions/graphql/SchemaError.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/manifest/extractManifest.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/manifest/extractManifest.worker.ts 0.0% (±0%)
packages/@sanity/cli/src/actions/schema/deploySchemas.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/schema/extractSanityWorkspace.worker.ts 0.0% (±0%)
packages/@sanity/cli/src/actions/schema/extractSchema.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/schema/extractSchemaWatcher.ts 64.9% (±0%)
packages/@sanity/cli/src/actions/schema/getExtractOptions.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/schema/validateAction.ts 97.4% (±0%)
packages/@sanity/cli/src/actions/schema/watchExtractSchema.ts 96.3% (±0%)
packages/@sanity/cli/src/commands/manifest/extract.ts 100.0% (±0%)
packages/@sanity/cli/src/commands/schemas/deploy.ts 95.0% (±0%)
packages/@sanity/cli/src/server/devServer.ts 94.4% (+ 0.3%)
packages/@sanity/cli/src/server/previewServer.ts 97.2% (±0%)

Comparing 52 changed files against main @ 96f06469a774b6ec8d21a41de3d0c6cba8f59558

Overall Coverage

Metric Coverage
Statements 84.3% (±0%)
Branches 74.3% (- 0.0%)
Functions 84.2% (+ 0.0%)
Lines 84.8% (±0%)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 26, 2026

Preview this PR with pkg.pr.new

Run the Sanity CLI

npx https://pkg.pr.new/sanity-io/cli/@sanity/cli@3b8e93c <command>

...Or upgrade project dependencies

📦 @sanity/cli
pnpm install https://pkg.pr.new/@sanity/cli@3b8e93c
📦 @sanity/cli-build
pnpm install https://pkg.pr.new/@sanity/cli-build@3b8e93c
📦 @sanity/cli-core
pnpm install https://pkg.pr.new/@sanity/cli-core@3b8e93c
📦 @sanity/cli-test
pnpm install https://pkg.pr.new/@sanity/cli-test@3b8e93c
📦 @sanity/eslint-config-cli
pnpm install https://pkg.pr.new/@sanity/eslint-config-cli@3b8e93c

View Commit (3b8e93c)

macdonst
macdonst previously approved these changes May 26, 2026
Copy link
Copy Markdown

@macdonst macdonst left a comment

Choose a reason for hiding this comment

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

LGTM Dave, it's mostly file moves anyway so it's not as terrible to review as the 67 changed files might indicate.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

Bundle Stats — An error occurred while calculating bundle sizes.

Error details
From https://github.com/sanity-io/cli
 * branch            cd110e7c2b0cdad7438f53d958a0831fea2a3773 -> FETCH_HEAD
Building baseline...

Attention:
Turborepo now collects completely anonymous telemetry regarding usage.
This information is used to shape the Turborepo roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://turborepo.dev/docs/telemetry

Measuring baseline for packages/@sanity/cli
Found 1 exports and 1 bin entries
Measuring internal sizes...
Bundling @sanity/cli...
"fsevents" is imported by "node_modules/.pnpm/rollup@4.60.2/node_modules/rollup/dist/es/shared/node-entry.js", but could not be resolved – treating it as an external dependency.
Bundling bin:sanity...
Benchmarking import @sanity/cli (1/2)...
Benchmarking import bin:sanity (2/2)...
Measuring baseline for packages/@sanity/cli-build
Error: No "exports" or "bin" entries found in @sanity/cli-build. At least one must be present in package.json.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0089805. Configure here.

Comment thread .github/workflows/bundle-stats.yml
rexxars
rexxars previously approved these changes May 27, 2026
Copy link
Copy Markdown
Member

@rexxars rexxars left a comment

Choose a reason for hiding this comment

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

Approving, but see comment - could be the safest approach would be to bump to 0.2.0

Comment on lines +31 to 38
"./_internal/build": {
"source": "./src/_exports/_internal/build.ts",
"default": "./dist/_exports/_internal/build.js"
},
"./_internal/extract": {
"source": "./src/_exports/_internal/extract.ts",
"default": "./dist/_exports/_internal/extract.js"
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm perhaps being overly cautious here, but:

Given @sanity/cli-build is a dependency of @sanity/cli, and uses ^ (not pinned versions), there could conceivably be a situation where an old version of the CLI uses the latest version of @sanity/cli-build. In that case, the removal of @sanity/cli-build/_internal would break.

Again, might be a bit overly defensive here - but potentially this should be marked as a breaking to force a new major of the package, or we could use ./internal-extract or some such and leave the old _internal in place

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

…but if going with the latter approach, we'd need to make sure that the shape of _internal matches what it was (eg generateWebManifest was part of it previously but seems to be removed from the new)

Copy link
Copy Markdown
Contributor Author

@snocorp snocorp May 28, 2026

Choose a reason for hiding this comment

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

Yes, you're correct. Good call. Added a changeset to do a minor bump. I don't think we need backward compat here because it's pre-v1. At least that was my intention. I'll make it v1 once it's finished and stable.

Copy link
Copy Markdown

@ryanbethel ryanbethel left a comment

Choose a reason for hiding this comment

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

Just reviewing the most recent changes since the other more in depth reviews previously. This looks good.

@snocorp snocorp merged commit 6165c80 into main May 28, 2026
56 checks passed
@snocorp snocorp deleted the cli-build-render-document branch May 28, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants