Skip to content

Commit ac0b6d2

Browse files
authored
Update transform exports and tests (#45251)
<!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change that you're making: --> ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
1 parent 6a51edc commit ac0b6d2

File tree

6 files changed

+69
-41
lines changed

6 files changed

+69
-41
lines changed

packages/next-swc/crates/core/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ where
239239
config.clone(),
240240
path,
241241
cm,
242-
comments,
242+
comments.clone(),
243243
),
244244
)
245245
})
@@ -261,8 +261,11 @@ where
261261
None => Either::Right(noop()),
262262
},
263263
match &opts.server_actions {
264-
Some(config) =>
265-
Either::Left(server_actions::server_actions(&file.name, config.clone())),
264+
Some(config) => Either::Left(server_actions::server_actions(
265+
&file.name,
266+
config.clone(),
267+
comments,
268+
)),
266269
None => Either::Right(noop()),
267270
},
268271
)

packages/next-swc/crates/core/src/server_actions.rs

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
use next_binding::swc::core::{
2-
common::{errors::HANDLER, util::take::Take, FileName, DUMMY_SP},
2+
common::{
3+
comments::{Comment, CommentKind, Comments},
4+
errors::HANDLER,
5+
util::take::Take,
6+
BytePos, FileName, DUMMY_SP,
7+
},
38
ecma::{
49
ast::{
510
op, ArrayLit, AssignExpr, BlockStmt, CallExpr, ComputedPropName, Decl, ExportDecl,
611
Expr, ExprStmt, FnDecl, Function, Id, Ident, KeyValueProp, Lit, MemberExpr, MemberProp,
7-
ModuleDecl, ModuleItem, PatOrExpr, Prop, PropName, ReturnStmt, Stmt, Str, VarDecl,
8-
VarDeclKind, VarDeclarator,
12+
Module, ModuleDecl, ModuleItem, PatOrExpr, Prop, PropName, ReturnStmt, Stmt, Str,
13+
VarDecl, VarDeclKind, VarDeclarator,
914
},
1015
atoms::JsWord,
1116
utils::{find_pat_ids, private_ident, quote_ident, ExprFactory},
@@ -19,28 +24,40 @@ use serde::Deserialize;
1924

2025
#[derive(Clone, Debug, Deserialize)]
2126
#[serde(deny_unknown_fields, rename_all = "camelCase")]
22-
pub struct Config {}
27+
pub struct Config {
28+
pub is_server: bool,
29+
}
2330

24-
pub fn server_actions(file_name: &FileName, config: Config) -> impl VisitMut + Fold {
31+
pub fn server_actions<C: Comments>(
32+
file_name: &FileName,
33+
config: Config,
34+
comments: C,
35+
) -> impl VisitMut + Fold {
2536
as_folder(ServerActions {
2637
config,
38+
comments,
2739
file_name: file_name.clone(),
40+
start_pos: BytePos(0),
2841
in_action_file: false,
2942
in_export_decl: false,
43+
has_action: false,
3044
top_level: false,
3145
closure_candidates: Default::default(),
3246
annotations: Default::default(),
3347
extra_items: Default::default(),
3448
})
3549
}
3650

37-
struct ServerActions {
51+
struct ServerActions<C: Comments> {
3852
#[allow(unused)]
3953
config: Config,
4054
file_name: FileName,
55+
comments: C,
4156

57+
start_pos: BytePos,
4258
in_action_file: bool,
4359
in_export_decl: bool,
60+
has_action: bool,
4461
top_level: bool,
4562

4663
closure_candidates: Vec<Id>,
@@ -49,7 +66,7 @@ struct ServerActions {
4966
extra_items: Vec<ModuleItem>,
5067
}
5168

52-
impl VisitMut for ServerActions {
69+
impl<C: Comments> VisitMut for ServerActions<C> {
5370
fn visit_mut_export_decl(&mut self, decl: &mut ExportDecl) {
5471
let old = self.in_export_decl;
5572
self.in_export_decl = true;
@@ -97,6 +114,8 @@ impl VisitMut for ServerActions {
97114
let action_name: JsWord = format!("$ACTION_{}", f.ident.sym).into();
98115
let action_ident = private_ident!(action_name.clone());
99116

117+
self.has_action = true;
118+
100119
// myAction.$$typeof = Symbol.for('react.action.reference');
101120
self.annotations.push(annotate(
102121
&f.ident,
@@ -124,22 +143,24 @@ impl VisitMut for ServerActions {
124143
.push(annotate(&f.ident, "$$name", action_name.into()));
125144

126145
if self.top_level {
127-
// export const $ACTION_myAction = myAction;
128-
self.extra_items
129-
.push(ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
130-
span: DUMMY_SP,
131-
decl: Decl::Var(Box::new(VarDecl {
146+
if !(self.in_action_file && self.in_export_decl) {
147+
// export const $ACTION_myAction = myAction;
148+
self.extra_items
149+
.push(ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
132150
span: DUMMY_SP,
133-
kind: VarDeclKind::Const,
134-
declare: Default::default(),
135-
decls: vec![VarDeclarator {
151+
decl: Decl::Var(Box::new(VarDecl {
136152
span: DUMMY_SP,
137-
name: action_ident.into(),
138-
init: Some(f.ident.clone().into()),
139-
definite: Default::default(),
140-
}],
141-
})),
142-
})));
153+
kind: VarDeclKind::Const,
154+
declare: Default::default(),
155+
decls: vec![VarDeclarator {
156+
span: DUMMY_SP,
157+
name: action_ident.into(),
158+
init: Some(f.ident.clone().into()),
159+
definite: Default::default(),
160+
}],
161+
})),
162+
})));
163+
}
143164
} else {
144165
// Hoist the function to the top level.
145166

@@ -215,25 +236,17 @@ impl VisitMut for ServerActions {
215236
}
216237
}
217238

218-
fn visit_mut_module_item(&mut self, s: &mut ModuleItem) {
219-
s.visit_mut_children_with(self);
220-
221-
if self.in_action_file {
222-
if let ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
223-
decl: decl @ Decl::Fn(..),
224-
..
225-
})) = s
226-
{
227-
*s = ModuleItem::Stmt(Stmt::Decl(decl.take()));
228-
}
229-
}
239+
fn visit_mut_module(&mut self, m: &mut Module) {
240+
self.start_pos = m.span.lo;
241+
m.visit_mut_children_with(self);
230242
}
231243

232244
fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
233245
if let Some(ModuleItem::Stmt(Stmt::Expr(first))) = stmts.first() {
234246
match &*first.expr {
235247
Expr::Lit(Lit::Str(Str { value, .. })) if value == "use action" => {
236248
self.in_action_file = true;
249+
self.has_action = true;
237250
}
238251
_ => {}
239252
}
@@ -258,6 +271,18 @@ impl VisitMut for ServerActions {
258271
*stmts = new;
259272

260273
self.annotations = old_annotations;
274+
275+
if self.has_action {
276+
// Prepend a special comment to the top of the file.
277+
self.comments.add_leading(
278+
self.start_pos,
279+
Comment {
280+
span: DUMMY_SP,
281+
kind: CommentKind::Block,
282+
text: " __next_internal_action_entry_do_not_use__ ".into(),
283+
},
284+
);
285+
}
261286
}
262287

263288
fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {

packages/next-swc/crates/core/tests/fixture.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ fn server_actions_fixture(input: PathBuf) {
307307
&|_tr| {
308308
server_actions(
309309
&FileName::Real("/app/item.js".into()),
310-
server_actions::Config {},
310+
server_actions::Config { is_server: true },
311+
_tr.comments.as_ref().clone(),
311312
)
312313
},
313314
&input,

packages/next-swc/crates/core/tests/fixture/server-actions/1/output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export function Item({ id1 , id2 }) {
1+
/* __next_internal_action_entry_do_not_use__ */ export function Item({ id1 , id2 }) {
22
async function deleteItem() {
33
return $ACTION_deleteItem(deleteItem.$$closure);
44
}

packages/next-swc/crates/core/tests/fixture/server-actions/2/output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
async function myAction(a, b, c) {
1+
/* __next_internal_action_entry_do_not_use__ */ async function myAction(a, b, c) {
22
console.log('a');
33
}
44
myAction.$$typeof = Symbol.for("react.action.reference");
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// app/send.ts
2-
async function myAction(a, b, c) {
2+
/* __next_internal_action_entry_do_not_use__ */ export async function myAction(a, b, c) {
33
console.log('a');
44
}
55
myAction.$$typeof = Symbol.for("react.action.reference");
66
myAction.$$filepath = "/app/item.js";
77
myAction.$$name = "$ACTION_myAction";
8-
export const $ACTION_myAction = myAction;

0 commit comments

Comments
 (0)