Skip to content

Commit f2ed75a

Browse files
authored
DX improvements for "use cache" functions (#71518)
With this PR, we're assigning names to the transformed `"use cache"` functions, using the same rules as in #71478. Since we can't use named function expressions here, we're using `Object.defineProperty` instead, which we already used in #71478 for server actions with default export expressions. In addition, this PR fixes source mapping of `"use cache"` functions, which was slightly off before, due to the wrong spans being assigned to the new expressions. **Before:** <img width="943" alt="before" src="https://github.com/user-attachments/assets/f7cf674c-32d4-4f0d-a304-d5de5637a6a1"> **After:** <img width="943" alt="after" src="https://github.com/user-attachments/assets/8edda482-a666-4431-bfad-7e21987331eb">
1 parent dfc5331 commit f2ed75a

File tree

17 files changed

+222
-70
lines changed

17 files changed

+222
-70
lines changed

crates/next-custom-transforms/src/transforms/server_actions.rs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl<C: Comments> ServerActions<C> {
214214
);
215215

216216
let register_action_expr = bind_args_to_ref_expr(
217-
annotate_ident_as_server_reference(action_ident.clone(), action_id.clone()),
217+
annotate_ident_as_server_reference(action_ident.clone(), action_id.clone(), arrow.span),
218218
ids_from_closure
219219
.iter()
220220
.cloned()
@@ -377,7 +377,11 @@ impl<C: Comments> ServerActions<C> {
377377
let action_id = generate_action_id(&self.config.hash_salt, &self.file_name, &action_name);
378378

379379
let register_action_expr = bind_args_to_ref_expr(
380-
annotate_ident_as_server_reference(action_ident.clone(), action_id.clone()),
380+
annotate_ident_as_server_reference(
381+
action_ident.clone(),
382+
action_id.clone(),
383+
function.span,
384+
),
381385
ids_from_closure
382386
.iter()
383387
.cloned()
@@ -652,14 +656,21 @@ impl<C: Comments> ServerActions<C> {
652656
.into(),
653657
})));
654658

659+
if let Some(Ident { sym, .. }) = &self.arrow_or_fn_expr_ident {
660+
assign_name_to_ident(&cache_ident, sym.as_str(), &mut self.hoisted_extra_items);
661+
}
662+
655663
let bound_args: Vec<_> = ids_from_closure
656664
.iter()
657665
.cloned()
658666
.map(|id| Some(id.as_arg()))
659667
.collect();
660668

661-
let register_action_expr =
662-
annotate_ident_as_server_reference(cache_ident.clone(), reference_id.clone());
669+
let register_action_expr = annotate_ident_as_server_reference(
670+
cache_ident.clone(),
671+
reference_id.clone(),
672+
arrow.span,
673+
);
663674

664675
// If there're any bound args from the closure, we need to hoist the
665676
// register action expression to the top-level, and return the bind
@@ -709,8 +720,11 @@ impl<C: Comments> ServerActions<C> {
709720

710721
let reference_id = generate_action_id(&self.config.hash_salt, &self.file_name, &cache_name);
711722

712-
let register_action_expr =
713-
annotate_ident_as_server_reference(cache_ident.clone(), reference_id.clone());
723+
let register_action_expr = annotate_ident_as_server_reference(
724+
cache_ident.clone(),
725+
reference_id.clone(),
726+
function.span,
727+
);
714728

715729
function.body.visit_mut_with(&mut ClosureReplacer {
716730
used_ids: &ids_from_closure,
@@ -805,7 +819,7 @@ impl<C: Comments> ServerActions<C> {
805819
name: Pat::Ident(cache_ident.clone().into()),
806820
init: Some(wrap_cache_expr(
807821
Box::new(Expr::Fn(FnExpr {
808-
ident: fn_name,
822+
ident: fn_name.clone(),
809823
function: Box::new(Function {
810824
params: new_params,
811825
body: new_body,
@@ -822,6 +836,12 @@ impl<C: Comments> ServerActions<C> {
822836
.into(),
823837
})));
824838

839+
if let Some(Ident { sym, .. }) = fn_name {
840+
assign_name_to_ident(&cache_ident, sym.as_str(), &mut self.hoisted_extra_items);
841+
} else if self.in_default_export_decl {
842+
assign_name_to_ident(&cache_ident, "default", &mut self.hoisted_extra_items);
843+
}
844+
825845
let bound_args: Vec<_> = ids_from_closure
826846
.iter()
827847
.cloned()
@@ -947,16 +967,6 @@ impl<C: Comments> VisitMut for ServerActions<C> {
947967
}
948968

949969
if let Some(cache_type_str) = cache_type {
950-
// It's a cache function. If it doesn't have a name, give it one.
951-
match f.ident.as_mut() {
952-
None => {
953-
let action_name = gen_cache_ident(&mut self.reference_index);
954-
let ident = Ident::new(action_name, DUMMY_SP, Default::default());
955-
f.ident.insert(ident)
956-
}
957-
Some(i) => i,
958-
};
959-
960970
// Collect all the identifiers defined inside the closure and used
961971
// in the cache function. With deduplication.
962972
retain_names_from_declared_idents(
@@ -966,7 +976,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
966976

967977
let new_expr = self.maybe_hoist_and_create_proxy_for_cache_function(
968978
child_names.clone(),
969-
f.ident.clone(),
979+
f.ident.clone().or(self.arrow_or_fn_expr_ident.clone()),
970980
cache_type_str.as_str(),
971981
&mut f.function,
972982
);
@@ -1489,7 +1499,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
14891499
self.exported_idents
14901500
.push((new_ident.clone(), "default".into()));
14911501

1492-
attach_name_to_default_expr(&new_ident, &mut self.extra_items);
1502+
assign_name_to_ident(&new_ident, "default", &mut self.extra_items);
14931503
}
14941504
}
14951505
_ => {
@@ -1514,7 +1524,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
15141524
.push((new_ident.clone(), "default".into()));
15151525

15161526
create_var_declarator(&new_ident, &mut self.extra_items);
1517-
attach_name_to_default_expr(&new_ident, &mut self.extra_items);
1527+
assign_name_to_ident(&new_ident, "default", &mut self.extra_items);
15181528

15191529
*default_expr.expr =
15201530
assign_arrow_expr(&new_ident, Expr::Arrow(arrow.clone()));
@@ -1538,7 +1548,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
15381548
.push((new_ident.clone(), "default".into()));
15391549

15401550
create_var_declarator(&new_ident, &mut self.extra_items);
1541-
attach_name_to_default_expr(&new_ident, &mut self.extra_items);
1551+
assign_name_to_ident(&new_ident, "default", &mut self.extra_items);
15421552

15431553
*default_expr.expr =
15441554
assign_arrow_expr(&new_ident, Expr::Call(call.clone()));
@@ -1726,6 +1736,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
17261736
expr: Box::new(annotate_ident_as_server_reference(
17271737
ident.clone(),
17281738
action_id,
1739+
ident.span,
17291740
)),
17301741
}));
17311742
}
@@ -2079,7 +2090,7 @@ fn create_var_declarator(ident: &Ident, extra_items: &mut Vec<ModuleItem>) {
20792090
})))));
20802091
}
20812092

