From c1e53b80e5f3aff5e1a575ee3c2a38fea03584da Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 16:29:06 +0900 Subject: [PATCH 1/9] fix(rsc): tree-shake unused client reference module and fix build error --- .../plugin-rsc/examples/starter/package.json | 1 + .../plugin-rsc/examples/starter/src/root.tsx | 7 +++ packages/plugin-rsc/src/plugin.ts | 7 ++- pnpm-lock.yaml | 52 +++++++++++++++++-- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/packages/plugin-rsc/examples/starter/package.json b/packages/plugin-rsc/examples/starter/package.json index 6cc65d40..05a37375 100644 --- a/packages/plugin-rsc/examples/starter/package.json +++ b/packages/plugin-rsc/examples/starter/package.json @@ -18,6 +18,7 @@ "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "latest", "@vitejs/plugin-rsc": "latest", + "react-tweet": "^3.2.2", "rsc-html-stream": "^0.0.7", "vite": "^7.1.4" } diff --git a/packages/plugin-rsc/examples/starter/src/root.tsx b/packages/plugin-rsc/examples/starter/src/root.tsx index c6a64970..b439efac 100644 --- a/packages/plugin-rsc/examples/starter/src/root.tsx +++ b/packages/plugin-rsc/examples/starter/src/root.tsx @@ -4,6 +4,13 @@ import { getServerCounter, updateServerCounter } from './action.tsx' import reactLogo from './assets/react.svg' import { ClientCounter } from './client.tsx' +// repro +import { Tweet } from 'react-tweet' +console.log(Tweet) +// import { useTweet } from 'react-tweet'; +// console.log(useTweet) +// repro + export function Root(props: { url: URL }) { return ( diff --git a/packages/plugin-rsc/src/plugin.ts b/packages/plugin-rsc/src/plugin.ts index 99f979a8..2ffc8013 100644 --- a/packages/plugin-rsc/src/plugin.ts +++ b/packages/plugin-rsc/src/plugin.ts @@ -1226,12 +1226,14 @@ function vitePluginUseClient( // group client reference modules by `clientChunks` option manager.clientReferenceGroups = {} for (const meta of Object.values(manager.clientReferenceMetaMap)) { + // no server chunk associated when the module is tree-shaken + if (!meta.serverChunk) continue let name = useClientPluginOptions.clientChunks?.({ id: meta.importId, normalizedId: manager.toRelativeId(meta.importId), - serverChunk: meta.serverChunk!, - }) ?? meta.serverChunk! + serverChunk: meta.serverChunk, + }) ?? meta.serverChunk // ensure clean virtual id to avoid interfering with other plugins name = cleanUrl(name.replaceAll('..', '__')) const group = (manager.clientReferenceGroups[name] ??= []) @@ -1333,6 +1335,7 @@ function vitePluginUseClient( } }, generateBundle(_options, bundle) { + if (manager.isScanBuild) return if (this.environment.name !== serverEnvironmentName) return // analyze rsc build to inform later client reference building. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 839f1e5e..88c5f96d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,7 +146,7 @@ importers: version: 1.0.0-beta.35 '@swc/core': specifier: ^1.13.5 - version: 1.13.5 + version: 1.13.5(@swc/helpers@0.5.17) devDependencies: '@playwright/test': specifier: ^1.55.0 @@ -548,6 +548,9 @@ importers: '@vitejs/test-dep-transitive-use-sync-external-store': specifier: file:./test-dep/transitive-use-sync-external-store version: file:packages/plugin-rsc/examples/basic/test-dep/transitive-use-sync-external-store(react@19.1.1) + react-tweet: + specifier: ^3.2.2 + version: 3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rsc-html-stream: specifier: ^0.0.7 version: 0.0.7 @@ -718,6 +721,9 @@ importers: '@vitejs/plugin-rsc': specifier: latest version: link:../.. + react-tweet: + specifier: ^3.2.2 + version: 3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rsc-html-stream: specifier: ^0.0.7 version: 0.0.7 @@ -2157,6 +2163,9 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/plugin-emotion@11.1.0': resolution: {integrity: sha512-R/Gm79HPsZTeXWOa/66yrlmBU4QHDX2Xq2N4p/Fg86TKbRLVrpxO5+yRm7jfHw1MbQDemL1x5yUAm6eKU6LDjw==} @@ -2762,6 +2771,10 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -4021,6 +4034,12 @@ packages: react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-tweet@3.2.2: + resolution: {integrity: sha512-hIkxAVPpN2RqWoDEbo3TTnN/pDcp9/Jb6pTgiA4EbXa9S+m2vHIvvZKHR+eS0PDIsYqe+zTmANRa5k6+/iwGog==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -4329,6 +4348,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + swr@2.3.6: + resolution: {integrity: sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + tailwindcss@4.1.13: resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} @@ -5680,7 +5704,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.13.5': optional: true - '@swc/core@1.13.5': + '@swc/core@1.13.5(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.24 @@ -5695,9 +5719,14 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.13.5 '@swc/core-win32-ia32-msvc': 1.13.5 '@swc/core-win32-x64-msvc': 1.13.5 + '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.17': + dependencies: + tslib: 2.8.1 + '@swc/plugin-emotion@11.1.0': dependencies: '@swc/counter': 0.1.3 @@ -6293,6 +6322,8 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.0.0 + clsx@2.1.1: {} + collapse-white-space@2.1.0: {} color-convert@2.0.1: @@ -7747,6 +7778,14 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) + react-tweet@3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + dependencies: + '@swc/helpers': 0.5.17 + clsx: 2.1.1 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + swr: 2.3.6(react@19.1.1) + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -8076,6 +8115,12 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + swr@2.3.6(react@19.1.1): + dependencies: + dequal: 2.0.3 + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) + tailwindcss@4.1.13: {} tapable@2.2.1: {} @@ -8156,8 +8201,7 @@ snapshots: tslib@2.6.2: {} - tslib@2.8.1: - optional: true + tslib@2.8.1: {} turbo-stream@3.1.0: {} From cfcdc5a87458b6b5f3e8ffefd0761cb9b06a71c1 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 16:33:55 +0900 Subject: [PATCH 2/9] chore: lockfile --- pnpm-lock.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88c5f96d..0ad33942 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,9 +548,6 @@ importers: '@vitejs/test-dep-transitive-use-sync-external-store': specifier: file:./test-dep/transitive-use-sync-external-store version: file:packages/plugin-rsc/examples/basic/test-dep/transitive-use-sync-external-store(react@19.1.1) - react-tweet: - specifier: ^3.2.2 - version: 3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rsc-html-stream: specifier: ^0.0.7 version: 0.0.7 From 8e2c31ce4914d099edfeb694906f2efa6a8f7d4f Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 16:40:53 +0900 Subject: [PATCH 3/9] chore: cleanup --- packages/plugin-rsc/examples/basic/package.json | 1 + packages/plugin-rsc/examples/basic/src/routes/root.tsx | 4 ++++ .../examples/basic/src/routes/tree-shake2/lib-client1.tsx | 0 .../examples/basic/src/routes/tree-shake2/lib-client2.tsx | 0 .../examples/basic/src/routes/tree-shake2/lib-server1.tsx | 0 .../examples/basic/src/routes/tree-shake2/lib-server2.tsx | 0 .../examples/basic/src/routes/tree-shake2/lib.tsx | 0 .../examples/basic/src/routes/tree-shake2/server.tsx | 1 + packages/plugin-rsc/examples/starter/src/root.tsx | 7 ------- pnpm-lock.yaml | 3 +++ 10 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx create mode 100644 packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx create mode 100644 packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx create mode 100644 packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx create mode 100644 packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx create mode 100644 packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx diff --git a/packages/plugin-rsc/examples/basic/package.json b/packages/plugin-rsc/examples/basic/package.json index 246c8de7..63a6519f 100644 --- a/packages/plugin-rsc/examples/basic/package.json +++ b/packages/plugin-rsc/examples/basic/package.json @@ -28,6 +28,7 @@ "@vitejs/test-dep-server-in-server": "file:./test-dep/server-in-server", "@vitejs/test-dep-transitive-cjs": "file:./test-dep/transitive-cjs", "@vitejs/test-dep-transitive-use-sync-external-store": "file:./test-dep/transitive-use-sync-external-store", + "react-tweet": "^3.2.2", "rsc-html-stream": "^0.0.7", "tailwindcss": "^4.1.13", "vite": "^7.1.4", diff --git a/packages/plugin-rsc/examples/basic/src/routes/root.tsx b/packages/plugin-rsc/examples/basic/src/routes/root.tsx index aa16feba..04b6d77d 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/root.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/root.tsx @@ -46,6 +46,10 @@ import { TestHmrClientDep3 } from './hmr-client-dep3/server' import { TestChunk2 } from './chunk2/server' import { TestUseId } from './use-id/server' +// repro +import { Tweet } from 'react-tweet' +console.log(Tweet) + export function Root(props: { url: URL }) { return ( diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx new file mode 100644 index 00000000..94b7a588 --- /dev/null +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx @@ -0,0 +1 @@ +export function TestTreeShake2() {} diff --git a/packages/plugin-rsc/examples/starter/src/root.tsx b/packages/plugin-rsc/examples/starter/src/root.tsx index b439efac..c6a64970 100644 --- a/packages/plugin-rsc/examples/starter/src/root.tsx +++ b/packages/plugin-rsc/examples/starter/src/root.tsx @@ -4,13 +4,6 @@ import { getServerCounter, updateServerCounter } from './action.tsx' import reactLogo from './assets/react.svg' import { ClientCounter } from './client.tsx' -// repro -import { Tweet } from 'react-tweet' -console.log(Tweet) -// import { useTweet } from 'react-tweet'; -// console.log(useTweet) -// repro - export function Root(props: { url: URL }) { return ( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0ad33942..88c5f96d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,6 +548,9 @@ importers: '@vitejs/test-dep-transitive-use-sync-external-store': specifier: file:./test-dep/transitive-use-sync-external-store version: file:packages/plugin-rsc/examples/basic/test-dep/transitive-use-sync-external-store(react@19.1.1) + react-tweet: + specifier: ^3.2.2 + version: 3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rsc-html-stream: specifier: ^0.0.7 version: 0.0.7 From 67f44680c63345935470346661a8b3f688729a8a Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 16:41:45 +0900 Subject: [PATCH 4/9] chore: comment --- packages/plugin-rsc/src/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-rsc/src/plugin.ts b/packages/plugin-rsc/src/plugin.ts index 2ffc8013..13b36d15 100644 --- a/packages/plugin-rsc/src/plugin.ts +++ b/packages/plugin-rsc/src/plugin.ts @@ -1226,7 +1226,7 @@ function vitePluginUseClient( // group client reference modules by `clientChunks` option manager.clientReferenceGroups = {} for (const meta of Object.values(manager.clientReferenceMetaMap)) { - // no server chunk associated when the module is tree-shaken + // no server chunk is associated when the entire "use client" module is tree-shaken if (!meta.serverChunk) continue let name = useClientPluginOptions.clientChunks?.({ From 7ba1eff947aee70b4c030245a127fe5984a447fc Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 16:57:39 +0900 Subject: [PATCH 5/9] test: add e2e --- .../plugin-rsc/examples/basic/src/routes/root.tsx | 6 ++---- .../basic/src/routes/tree-shake2/lib-client1.tsx | 5 +++++ .../basic/src/routes/tree-shake2/lib-client2.tsx | 5 +++++ .../basic/src/routes/tree-shake2/lib-server1.tsx | 3 +++ .../basic/src/routes/tree-shake2/lib-server2.tsx | 3 +++ .../examples/basic/src/routes/tree-shake2/lib.tsx | 4 ++++ .../examples/basic/src/routes/tree-shake2/server.tsx | 11 ++++++++++- 7 files changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/plugin-rsc/examples/basic/src/routes/root.tsx b/packages/plugin-rsc/examples/basic/src/routes/root.tsx index 04b6d77d..42951874 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/root.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/root.tsx @@ -39,6 +39,7 @@ import { TestAssetsServer } from './assets/server' import { TestHmrSwitchServer } from './hmr-switch/server' import { TestHmrSwitchClient } from './hmr-switch/client' import { TestTreeShakeServer } from './tree-shake/server' +import { TestTreeShake2 } from './tree-shake2/server' import { TestClientChunkServer } from './chunk/server' import { TestTailwind } from './tailwind' import { TestHmrClientDep2 } from './hmr-client-dep2/client' @@ -46,10 +47,6 @@ import { TestHmrClientDep3 } from './hmr-client-dep3/server' import { TestChunk2 } from './chunk2/server' import { TestUseId } from './use-id/server' -// repro -import { Tweet } from 'react-tweet' -console.log(Tweet) - export function Root(props: { url: URL }) { return ( @@ -104,6 +101,7 @@ export function Root(props: { url: URL }) { + diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx index e69de29b..6c87c033 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx @@ -0,0 +1,5 @@ +'use client' + +export function LibClient1() { + return 'test-tree-shake-lib-client1' +} diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx index e69de29b..622baebb 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx @@ -0,0 +1,5 @@ +'use client' + +export function LibClient2() { + return 'test-tree-shake-lib-client2' +} diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx index e69de29b..ae6f3265 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx @@ -0,0 +1,3 @@ +export function LibServer1() { + return 'test-tree-shake-lib-server1' +} diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx index e69de29b..41dafc41 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx @@ -0,0 +1,3 @@ +export function LibServer2() { + return 'test-tree-shake-lib-server2' +} diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx index e69de29b..76d4c3c2 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib.tsx @@ -0,0 +1,4 @@ +export * from './lib-client1' +export * from './lib-client2' +export * from './lib-server1' +export * from './lib-server2' diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx index 94b7a588..39e2652d 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/server.tsx @@ -1 +1,10 @@ -export function TestTreeShake2() {} +import { LibClient1, LibServer1 } from './lib' + +export function TestTreeShake2() { + return ( +
+ test-tree-shake2: + | +
+ ) +} From ef596d1c8b34854c54879a79844d660619f75e97 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 17:05:02 +0900 Subject: [PATCH 6/9] chore: tweak --- .../examples/basic/src/routes/tree-shake2/lib-client1.tsx | 2 +- .../examples/basic/src/routes/tree-shake2/lib-client2.tsx | 2 +- .../examples/basic/src/routes/tree-shake2/lib-server1.tsx | 2 +- .../examples/basic/src/routes/tree-shake2/lib-server2.tsx | 2 +- packages/plugin-rsc/examples/basic/vite.config.ts | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx index 6c87c033..df4f7bfd 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client1.tsx @@ -1,5 +1,5 @@ 'use client' export function LibClient1() { - return 'test-tree-shake-lib-client1' + return 'lib-client1' } diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx index 622baebb..4bb13bd3 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-client2.tsx @@ -1,5 +1,5 @@ 'use client' export function LibClient2() { - return 'test-tree-shake-lib-client2' + return 'lib-client2:__unused_tree_shake2__' } diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx index ae6f3265..ff764017 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server1.tsx @@ -1,3 +1,3 @@ export function LibServer1() { - return 'test-tree-shake-lib-server1' + return 'lib-server1' } diff --git a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx index 41dafc41..22bb7efc 100644 --- a/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx +++ b/packages/plugin-rsc/examples/basic/src/routes/tree-shake2/lib-server2.tsx @@ -1,3 +1,3 @@ export function LibServer2() { - return 'test-tree-shake-lib-server2' + return 'lib-server2:__unused_tree_shake2__' } diff --git a/packages/plugin-rsc/examples/basic/vite.config.ts b/packages/plugin-rsc/examples/basic/vite.config.ts index 144117f2..3da96ca2 100644 --- a/packages/plugin-rsc/examples/basic/vite.config.ts +++ b/packages/plugin-rsc/examples/basic/vite.config.ts @@ -47,6 +47,7 @@ export default defineConfig({ if (chunk.type === 'chunk') { assert(!chunk.code.includes('__unused_client_reference__')) assert(!chunk.code.includes('__unused_server_export__')) + assert(!chunk.code.includes('__unused_tree_shake2__')) } } }, From 585061bba57c07518f5517091052893d38c5d17a Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 17:07:05 +0900 Subject: [PATCH 7/9] test: more --- packages/plugin-rsc/e2e/basic.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/plugin-rsc/e2e/basic.test.ts b/packages/plugin-rsc/e2e/basic.test.ts index 99163871..7e9f4880 100644 --- a/packages/plugin-rsc/e2e/basic.test.ts +++ b/packages/plugin-rsc/e2e/basic.test.ts @@ -1454,4 +1454,12 @@ function defineTest(f: Fixture) { 'test-chunk1|test-chunk2|test-chunk2b|test-chunk3|test-chunk3', ) }) + + test('tree-shake2', async ({ page }) => { + await page.goto(f.url()) + await waitForHydration(page) + await expect(page.getByTestId('test-tree-shake2')).toHaveText( + 'test-tree-shake2:lib-client1|lib-server1', + ) + }) } From 6a390d45412b79c78b4bddb4925eeb1f1f70cd3d Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 17:08:16 +0900 Subject: [PATCH 8/9] chore: cleanup --- packages/plugin-rsc/examples/basic/package.json | 1 - pnpm-lock.yaml | 3 --- 2 files changed, 4 deletions(-) diff --git a/packages/plugin-rsc/examples/basic/package.json b/packages/plugin-rsc/examples/basic/package.json index 63a6519f..246c8de7 100644 --- a/packages/plugin-rsc/examples/basic/package.json +++ b/packages/plugin-rsc/examples/basic/package.json @@ -28,7 +28,6 @@ "@vitejs/test-dep-server-in-server": "file:./test-dep/server-in-server", "@vitejs/test-dep-transitive-cjs": "file:./test-dep/transitive-cjs", "@vitejs/test-dep-transitive-use-sync-external-store": "file:./test-dep/transitive-use-sync-external-store", - "react-tweet": "^3.2.2", "rsc-html-stream": "^0.0.7", "tailwindcss": "^4.1.13", "vite": "^7.1.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88c5f96d..0ad33942 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,9 +548,6 @@ importers: '@vitejs/test-dep-transitive-use-sync-external-store': specifier: file:./test-dep/transitive-use-sync-external-store version: file:packages/plugin-rsc/examples/basic/test-dep/transitive-use-sync-external-store(react@19.1.1) - react-tweet: - specifier: ^3.2.2 - version: 3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rsc-html-stream: specifier: ^0.0.7 version: 0.0.7 From d57598672fe3a5eb7f9e2fda902a0a1b5c16aac6 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 8 Sep 2025 17:35:08 +0900 Subject: [PATCH 9/9] chore: cleanup --- .../plugin-rsc/examples/starter/package.json | 1 - pnpm-lock.yaml | 57 +++---------------- 2 files changed, 8 insertions(+), 50 deletions(-) diff --git a/packages/plugin-rsc/examples/starter/package.json b/packages/plugin-rsc/examples/starter/package.json index 05a37375..6cc65d40 100644 --- a/packages/plugin-rsc/examples/starter/package.json +++ b/packages/plugin-rsc/examples/starter/package.json @@ -18,7 +18,6 @@ "@types/react-dom": "^19.1.9", "@vitejs/plugin-react": "latest", "@vitejs/plugin-rsc": "latest", - "react-tweet": "^3.2.2", "rsc-html-stream": "^0.0.7", "vite": "^7.1.4" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0ad33942..cb46e35c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,7 +146,7 @@ importers: version: 1.0.0-beta.35 '@swc/core': specifier: ^1.13.5 - version: 1.13.5(@swc/helpers@0.5.17) + version: 1.13.5 devDependencies: '@playwright/test': specifier: ^1.55.0 @@ -643,7 +643,7 @@ importers: devDependencies: '@cloudflare/vite-plugin': specifier: ^1.12.3 - version: 1.12.3(vite@7.1.4(@types/node@22.18.1)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))(workerd@1.20250902.0)(wrangler@4.34.0) + version: 1.12.3(vite@7.1.4(@types/node@22.18.1)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))(workerd@1.20250902.0) '@tailwindcss/typography': specifier: ^0.5.16 version: 0.5.16(tailwindcss@4.1.13) @@ -718,9 +718,6 @@ importers: '@vitejs/plugin-rsc': specifier: latest version: link:../.. - react-tweet: - specifier: ^3.2.2 - version: 3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) rsc-html-stream: specifier: ^0.0.7 version: 0.0.7 @@ -739,7 +736,7 @@ importers: devDependencies: '@cloudflare/vite-plugin': specifier: ^1.12.3 - version: 1.12.3(vite@7.1.4(@types/node@22.18.1)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))(workerd@1.20250902.0)(wrangler@4.34.0) + version: 1.12.3(vite@7.1.4(@types/node@22.18.1)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))(workerd@1.20250902.0) '@types/react': specifier: ^19.1.12 version: 19.1.12 @@ -1213,7 +1210,6 @@ packages: resolution: {integrity: sha512-kdXo0/qERVs7xQfv03O1Z5vZ8+nfdISY5dTKf2qWmqPQHEc4QRD5ImFG9SfDFZvcYZwEkX10mqNCZl3HXagdgA==} peerDependencies: vite: ^6.1.0 || ^7.0.0 - wrangler: ^4.34.0 '@cloudflare/workerd-darwin-64@1.20250902.0': resolution: {integrity: sha512-mwC/YEtDUGfnjXdbW5Lya+bgODrpJ5RxxqpaTjtMJycqnjR0RZgVpOqISwGfBHIhseykU3ahPugM5t91XkBKTg==} @@ -2160,9 +2156,6 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@swc/plugin-emotion@11.1.0': resolution: {integrity: sha512-R/Gm79HPsZTeXWOa/66yrlmBU4QHDX2Xq2N4p/Fg86TKbRLVrpxO5+yRm7jfHw1MbQDemL1x5yUAm6eKU6LDjw==} @@ -2768,10 +2761,6 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -4031,12 +4020,6 @@ packages: react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-tweet@3.2.2: - resolution: {integrity: sha512-hIkxAVPpN2RqWoDEbo3TTnN/pDcp9/Jb6pTgiA4EbXa9S+m2vHIvvZKHR+eS0PDIsYqe+zTmANRa5k6+/iwGog==} - peerDependencies: - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -4345,11 +4328,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - swr@2.3.6: - resolution: {integrity: sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==} - peerDependencies: - react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - tailwindcss@4.1.13: resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} @@ -4979,7 +4957,7 @@ snapshots: optionalDependencies: workerd: 1.20250902.0 - '@cloudflare/vite-plugin@1.12.3(vite@7.1.4(@types/node@22.18.1)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))(workerd@1.20250902.0)(wrangler@4.34.0)': + '@cloudflare/vite-plugin@1.12.3(vite@7.1.4(@types/node@22.18.1)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.7.1))(workerd@1.20250902.0)': dependencies: '@cloudflare/unenv-preset': 2.7.2(unenv@2.0.0-rc.20)(workerd@1.20250902.0) '@remix-run/node-fetch-server': 0.8.0 @@ -4992,6 +4970,7 @@ snapshots: wrangler: 4.34.0 ws: 8.18.0 transitivePeerDependencies: + - '@cloudflare/workers-types' - bufferutil - utf-8-validate - workerd @@ -5701,7 +5680,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.13.5': optional: true - '@swc/core@1.13.5(@swc/helpers@0.5.17)': + '@swc/core@1.13.5': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.24 @@ -5716,14 +5695,9 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.13.5 '@swc/core-win32-ia32-msvc': 1.13.5 '@swc/core-win32-x64-msvc': 1.13.5 - '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.17': - dependencies: - tslib: 2.8.1 - '@swc/plugin-emotion@11.1.0': dependencies: '@swc/counter': 0.1.3 @@ -6319,8 +6293,6 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.0.0 - clsx@2.1.1: {} - collapse-white-space@2.1.0: {} color-convert@2.0.1: @@ -7775,14 +7747,6 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - react-tweet@3.2.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): - dependencies: - '@swc/helpers': 0.5.17 - clsx: 2.1.1 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - swr: 2.3.6(react@19.1.1) - react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -8112,12 +8076,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swr@2.3.6(react@19.1.1): - dependencies: - dequal: 2.0.3 - react: 19.1.1 - use-sync-external-store: 1.5.0(react@19.1.1) - tailwindcss@4.1.13: {} tapable@2.2.1: {} @@ -8198,7 +8156,8 @@ snapshots: tslib@2.6.2: {} - tslib@2.8.1: {} + tslib@2.8.1: + optional: true turbo-stream@3.1.0: {}