Skip to content

feat(workbench-cli): generate types for federated remotes#1440

Draft
gu-stav wants to merge 1 commit into
mainfrom
investigate/mf-types
Draft

feat(workbench-cli): generate types for federated remotes#1440
gu-stav wants to merge 1 commit into
mainfrom
investigate/mf-types

Conversation

@gu-stav

@gu-stav gu-stav commented Jul 7, 2026

Copy link
Copy Markdown
Member

Description

Federation type generation is turned off in the workbench CLI, so remotes build without any @mf-types. Turning it back on isn't a one-liner, though: someone tried the naive version in #1282 and had to revert it in #1288.

@module-federation/vite runs the TypeScript compiler over the exposed files using the app's own tsconfig. But our exposed files aren't the app's code, they're small .js/.jsx wrappers the build generates. The compiler won't touch .js without allowJs, and once you add that it starts emitting .d.ts for the app's real source, which falls over on most real projects (TS2742, TS4082).

So hand the compiler its own tsconfig instead of the app's. Two settings do the work: allowJs so it accepts the generated wrappers, and rootDir plus noResolve so it only ever looks at those wrappers and never follows their imports into the app's code. Every wrapper exports the same tiny shape (render, version), so there's nothing app-specific to generate anyway.

Two guardrails: type generation logs and moves on if it hiccups rather than failing the build, and it only prints those errors during sanity dev, not sanity build.

consumeTypes is on as well. Nothing consumes remote types today, but leaving it on means a workbench app that starts loading another app's view gets its types for free. It's inert until then, since nothing configures remotes to consume yet.

What to review

  • plugin-sanity-federation-types.ts: the tsconfig and why each setting is there.
  • plugin-module-federation.ts: the dts block.
  • The dev flag threaded through getViteConfig, workbenchVitePlugins and federation, which is what keeps the errors dev-only.

Testing

generate-types.real.node.test.ts builds a small fixture app for real and checks the @mf-types output actually shows up with the render contract, and that the app's own source never gets compiled into it. It fails on the current (off) build.

@gu-stav gu-stav force-pushed the investigate/mf-types branch 2 times, most recently from a0e770d to 9d4f005 Compare July 7, 2026 09:21
@gu-stav gu-stav changed the title feat(workbench-cli): generate @mf-types for federated remotes feat(workbench-cli): generate types for federated remotes Jul 9, 2026
Type generation was off because @module-federation/vite compiled the
exposes with the app's own tsconfig, which broke on real projects: the
exposes are generated .js/.jsx render-contract shims the compiler rejects
without allowJs, and declaration emit then dragged in the app's noEmit
source (TS2742/TS4082).

Compile from a tsconfig the build owns instead, scoped with noResolve so
only the shims are emitted — the app's own types can never break it.
Best-effort: generation never fails the build, and errors surface in dev
but stay silent in production.
@gu-stav gu-stav force-pushed the investigate/mf-types branch from 9d4f005 to 9b4ed67 Compare July 9, 2026 08:06
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @sanity/cli

Compared against main (fa1edf4b)

@sanity/cli

Metric Value vs main (fa1edf4)
Internal (raw) 2.2 KB -
Internal (gzip) 838 B -
Bundled (raw) 11.16 MB -
Bundled (gzip) 2.10 MB -
Import time 877ms -21ms, -2.4%

bin:sanity

Metric Value vs main (fa1edf4)
Internal (raw) 782 B -
Internal (gzip) 423 B -
Bundled (raw) 9.87 MB -
Bundled (gzip) 1.78 MB -
Import time 2.27s -13ms, -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 (fa1edf4b)

Metric Value vs main (fa1edf4)
Internal (raw) 108.1 KB -
Internal (gzip) 27.0 KB -
Bundled (raw) 21.72 MB -
Bundled (gzip) 3.46 MB -
Import time 775ms +0ms, +0.0%

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

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

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Coverage Delta

File Statements
packages/@sanity/cli-build/src/actions/build/getViteConfig.ts 97.7% (±0%)
packages/@sanity/workbench-cli/src/actions/build/vite/constants.ts 100.0% (±0%)
packages/@sanity/workbench-cli/src/actions/build/vite/plugin.ts 5.0% (±0%)
packages/@sanity/workbench-cli/src/actions/build/vite/plugins/plugin-module-federation.ts 92.8% (±0%)
packages/@sanity/workbench-cli/src/actions/build/vite/plugins/plugin-sanity-federation-types.ts 20.0% (new)
packages/@sanity/workbench-cli/src/actions/build/vite/workbench-vite-plugins.ts 100.0% (±0%)

Comparing 6 changed files against main @ fa1edf4b13539e077880a7205e9b96d3252ae5d2

Overall Coverage

Metric Coverage
Statements 74.2% (- 0.0%)
Branches 64.2% (±0%)
Functions 69.1% (- 0.1%)
Lines 74.7% (- 0.0%)

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