[docs-infra] Add a live demo provider - #1784
Conversation
Deploy previewBundle sizeTotal Size Change: 🔺+5.76KB(+0.17%) - Total Gzip Change: 🔺+2.4KB(+0.27%) Show details for 72 more bundles@mui/internal-docs-infra/useDemoController parsed: 🔺+24B(+0.44%) gzip: 🔺+17B(+0.75%) PerformanceTotal duration: 16.85 ms +0.60 ms(+3.7%) | Renders: 5 (+0) | Paint: 61.06 ms +2.09 ms(+3.5%)
6 tests within noise — details Check out the code infra dashboard for more information about this PR. |
Live editing required a generated `client.ts` per demo: the loader wrote a
file that called `createDemoClient`, which wired the externals and a
controller together. A host that already produces static imports for its
demos had no way to skip that step.
`LiveDemoProvider` is that way. It composes `CodeExternalsContext`,
`useDemoController`, and `CodeControllerContext` into one component, so
wrapping demos in it makes them live with no generated file.
It also takes `globals`, for identifiers a demo mentions at the top level
rather than imports — `process` being the usual one, which would otherwise
be a `ReferenceError` in the runner. Globals bind as locals in the runner's
scope, making it `{ ...globals, import: externals }`, which matches the
shape Material UI's runner already uses. A global cannot displace the
module registry the `require` shim reads, and the host controls exactly
what a demo sees: `{ process: {} }` exposes nothing, so reaching for
`process.env.NODE_ENV` throws and is reported as that variant's error.
`createDemoClient` is unchanged. It wraps a consumer-supplied
`DemoController` rather than this one, so reimplementing it through the
provider would change behaviour for existing consumers.
9e45aac to
b4dde9f
Compare
5ed9f0e to
c19fef3
Compare
Tenth in the docs-infra migration stack, on top of #1783.
Live editing required a generated
client.tsper demo: the loader wrote a file that calledcreateDemoClient, which wired the externals and a controller together. A host that already produces static imports for its demos had no way to skip that step.LiveDemoProvideris that way — it composesCodeExternalsContext,useDemoController, andCodeControllerContextinto one component, so wrapping demos in it makes them live with no generated file:globalsis for identifiers a demo mentions at the top level rather than imports —processbeing the usual one, which would otherwise be aReferenceErrorin the runner. They bind as locals in the runner's scope, making it{ ...globals, import: externals }, the shape Material UI's runner already uses. Two properties worth stating: a global cannot displace the module registry therequireshim reads (nor the always-injectedReact/require), and the host controls exactly what a demo sees —{ process: {} }exposes nothing, so reaching forprocess.env.NODE_ENVthrows and surfaces as that variant's error rather than taking the page down.createDemoClientis unchanged. The strategy suggested reimplementing it through the provider "where practical"; it isn't, because it wraps a consumer-suppliedDemoControllerrather than this one, and rerouting it would change behaviour for existing consumers.Gate: 10 new unit tests (provider composition and context stability, globals reaching the runner scope, a bound global, a forbidden
processproperty access), 5,579 unit tests, 39 browser tests across chromium, firefox, and webkit, plus a clean typecheck, lint, anddocs:validate. The 41user.spec.tsfailures are the pre-existing ones.