Skip to content

Commit

Permalink
Implement custom Turbopack Next transformers (#47137)
Browse files Browse the repository at this point in the history
Builds on vercel/turborepo#4202 to implement custom Next.js Transformers in Turbopack.

This is the final piece to moving the `next-*` crates to Next. While we've _technically_ moved everything, Turbopack didn't support running custom transformers. So we're actually stuck on the last version we cut before deleting the next crates, running the transformers that exist in the turbopack repo. With the new support, we're almost back to the tip of main branch (there's still some snafu with `swc_core` upgrading that I'm working on).

Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
  • Loading branch information
jridgewell and sokra authored Mar 15, 2023
1 parent 4824d96 commit 02125cf
Show file tree
Hide file tree
Showing 11 changed files with 579 additions and 471 deletions.
638 changes: 329 additions & 309 deletions packages/next-swc/Cargo.lock

Large diffs are not rendered by default.

86 changes: 43 additions & 43 deletions packages/next-swc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ members = [
"crates/next-core",
"crates/next-dev",
"crates/next-dev-tests",
# "crates/next-font",
# "crates/next-transform-dynamic",
# "crates/next-transform-strip-page-exports",
"crates/next-font",
"crates/next-transform-dynamic",
"crates/next-transform-strip-page-exports",
]

[profile.dev.package.swc_css_prefixer]
Expand All @@ -26,55 +26,55 @@ lto = true
[workspace.dependencies]
# Workspace crates
next-binding = { path = "crates/next-binding" }
next-core = { path = "crates/next-core" }
next-core = { path = "crates/next-core", default-features = false }
next-dev = { path = "crates/next-dev" }
next-dev-tests = { path = "crates/next-dev-tests" }
# next-font = { path = "crates/next-font" }
# next-transform-dynamic = { path = "crates/next-transform-dynamic" }
# next-transform-strip-page-exports = { path = "crates/next-transform-strip-page-exports" }
next-font = { path = "crates/next-font" }
next-transform-dynamic = { path = "crates/next-transform-dynamic" }
next-transform-strip-page-exports = { path = "crates/next-transform-strip-page-exports" }

# SWC crates
# Keep consistent with preset_env_base through swc_core
browserslist-rs = { version = "0.12.2" }
mdxjs = { version = "0.1.6" }
modularize_imports = { version = "0.26.4" }
styled_components = { version = "0.53.4" }
styled_jsx = { version = "0.30.4" }
swc_core = { version = "0.59.26" }
swc_emotion = { version = "0.29.4" }
mdxjs = { version = "0.1.8" }
modularize_imports = { version = "0.26.10" }
styled_components = { version = "0.53.10" }
styled_jsx = { version = "0.30.10" }
swc_core = { version = "0.69.6" }
swc_emotion = { version = "0.29.10" }
testing = { version = "0.31.31" }

# Turbo crates
auto-hash-map = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
node-file-trace = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
swc-ast-explorer = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-malloc = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94", default-features = false }
turbo-tasks = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-build = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-env = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-fetch = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-hash = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-macros = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-macros-shared = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-memory = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-tasks-testing = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbo-updater = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-cli-utils = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-core = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-create-test-app = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-css = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-dev-server = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-ecmascript = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-env = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-json = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-mdx = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-node = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-static = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-swc-utils = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-test-utils = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
turbopack-tests = { git = "https://github.com/vercel/turbo.git", rev = "8a8038f94" }
auto-hash-map = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
node-file-trace = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
swc-ast-explorer = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-malloc = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2", default-features = false }
turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-build = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-env = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-fetch = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2", default-features = false }
turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-hash = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-macros = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-macros-shared = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-memory = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-tasks-testing = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbo-updater = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-cli-utils = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-core = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-create-test-app = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-css = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-dev-server = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-ecmascript = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-env = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-json = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-mdx = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-node = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-static = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-swc-utils = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-test-utils = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }
turbopack-tests = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230315.2" }