2082-
fn attach_name_to_default_expr(ident: &Ident, extra_items: &mut Vec<ModuleItem>) {
2093+
fn assign_name_to_ident(ident: &Ident, name: &str, extra_items: &mut Vec<ModuleItem>) {
20832094
// Assign a name with `Object.defineProperty($$ACTION_0, 'name', {value: 'default'})`
20842095
extra_items.push(ModuleItem::Stmt(Stmt::Expr(ExprStmt {
20852096
span: DUMMY_SP,
@@ -2110,7 +2121,7 @@ fn attach_name_to_default_expr(ident: &Ident, extra_items: &mut Vec<ModuleItem>)
21102121
props: vec![
21112122
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
21122123
key: PropName::Str("value".into()),
2113-
value: Box::new("default".into()),
2124+
value: Box::new(name.into()),
21142125
}))),
21152126
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
21162127
key: PropName::Str("writable".into()),
@@ -2155,10 +2166,14 @@ fn generate_action_id(hash_salt: &str, file_name: &str, export_name: &str) -> St
21552166
hex_encode(result)
21562167
}
21572168

2158-
fn annotate_ident_as_server_reference(ident: Ident, action_id: String) -> Expr {
2169+
fn annotate_ident_as_server_reference(
2170+
ident: Ident,
2171+
action_id: String,
2172+
original_span: Span,
2173+
) -> Expr {
21592174
// registerServerReference(reference, id, null)
21602175
Expr::Call(CallExpr {
2161-
span: ident.span,
2176+
span: original_span,
21622177
callee: quote_ident!("registerServerReference").as_callee(),
21632178
args: vec![
21642179
ExprOrSpread {

crates/next-custom-transforms/tests/fixture/server-actions/server/33/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ const v = 'world';
55
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788b846c0d2b7f74743", async function fn() {
66
return 'hello, ' + v;
77
});
8+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
9+
"value": "fn",
10+
"writable": false
11+
});
812
var fn = registerServerReference($$RSC_SERVER_CACHE_0, "3128060c414d59f8552e4788b846c0d2b7f74743", null);
913
export async function Component() {
1014
const data = await fn();
Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
1-
/* __next_internal_action_entry_do_not_use__ {"12a8d21b6362b4cc8f5b15560525095bc48dba80":"$$RSC_SERVER_CACHE_3","3128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0","4acc55633206134002149ce873fe498be64a6fef":"$$RSC_SERVER_CACHE_4","951c375b4a6a6e89d67b743ec5808127cfde405d":"$$RSC_SERVER_CACHE_1"} */ import { registerServerReference } from "private-next-rsc-server-reference";
1+
/* __next_internal_action_entry_do_not_use__ {"12a8d21b6362b4cc8f5b15560525095bc48dba80":"$$RSC_SERVER_CACHE_3","3128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0","69348c79fce073bae2f70f139565a2fda1c74c74":"$$RSC_SERVER_CACHE_2","951c375b4a6a6e89d67b743ec5808127cfde405d":"$$RSC_SERVER_CACHE_1"} */ import { registerServerReference } from "private-next-rsc-server-reference";
22
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
33
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
44
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788b846c0d2b7f74743", async function() {
55
return 'foo';
66
});
7+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
8+
"value": "foo",
9+
"writable": false
10+
});
711
const foo = registerServerReference($$RSC_SERVER_CACHE_0, "3128060c414d59f8552e4788b846c0d2b7f74743", null);
812
export { bar };
913
export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "951c375b4a6a6e89d67b743ec5808127cfde405d", async function bar() {
1014
return 'bar';
1115
});
16+
Object.defineProperty($$RSC_SERVER_CACHE_1, "name", {
17+
"value": "bar",
18+
"writable": false
19+
});
1220
var bar = registerServerReference($$RSC_SERVER_CACHE_1, "951c375b4a6a6e89d67b743ec5808127cfde405d", null);
1321
// Should not be wrapped in $$cache__.
1422
const qux = async function qux() {
1523
return 'qux';
1624
};
17-
export var $$RSC_SERVER_CACHE_3 = $$cache__("default", "12a8d21b6362b4cc8f5b15560525095bc48dba80", async function $$RSC_SERVER_CACHE_2() {
25+
export var $$RSC_SERVER_CACHE_2 = $$cache__("default", "69348c79fce073bae2f70f139565a2fda1c74c74", async function baz() {
1826
return qux() + 'baz';
1927
});
20-
const baz = registerServerReference($$RSC_SERVER_CACHE_3, "12a8d21b6362b4cc8f5b15560525095bc48dba80", null);
21-
export var $$RSC_SERVER_CACHE_4 = $$cache__("default", "4acc55633206134002149ce873fe498be64a6fef", async function() {
28+
Object.defineProperty($$RSC_SERVER_CACHE_2, "name", {
29+
"value": "baz",
30+
"writable": false
31+
});
32+
const baz = registerServerReference($$RSC_SERVER_CACHE_2, "69348c79fce073bae2f70f139565a2fda1c74c74", null);
33+
export var $$RSC_SERVER_CACHE_3 = $$cache__("default", "12a8d21b6362b4cc8f5b15560525095bc48dba80", async function() {
2234
return 'quux';
2335
});
24-
const quux = registerServerReference($$RSC_SERVER_CACHE_4, "4acc55633206134002149ce873fe498be64a6fef", null);
36+
Object.defineProperty($$RSC_SERVER_CACHE_3, "name", {
37+
"value": "quux",
38+
"writable": false
39+
});
40+
const quux = registerServerReference($$RSC_SERVER_CACHE_3, "12a8d21b6362b4cc8f5b15560525095bc48dba80", null);
2541
export { foo, baz };
2642
export default quux;

crates/next-custom-transforms/tests/fixture/server-actions/server/35/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
44
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788b846c0d2b7f74743", async function() {
55
return 'data';
66
});
7+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
8+
"value": "my_fn",
9+
"writable": false
10+
});
711
export const my_fn = registerServerReference($$RSC_SERVER_CACHE_0, "3128060c414d59f8552e4788b846c0d2b7f74743", null);
Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
1-
/* __next_internal_action_entry_do_not_use__ {"3128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0","4acc55633206134002149ce873fe498be64a6fef":"$$RSC_SERVER_CACHE_4","69348c79fce073bae2f70f139565a2fda1c74c74":"$$RSC_SERVER_CACHE_2","951c375b4a6a6e89d67b743ec5808127cfde405d":"$$RSC_SERVER_CACHE_1"} */ import { registerServerReference } from "private-next-rsc-server-reference";
1+
/* __next_internal_action_entry_do_not_use__ {"12a8d21b6362b4cc8f5b15560525095bc48dba80":"$$RSC_SERVER_CACHE_3","3128060c414d59f8552e4788b846c0d2b7f74743":"$$RSC_SERVER_CACHE_0","69348c79fce073bae2f70f139565a2fda1c74c74":"$$RSC_SERVER_CACHE_2","951c375b4a6a6e89d67b743ec5808127cfde405d":"$$RSC_SERVER_CACHE_1"} */ import { registerServerReference } from "private-next-rsc-server-reference";
22
import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption";
33
import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
44
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788b846c0d2b7f74743", async function foo() {
55
return 'data A';
66
});
7+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
8+
"value": "foo",
9+
"writable": false
10+
});
711
export var foo = registerServerReference($$RSC_SERVER_CACHE_0, "3128060c414d59f8552e4788b846c0d2b7f74743", null);
812
export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "951c375b4a6a6e89d67b743ec5808127cfde405d", async function bar() {
913
return 'data B';
1014
});
15+
Object.defineProperty($$RSC_SERVER_CACHE_1, "name", {
16+
"value": "bar",
17+
"writable": false
18+
});
1119
export var bar = registerServerReference($$RSC_SERVER_CACHE_1, "951c375b4a6a6e89d67b743ec5808127cfde405d", null);
1220
export var $$RSC_SERVER_CACHE_2 = $$cache__("default", "69348c79fce073bae2f70f139565a2fda1c74c74", async function Cached({ children }) {
1321
return children;
1422
});
23+
Object.defineProperty($$RSC_SERVER_CACHE_2, "name", {
24+
"value": "Cached",
25+
"writable": false
26+
});
1527
export default registerServerReference($$RSC_SERVER_CACHE_2, "69348c79fce073bae2f70f139565a2fda1c74c74", null);
16-
export var $$RSC_SERVER_CACHE_4 = $$cache__("default", "4acc55633206134002149ce873fe498be64a6fef", async function $$RSC_SERVER_CACHE_3() {
28+
export var $$RSC_SERVER_CACHE_3 = $$cache__("default", "12a8d21b6362b4cc8f5b15560525095bc48dba80", async function baz() {
1729
return 'data C';
1830
});
19-
export const baz = registerServerReference($$RSC_SERVER_CACHE_4, "4acc55633206134002149ce873fe498be64a6fef", null);
31+
Object.defineProperty($$RSC_SERVER_CACHE_3, "name", {
32+
"value": "baz",
33+
"writable": false
34+
});
35+
export const baz = registerServerReference($$RSC_SERVER_CACHE_3, "12a8d21b6362b4cc8f5b15560525095bc48dba80", null);

crates/next-custom-transforms/tests/fixture/server-actions/server/37/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
44
export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788b846c0d2b7f74743", async function fn() {
55
return 'foo';
66
});
7+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
8+
"value": "fn",
9+
"writable": false
10+
});
711
var fn = registerServerReference($$RSC_SERVER_CACHE_0, "3128060c414d59f8552e4788b846c0d2b7f74743", null);
812
async function Component() {
913
const data = await fn();

crates/next-custom-transforms/tests/fixture/server-actions/server/38/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ import { cache as $$cache__ } from "private-next-rsc-cache-wrapper";
44
export var $$RSC_SERVER_CACHE_0 = $$cache__("x", "3128060c414d59f8552e4788b846c0d2b7f74743", async function foo() {
55
return 'data';
66
});
7+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
8+
"value": "foo",
9+
"writable": false
10+
});
711
export var foo = registerServerReference($$RSC_SERVER_CACHE_0, "3128060c414d59f8552e4788b846c0d2b7f74743", null);

