Skip to content

Commit dc239d6

Browse files
hi-ogawaclaude
andcommitted
feat(rsc): expose builder.rsc API for custom build pipelines
Add `customBuildApp` option that allows downstream frameworks to skip the default buildApp orchestration and implement their own build order using the exposed `builder.rsc` API. When `customBuildApp: true`: - Default 4/5-step build orchestration is skipped - `builder.rsc.manager` provides access to RscPluginManager - `builder.rsc.writeAssetsManifest()` writes manifest to appropriate environments Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8527360 commit dc239d6

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

packages/plugin-rsc/src/plugin.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ export type RscPluginOptions = {
186186
*/
187187
useBuildAppHook?: boolean
188188

189+
/**
190+
* Skip the default buildApp orchestration and expose utilities on `builder.rsc`
191+
* for downstream frameworks to implement custom build pipelines.
192+
* @experimental
193+
* @default false
194+
*/
195+
customBuildApp?: boolean
196+
189197
/**
190198
* Custom environment configuration
191199
* @experimental
@@ -383,9 +391,31 @@ export default function vitePluginRsc(
383391
}
384392
}
385393

394+
function getManifestEnvironments(builder: vite.ViteBuilder): string[] {
395+
if (!builder.environments.ssr?.config.build.rollupOptions.input) {
396+
return ['rsc']
397+
}
398+
return ['ssr', 'rsc']
399+
}
400+
386401
let hasReactServerDomWebpack = false
387402

388403
return [
404+
{
405+
name: 'rsc:builder-api',
406+
buildApp: {
407+
order: 'pre' as const,
408+
async handler(builder) {
409+
builder.rsc = {
410+
manager,
411+
writeAssetsManifest: async () => {
412+
const envNames = getManifestEnvironments(builder)
413+
writeAssetsManifest(envNames)
414+
},
415+
}
416+
},
417+
},
418+
},
389419
{
390420
name: 'rsc',
391421
async config(config, env) {
@@ -509,6 +539,9 @@ export default function vitePluginRsc(
509539
sharedPlugins: true,
510540
sharedConfigBuild: true,
511541
async buildApp(builder) {
542+
if (rscPluginOptions.customBuildApp) {
543+
return
544+
}
512545
if (!rscPluginOptions.useBuildAppHook) {
513546
await buildApp(builder)
514547
}
@@ -523,6 +556,9 @@ export default function vitePluginRsc(
523556
},
524557
buildApp: {
525558
async handler(builder) {
559+
if (rscPluginOptions.customBuildApp) {
560+
return
561+
}
526562
if (rscPluginOptions.useBuildAppHook) {
527563
await buildApp(builder)
528564
}

packages/plugin-rsc/types/index.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ declare module 'vite' {
1717
/** Options for `@vitejs/plugin-rsc` */
1818
rsc?: import('@vitejs/plugin-rsc').RscPluginOptions
1919
}
20+
21+
interface ViteBuilder {
22+
/**
23+
* RSC plugin API exposed for custom build pipelines.
24+
* Available when using `rsc({ customBuildApp: true })`.
25+
* @experimental
26+
*/
27+
rsc: {
28+
/** Access to internal RscPluginManager for controlling build phases */
29+
manager: import('@vitejs/plugin-rsc').RscPluginManager
30+
/** Write assets manifest to appropriate environments (ssr, rsc) */
31+
writeAssetsManifest(): Promise<void>
32+
}
33+
}
2034
}
2135

2236
export {}

0 commit comments

Comments
 (0)