Skip to content

Commit c69f0f6

Browse files
authored
feat(rsc): ability to merge client reference chunks based on server chunk usage (#767)
1 parent 41e4bf5 commit c69f0f6

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

packages/plugin-rsc/e2e/basic.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,31 @@ test.describe('build-default', () => {
6060
})
6161
})
6262

63+
test.describe('build-server-client-chunks', () => {
64+
const f = useFixture({
65+
root: 'examples/basic',
66+
mode: 'build',
67+
cliOptions: {
68+
env: {
69+
TEST_SERVER_CLIENT_CHUNKS: 'true',
70+
},
71+
},
72+
})
73+
74+
defineTest(f)
75+
76+
test('custom client chunk', async () => {
77+
const { chunks }: { chunks: Rollup.OutputChunk[] } = JSON.parse(
78+
f.createEditor('dist/client/.vite/test.json').read(),
79+
)
80+
const chunk = chunks.find((c) => c.name === 'root')
81+
const expected = [1, 2, 3].map((i) =>
82+
normalizePath(path.join(f.root, `src/routes/chunk/client${i}.tsx`)),
83+
)
84+
expect(chunk?.moduleIds).toEqual(expect.arrayContaining(expected))
85+
})
86+
})
87+
6388
test.describe('dev-non-optimized-cjs', () => {
6489
test.beforeAll(async () => {
6590
// remove explicitly added optimizeDeps.include

packages/plugin-rsc/examples/basic/vite.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ export default defineConfig({
3131
rscCssTransform: false,
3232
copyServerAssetsToClient: (fileName) =>
3333
fileName !== '__server_secret.txt',
34-
clientChunks(id) {
35-
if (id.includes('/src/routes/chunk/')) {
34+
clientChunks(meta) {
35+
if (process.env.TEST_SERVER_CLIENT_CHUNKS) {
36+
return meta.serverChunk
37+
}
38+
if (meta.id.includes('/src/routes/chunk/')) {
3639
return 'custom-chunk'
3740
}
3841
},

packages/plugin-rsc/src/plugin.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type ClientReferenceMeta = {
6363
// build only for tree-shaking unused export
6464
exportNames: string[]
6565
renderedExports: string[]
66+
serverChunk?: string
6667
groupChunkId?: string
6768
}
6869

@@ -185,11 +186,13 @@ export type RscPluginOptions = {
185186
*
186187
* This function allows you to group multiple client components into
187188
* custom chunks instead of having each module in its own chunk.
188-
*
189-
* @param id - The absolute path of the client module
190-
* @returns The chunk name to group this module with, or undefined to use default behavior
191189
*/
192-
clientChunks?: (id: string) => string | undefined
190+
clientChunks?: (meta: {
191+
/** client reference module id */
192+
id: string
193+
/** server chunk which includes a corresponding client reference proxy module */
194+
serverChunk: string
195+
}) => string | undefined
193196
}
194197

195198
/** @experimental */
@@ -1148,7 +1151,10 @@ function vitePluginUseClient(
11481151
manager.clientReferenceGroups = {}
11491152
for (const meta of Object.values(manager.clientReferenceMetaMap)) {
11501153
let name =
1151-
useClientPluginOptions.clientChunks?.(meta.importId) ||
1154+
useClientPluginOptions.clientChunks?.({
1155+
id: meta.importId,
1156+
serverChunk: meta.serverChunk!,
1157+
}) ??
11521158
// use original module id as name by default
11531159
normalizePath(path.relative(manager.config.root, meta.importId))
11541160
name = name.replaceAll('..', '__')
@@ -1261,6 +1267,14 @@ function vitePluginUseClient(
12611267
const meta = manager.clientReferenceMetaMap[id]
12621268
if (meta) {
12631269
meta.renderedExports = mod.renderedExports
1270+
meta.serverChunk =
1271+
(chunk.facadeModuleId ? 'facade:' : 'non-facade:') +
1272+
normalizePath(
1273+
path.relative(
1274+
manager.config.root,
1275+
chunk.facadeModuleId ?? [...chunk.moduleIds].sort()[0]!,
1276+
),
1277+
)
12641278
}
12651279
}
12661280
}

0 commit comments

Comments
 (0)