crates/next-custom-transforms/tests/fixture/server-actions/server/39/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788
88
foo: $$ACTION_ARG_1
99
};
1010
});
11+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
12+
"value": "fn",
13+
"writable": false
14+
});
1115
async function Component({ foo }) {
1216
const a = 123;
1317
var fn = $$RSC_SERVER_REF_1.bind(null, encryptActionBoundArgs("3128060c414d59f8552e4788b846c0d2b7f74743", [

crates/next-custom-transforms/tests/fixture/server-actions/server/40/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export var $$RSC_SERVER_CACHE_0 = $$cache__("default", "3128060c414d59f8552e4788
1111
}
1212
];
1313
});
14+
Object.defineProperty($$RSC_SERVER_CACHE_0, "name", {
15+
"value": "cache",
16+
"writable": false
17+
});
1418
export const $$RSC_SERVER_ACTION_2 = async function action($$ACTION_CLOSURE_BOUND, c) {
1519
var [$$ACTION_ARG_0, $$ACTION_ARG_1] = await decryptActionBoundArgs("1c36b06e398c97abe5d5d7ae8c672bfddf4e1b91", $$ACTION_CLOSURE_BOUND);
1620
const d = $$ACTION_ARG_0 + $$ACTION_ARG_1 + c;

crates/next-custom-transforms/tests/fixture/server-actions/server/41/output.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@ export var $$RSC_SERVER_CACHE_1 = $$cache__("default", "951c375b4a6a6e89d67b743e
1717
const data = await fn();
1818
return <div>{data}</div>;
1919
});
20+
Object.defineProperty($$RSC_SERVER_CACHE_1, "name", {
21+
"value": "Component",
22+
"writable": false
23+
});
2024
export var Component = registerServerReference($$RSC_SERVER_CACHE_1, "951c375b4a6a6e89d67b743ec5808127cfde405d", null);

0 commit comments

Comments
 (0)