# General Deps

Expand Down
74 changes: 38 additions & 36 deletions packages/next-swc/crates/core/src/next_dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,44 +179,46 @@ impl Fold for NextDynamicPatcher {
key: PropName::Ident(Ident::new("webpack".into(), DUMMY_SP)),
value: Box::new(Expr::Arrow(ArrowExpr {
params: vec![],
body: BlockStmtOrExpr::Expr(Box::new(Expr::Array(ArrayLit {
elems: vec![Some(ExprOrSpread {
expr: Box::new(Expr::Call(CallExpr {
callee: Callee::Expr(Box::new(Expr::Member(
MemberExpr {
obj: Box::new(Expr::Ident(Ident {
sym: js_word!("require"),
body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Array(
ArrayLit {
elems: vec![Some(ExprOrSpread {
expr: Box::new(Expr::Call(CallExpr {
callee: Callee::Expr(Box::new(Expr::Member(
MemberExpr {
obj: Box::new(Expr::Ident(Ident {
sym: js_word!("require"),
span: DUMMY_SP,
optional: false,
})),
prop: MemberProp::Ident(Ident {
sym: "resolveWeak".into(),
span: DUMMY_SP,
optional: false,
}),
span: DUMMY_SP,
optional: false,
})),
prop: MemberProp::Ident(Ident {
sym: "resolveWeak".into(),
},
))),
args: vec![ExprOrSpread {
expr: Box::new(Expr::Lit(Lit::Str(Str {
value: self
.dynamically_imported_specifier
.as_ref()
.unwrap()
.clone()
.into(),
span: DUMMY_SP,
optional: false,
}),
span: DUMMY_SP,
},
))),
args: vec![ExprOrSpread {
expr: Box::new(Expr::Lit(Lit::Str(Str {
value: self
.dynamically_imported_specifier
.as_ref()
.unwrap()
.clone()
.into(),
span: DUMMY_SP,
raw: None,
}))),
spread: None,
}],
span: DUMMY_SP,
type_args: None,
})),
spread: None,
})],
span: DUMMY_SP,
}))),
raw: None,
}))),
spread: None,
}],
span: DUMMY_SP,
type_args: None,
})),
spread: None,
})],
span: DUMMY_SP,
},
)))),
is_async: false,
is_generator: false,
span: DUMMY_SP,
Expand Down
14 changes: 7 additions & 7 deletions packages/next-swc/crates/core/src/server_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl<C: Comments> ServerActions<C> {
);

if let Some(a) = arrow {
if let BlockStmtOrExpr::BlockStmt(block) = &mut a.body {
if let BlockStmtOrExpr::BlockStmt(block) = &mut *a.body {
block.visit_mut_with(&mut ClosureReplacer {
closure_arg: &closure_arg,
used_ids: &ids_from_closure,
Expand All @@ -201,7 +201,7 @@ impl<C: Comments> ServerActions<C> {
let new_arrow = ArrowExpr {
span: DUMMY_SP,
params: a.params.clone(),
body: BlockStmtOrExpr::Expr(Box::new(Expr::Call(call))),
body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Call(call)))),
is_async: a.is_async,
is_generator: a.is_generator,
type_params: Default::default(),
Expand Down Expand Up @@ -402,7 +402,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
// Arrow expressions need to be visited in prepass to determine if it's
// an action function or not.
let is_action_fn = self.get_action_info(
if let BlockStmtOrExpr::BlockStmt(block) = &mut a.body {
if let BlockStmtOrExpr::BlockStmt(block) = &mut *a.body {
Some(block)
} else {
None
Expand Down Expand Up @@ -503,7 +503,7 @@ impl<C: Comments> VisitMut for ServerActions<C> {
if !self.in_action_file {
if let Expr::Arrow(a) = n {
let is_action_fn = self.get_action_info(
if let BlockStmtOrExpr::BlockStmt(block) = &mut a.body {
if let BlockStmtOrExpr::BlockStmt(block) = &mut *a.body {
Some(block)
} else {
None
Expand Down Expand Up @@ -1194,7 +1194,7 @@ impl TryFrom<&'_ OptChainExpr> for Name {
type Error = ();

fn try_from(value: &OptChainExpr) -> Result<Self, Self::Error> {
match &value.base {
match &*value.base {
OptChainBase::Member(value) => match &value.prop {
MemberProp::Ident(prop) => {
let mut obj: Name = value.obj.as_ref().try_into()?;
Expand Down Expand Up @@ -1223,11 +1223,11 @@ impl From<Name> for Expr {
expr = Expr::OptChain(OptChainExpr {
span: DUMMY_SP,
question_dot_token: DUMMY_SP,
base: OptChainBase::Member(MemberExpr {
base: Box::new(OptChainBase::Member(MemberExpr {
span: DUMMY_SP,
obj: expr.into(),
prop: MemberProp::Ident(Ident::new(prop, DUMMY_SP)),
}),
})),
});
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/next-swc/crates/next-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ turbopack-dev-server = { workspace = true }
turbopack-ecmascript = { workspace = true }
turbopack-env = { workspace = true }
turbopack-node = { workspace = true }
next-transform-strip-page-exports = { workspace = true }
next-font = { workspace = true }
next-transform-dynamic = { workspace = true }

swc_core = { workspace = true, features = ["ecma_ast", "common"] }

Expand Down
1 change: 1 addition & 0 deletions packages/next-swc/crates/next-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![feature(async_closure)]
#![feature(min_specialization)]
#![feature(box_syntax)]

mod app_render;
mod app_source;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Result;
use next_transform_strip_page_exports::ExportFilter;
use turbopack::module_options::ModuleRule;
use turbopack_ecmascript::NextJsPageExportFilter;

use crate::{
next_client::context::ClientContextType,
Expand All @@ -22,8 +22,7 @@ pub async fn get_next_client_transforms_rules(
let pages_dir = match context_ty {
ClientContextType::Pages { pages_dir } => {
rules.push(
get_next_pages_transforms_rule(pages_dir, NextJsPageExportFilter::StripDataExports)
.await?,
get_next_pages_transforms_rule(pages_dir, ExportFilter::StripDataExports).await?,
);
Some(pages_dir)
}
Expand All @@ -32,9 +31,7 @@ pub async fn get_next_client_transforms_rules(
}
};

rules.push(get_next_dynamic_transform_rule(
true, false, false, pages_dir,
));
rules.push(get_next_dynamic_transform_rule(true, false, false, pages_dir).await?);

Ok(rules)
}
15 changes: 3 additions & 12 deletions packages/next-swc/crates/next-core/src/next_server/transforms.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Result;
use next_transform_strip_page_exports::ExportFilter;
use turbopack::module_options::ModuleRule;
use turbopack_ecmascript::NextJsPageExportFilter;

use crate::{
next_server::context::ServerContextType,
Expand All @@ -21,11 +21,7 @@ pub async fn get_next_server_transforms_rules(
ServerContextType::Pages { pages_dir } => (false, Some(pages_dir)),
ServerContextType::PagesData { pages_dir } => {
rules.push(
get_next_pages_transforms_rule(
pages_dir,
NextJsPageExportFilter::StripDefaultExport,
)
.await?,
get_next_pages_transforms_rule(pages_dir, ExportFilter::StripDefaultExport).await?,
);
(false, Some(pages_dir))
}
Expand All @@ -35,12 +31,7 @@ pub async fn get_next_server_transforms_rules(
ServerContextType::Middleware { .. } => (false, None),
};

rules.push(get_next_dynamic_transform_rule(
true,
true,
is_server_components,
pages_dir,
));
rules.push(get_next_dynamic_transform_rule(true, true, is_server_components, pages_dir).await?);

Ok(rules)
}
Loading

0 comments on commit 02125cf

Please sign in to comment.