Skip to content

Commit 6af3ae0

Browse files
committed
Docs on tree shaking tests
1 parent b581ad5 commit 6af3ae0

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

test/production/app-dir/actions-tree-shaking/basic/basic.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,51 @@ import {
44
} from '../_testing/utils'
55

66
// TODO: revisit when we have a better side-effect free transform approach for server action
7+
// These tests are checking that importing a single server action from a file that has multiple
8+
// server actions, only includes the used server action in the manifest. This has both security
9+
// benefits (not exposing unused server actions, though we also have the unguessable IDs anyway)
10+
// and bundle size benefits (not bundling unused server actions and their dependencies).
11+
//
12+
// https://github.com/vercel/next.js/pull/76877 originally implemented this optimization, but
13+
// only when importing server action modules from client components. This only happened
14+
// accidentally because the main goal was to not include the unused server action hashes in the
15+
// client chunk, see test/production/app-dir/actions-tree-shaking/client-actions-tree-shaking.
16+
//
17+
// Importing server action modules from server components did not have this optimization, so if
18+
// it would still bundle all server actions.
19+
//
20+
// https://github.com/vercel/next.js/pull/91212 then reworked the server action implementation
21+
// and now both use situation unfortunately cause all server actions to be bundled.
22+
//
23+
// The solution here is to rework the giant
24+
// crates/next-custom-transforms/src/transforms/server_actions.rs transform and perform the
25+
// dataurl reexports trick also when importing from server components.
26+
//
27+
// So when in the client layer (already implemented):
28+
// ```
29+
// export {foo} from "data:text/javascript,export const foo = createServerReference('HASH'); __turbopack_emit__('./actions.ts?server_actions_impl', {data: 'foo|HASH', exports: 'foo', with: {turbopackTransition: 'next-rsc'}})";
30+
// export {bar} from "data:...";
31+
// ```
32+
//
33+
// When in the server layer:
34+
// ```
35+
// export {foo} from "data:text/javascript,export {foo} from './actions.ts?server_actions_impl'; __turbopack_emit__('./actions.ts?server_actions_impl', {data: 'foo|HASH', exports: 'foo'})";
36+
// export {bar} from "data:...";
37+
// ```
38+
//
39+
// And `actions.ts?server_actions_impl` would be transformed to:
40+
// ```
41+
// export const foo = registerServerReference(async function foo() { ... })
42+
//
43+
// const $$RSC_SERVER_CACHE_0_INNER = async function my_fn() { return 'data'; };
44+
// export var $$RSC_SERVER_CACHE_0 = $$reactCache__(function my_fn() {
45+
// return $$cache__("default", "803128060c414d59f8552e4788b846c0d2b7f74743", 0, $$RSC_SERVER_CACHE_0_INNER, []);
46+
// });
47+
// export const my_fn = registerServerReference($$RSC_SERVER_CACHE_0);
48+
// ```
49+
//
50+
// This way, the actual actions.ts?server_actions_impl file has accurate used exports, so unused
51+
// code can be removed by inner graph tree shaking.
752
;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)(
853
'actions-tree-shaking - basic',
954
() => {
@@ -17,6 +62,8 @@ import {
1762
{
1863
"app/client/page": [
1964
"app/actions.js#clientComponentAction",
65+
"app/actions.js#serverComponentAction",
66+
"app/actions.js#unusedExportedAction",
2067
],
2168
"app/inline/page": [
2269
"app/inline/page.js#$$RSC_SERVER_ACTION_0",

test/production/app-dir/actions-tree-shaking/reexport/reexport.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
import { retry } from 'next-test-utils'
66

77
// TODO: revisit when we have a better side-effect free transform approach for server action
8+
// See the explaination in test/production/app-dir/actions-tree-shaking/basic/basic.test.ts
89
;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)(
910
'actions-tree-shaking - reexport',
1011
() => {
@@ -20,6 +21,8 @@ import { retry } from 'next-test-utils'
2021
{
2122
"app/named-reexport/client/page": [
2223
"app/named-reexport/client/actions.js#sharedClientLayerAction",
24+
"app/named-reexport/client/actions.js#unusedClientLayerAction1",
25+
"app/named-reexport/client/actions.js#unusedClientLayerAction2",
2326
],
2427
"app/named-reexport/server/page": [
2528
"app/named-reexport/server/actions.js#sharedServerLayerAction",
@@ -28,6 +31,7 @@ import { retry } from 'next-test-utils'
2831
],
2932
"app/namespace-reexport-2/client/page": [
3033
"app/namespace-reexport-2/actions/action-modules.js#action",
34+
"app/namespace-reexport-2/nested.js#foo",
3135
"app/namespace-reexport-2/nested.js#getFoo",
3236
],
3337
"app/namespace-reexport-2/server/page": [
@@ -37,6 +41,8 @@ import { retry } from 'next-test-utils'
3741
],
3842
"app/namespace-reexport/client/page": [
3943
"app/namespace-reexport/client/actions.js#sharedClientLayerAction",
44+
"app/namespace-reexport/client/actions.js#unusedClientLayerAction1",
45+
"app/namespace-reexport/client/actions.js#unusedClientLayerAction2",
4046
],
4147
"app/namespace-reexport/server/page": [
4248
"app/namespace-reexport/server/actions.js#sharedServerLayerAction",

test/production/app-dir/actions-tree-shaking/shared-module-actions/shared-module-actions.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
} from '../_testing/utils'
55

66
// TODO: revisit when we have a better side-effect free transform approach for server action
7+
// See the explaination in test/production/app-dir/actions-tree-shaking/basic/basic.test.ts
78
;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)(
89
'actions-tree-shaking - shared-module-actions',
910
() => {
@@ -17,9 +18,13 @@ import {
1718
{
1819
"app/client/one/page": [
1920
"app/client/actions.js#sharedClientLayerAction",
21+
"app/client/actions.js#unusedClientLayerAction1",
22+
"app/client/actions.js#unusedClientLayerAction2",
2023
],
2124
"app/client/two/page": [
2225
"app/client/actions.js#sharedClientLayerAction",
26+
"app/client/actions.js#unusedClientLayerAction1",
27+
"app/client/actions.js#unusedClientLayerAction2",
2328
],
2429
"app/server/one/page": [
2530
"app/server/actions.js#sharedServerLayerAction",

0 commit comments

Comments
 (0)