diff --git a/Cargo.lock b/Cargo.lock index 7c259b851b747..6d2c36e7f1f06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,7 +400,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "serde", ] @@ -3237,6 +3237,7 @@ dependencies = [ "allsorts", "anyhow", "async-recursion", + "async-trait", "futures", "indexmap", "indoc", @@ -3334,7 +3335,6 @@ dependencies = [ "serde", "serde_json", "sha1 0.10.5", - "swc_relay", "tracing", "turbo-binding", "walkdir", @@ -3413,7 +3413,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "serde", @@ -6980,7 +6980,7 @@ dependencies = [ [[package]] name = "turbo-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "auto-hash-map", "mdxjs", @@ -7020,7 +7020,7 @@ dependencies = [ [[package]] name = "turbo-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "mimalloc", ] @@ -7028,7 +7028,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "auto-hash-map", @@ -7058,7 +7058,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "cargo-lock", @@ -7070,7 +7070,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "bytes", @@ -7085,7 +7085,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "dotenvy", @@ -7099,7 +7099,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "indexmap", @@ -7116,7 +7116,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "auto-hash-map", @@ -7145,7 +7145,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "base16", "hex", @@ -7157,7 +7157,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7171,7 +7171,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "proc-macro2", "quote", @@ -7181,7 +7181,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "auto-hash-map", @@ -7203,7 +7203,7 @@ dependencies = [ [[package]] name = "turbo-tasks-testing" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "auto-hash-map", @@ -7215,7 +7215,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "async-recursion", @@ -7244,7 +7244,7 @@ dependencies = [ [[package]] name = "turbopack-bench" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "chromiumoxide", @@ -7274,7 +7274,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "clap 4.1.11", @@ -7291,7 +7291,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "async-trait", @@ -7318,7 +7318,7 @@ dependencies = [ [[package]] name = "turbopack-create-test-app" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "clap 4.1.11", @@ -7331,7 +7331,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "async-trait", @@ -7353,7 +7353,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "indexmap", @@ -7374,7 +7374,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "async-compression", @@ -7408,7 +7408,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "async-trait", @@ -7444,21 +7444,24 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", + "async-trait", "serde", "swc_core", "swc_emotion", + "swc_relay", "turbo-tasks", "turbo-tasks-build", + "turbo-tasks-fs", "turbopack-ecmascript", ] [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "indexmap", @@ -7474,7 +7477,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "base64 0.21.0", @@ -7494,7 +7497,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "serde", @@ -7509,7 +7512,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "mdxjs", @@ -7524,7 +7527,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "async-stream", @@ -7558,7 +7561,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "serde", @@ -7574,7 +7577,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "swc_core", "turbo-tasks", @@ -7585,7 +7588,7 @@ dependencies = [ [[package]] name = "turbopack-test-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230504.3#a68486bd15982ba1634a3f672d0808b061f72e28" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230508.2#b9e5e6d750c048bb083bfa60941554c479f6685f" dependencies = [ "anyhow", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 3b62544bad664..cefc763c5180a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,15 +38,14 @@ next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-tran # SWC crates # Keep consistent with preset_env_base through swc_core swc_core = { version = "0.75.41" } -swc_relay = { version = "0.2.7" } -testing = { version = "0.33.6" } +testing = { version = "0.33.4" } # Turbo crates -turbo-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230504.3" } +turbo-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230508.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230504.3" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230508.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230504.3" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230508.2" } # General Deps diff --git a/packages/next-swc/crates/core/Cargo.toml b/packages/next-swc/crates/core/Cargo.toml index 0b67af72e3290..5a69e793f6e88 100644 --- a/packages/next-swc/crates/core/Cargo.toml +++ b/packages/next-swc/crates/core/Cargo.toml @@ -31,7 +31,6 @@ turbo-binding = { workspace = true, features = [ "__swc_transform_modularize_imports", "__swc_transform_relay", ] } -swc_relay = { workspace = true } [dev-dependencies] turbo-binding = { workspace = true, features = [ diff --git a/packages/next-swc/crates/core/src/lib.rs b/packages/next-swc/crates/core/src/lib.rs index 2a90a74106698..7163d673a2a00 100644 --- a/packages/next-swc/crates/core/src/lib.rs +++ b/packages/next-swc/crates/core/src/lib.rs @@ -101,7 +101,7 @@ pub struct TransformOptions { #[serde(default)] #[cfg(not(target_arch = "wasm32"))] - pub relay: Option, + pub relay: Option, #[allow(unused)] #[serde(default)] @@ -142,7 +142,7 @@ where #[cfg(not(target_arch = "wasm32"))] let relay_plugin = { if let Some(config) = &opts.relay { - Either::Left(swc_relay::relay( + Either::Left(turbo_binding::swc::custom_transform::relay::relay( config, file.name.clone(), current_dir().unwrap(), diff --git a/packages/next-swc/crates/core/tests/fixture.rs b/packages/next-swc/crates/core/tests/fixture.rs index 22bc13d8cbb27..6b0401b54249e 100644 --- a/packages/next-swc/crates/core/tests/fixture.rs +++ b/packages/next-swc/crates/core/tests/fixture.rs @@ -12,7 +12,6 @@ use next_swc::{ shake_exports::{shake_exports, Config as ShakeExportsConfig}, }; use next_transform_font::{next_font_loaders, Config as FontLoaderConfig}; -use swc_relay::{relay, RelayLanguageConfig}; use turbo_binding::swc::{ core::{ common::{chain, comments::SingleThreadedComments, FileName, Mark}, @@ -25,6 +24,7 @@ use turbo_binding::swc::{ }, }, }, + custom_transform::relay::{relay, RelayLanguageConfig}, testing::fixture, }; @@ -151,7 +151,7 @@ fn page_config_fixture(input: PathBuf) { #[fixture("tests/fixture/relay/**/input.ts*")] fn relay_no_artifact_dir_fixture(input: PathBuf) { let output = input.parent().unwrap().join("output.js"); - let config = swc_relay::Config { + let config = turbo_binding::swc::custom_transform::relay::Config { language: RelayLanguageConfig::TypeScript, artifact_directory: Some(PathBuf::from("__generated__")), ..Default::default() diff --git a/packages/next-swc/crates/next-core/Cargo.toml b/packages/next-swc/crates/next-core/Cargo.toml index 4137fbbf63903..39463bf3726d1 100644 --- a/packages/next-swc/crates/next-core/Cargo.toml +++ b/packages/next-swc/crates/next-core/Cargo.toml @@ -11,6 +11,7 @@ bench = false [dependencies] anyhow = { workspace = true } async-recursion = "1.0.2" +async-trait = { workspace = true } once_cell = { workspace = true } qstring = { workspace = true } regex = { workspace = true } @@ -24,6 +25,7 @@ futures = { workspace = true } lazy_static = { workspace = true } turbo-binding = { workspace = true, features = [ "__swc_transform_modularize_imports", + "__swc_transform_relay", "__feature_auto_hash_map", "__turbo_tasks", "__turbo_tasks_bytes", @@ -50,6 +52,7 @@ next-transform-dynamic = { workspace = true } swc_core = { workspace = true, features = [ "ecma_ast", + "ecma_transforms", "common", ] } diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index 48408f8101968..08ae3784ceb6a 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -26,6 +26,7 @@ use turbo_binding::{ condition::ContextCondition, module_options::{ module_options_context::{ModuleOptionsContext, ModuleOptionsContextVc}, + CustomEcmascriptTransformPlugins, CustomEcmascriptTransformPluginsVc, JsxTransformOptions, PostCssTransformOptions, TypescriptTransformOptions, WebpackLoadersOptions, }, @@ -50,7 +51,9 @@ use crate::{ get_next_client_fallback_import_map, get_next_client_import_map, get_next_client_resolved_map, }, - next_shared::resolve::UnsupportedModulesResolvePluginVc, + next_shared::{ + resolve::UnsupportedModulesResolvePluginVc, transforms::get_relay_transform_plugin, + }, transform_options::{ get_decorators_transform_options, get_emotion_compiler_config, get_jsx_transform_options, get_styled_components_compiler_config, get_typescript_transform_options, @@ -193,6 +196,18 @@ pub async fn get_client_module_options_context( let enable_emotion = *get_emotion_compiler_config(next_config).await?; + let mut source_transforms = vec![]; + if let Some(relay_transform_plugin) = *get_relay_transform_plugin(next_config).await? { + source_transforms.push(relay_transform_plugin); + } + + let custom_ecma_transform_plugins = Some(CustomEcmascriptTransformPluginsVc::cell( + CustomEcmascriptTransformPlugins { + source_transforms, + output_transforms: vec![], + }, + )); + let module_options_context = ModuleOptionsContext { custom_ecmascript_transforms: vec![EcmascriptInputTransform::ServerDirective( // ServerDirective is not implemented yet and always reports an issue. @@ -201,6 +216,7 @@ pub async fn get_client_module_options_context( )], preset_env_versions: Some(env), execution_context: Some(execution_context), + custom_ecma_transform_plugins, ..Default::default() }; diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index e687baf25eceb..a7efdf528ec9f 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -463,7 +463,7 @@ pub struct RelayConfig { } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TraceRawVcs)] -#[serde(untagged, rename_all = "lowercase")] +#[serde(rename_all = "lowercase")] pub enum RelayLanguage { TypeScript, Flow, diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 84a23be2e79a7..ff1231602f47c 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -19,6 +19,7 @@ use turbo_binding::{ turbopack::{ condition::ContextCondition, module_options::{ + CustomEcmascriptTransformPlugins, CustomEcmascriptTransformPluginsVc, JsxTransformOptions, ModuleOptionsContext, ModuleOptionsContextVc, PostCssTransformOptions, TypescriptTransformOptions, WebpackLoadersOptions, }, @@ -39,7 +40,9 @@ use crate::{ next_config::NextConfigVc, next_import_map::get_next_server_import_map, next_server::resolve::ExternalPredicate, - next_shared::resolve::UnsupportedModulesResolvePluginVc, + next_shared::{ + resolve::UnsupportedModulesResolvePluginVc, transforms::get_relay_transform_plugin, + }, transform_options::{ get_decorators_transform_options, get_emotion_compiler_config, get_jsx_transform_options, get_styled_components_compiler_config, get_typescript_transform_options, @@ -281,6 +284,18 @@ pub async fn get_server_module_options_context( let enable_emotion = *get_emotion_compiler_config(next_config).await?; let enable_styled_components = *get_styled_components_compiler_config(next_config).await?; + let mut source_transforms = vec![]; + if let Some(relay_transform_plugin) = *get_relay_transform_plugin(next_config).await? { + source_transforms.push(relay_transform_plugin); + } + + let custom_ecma_transform_plugins = Some(CustomEcmascriptTransformPluginsVc::cell( + CustomEcmascriptTransformPlugins { + source_transforms, + output_transforms: vec![], + }, + )); + let module_options_context = match ty.into_value() { ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } => { let module_options_context = ModuleOptionsContext { @@ -315,6 +330,7 @@ pub async fn get_server_module_options_context( ), ], custom_rules, + custom_ecma_transform_plugins, ..module_options_context } } @@ -354,6 +370,7 @@ pub async fn get_server_module_options_context( ), ], custom_rules, + custom_ecma_transform_plugins, ..module_options_context } } @@ -397,6 +414,7 @@ pub async fn get_server_module_options_context( ), ], custom_rules, + custom_ecma_transform_plugins, ..module_options_context } } @@ -426,6 +444,7 @@ pub async fn get_server_module_options_context( ), ], custom_rules, + custom_ecma_transform_plugins, ..module_options_context } } @@ -459,6 +478,7 @@ pub async fn get_server_module_options_context( ), ], custom_rules, + custom_ecma_transform_plugins, ..module_options_context } } diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms.rs deleted file mode 100644 index 1746f76de2ad7..0000000000000 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms.rs +++ /dev/null @@ -1,280 +0,0 @@ -use std::{collections::HashMap, path::PathBuf}; - -use anyhow::Result; -use indexmap::IndexMap; -use next_transform_dynamic::{next_dynamic, NextDynamicMode}; -use next_transform_strip_page_exports::{next_transform_strip_page_exports, ExportFilter}; -use serde::{Deserialize, Serialize}; -use swc_core::{ - common::{util::take::Take, FileName}, - ecma::{ - ast::{Module, ModuleItem, Program}, - atoms::JsWord, - visit::{FoldWith, VisitMutWith}, - }, -}; -use turbo_binding::{ - swc::custom_transform::modularize_imports::{modularize_imports, PackageConfig}, - turbo::tasks_fs::FileSystemPathVc, - turbopack::{ - core::reference_type::{ReferenceType, UrlReferenceSubType}, - ecmascript::{ - CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransformsVc, - TransformContext, TransformPluginVc, - }, - turbopack::module_options::{ - ModuleRule, ModuleRuleCondition, ModuleRuleEffect, ModuleType, - }, - }, -}; -use turbo_tasks::{trace::TraceRawVcs, Value}; - -use crate::next_image::{module::BlurPlaceholderMode, StructuredImageModuleTypeVc}; - -/// Returns a rule which applies the Next.js page export stripping transform. -pub async fn get_next_pages_transforms_rule( - pages_dir: FileSystemPathVc, - export_filter: ExportFilter, -) -> Result { - // Apply the Next SSG transform to all pages. - let strip_transform = - EcmascriptInputTransform::Plugin(TransformPluginVc::cell(box NextJsStripPageExports { - export_filter, - })); - Ok(ModuleRule::new( - ModuleRuleCondition::all(vec![ - ModuleRuleCondition::all(vec![ - ModuleRuleCondition::ResourcePathInExactDirectory(pages_dir.await?), - ModuleRuleCondition::not(ModuleRuleCondition::ResourcePathInExactDirectory( - pages_dir.join("api").await?, - )), - ModuleRuleCondition::not(ModuleRuleCondition::any(vec![ - // TODO(alexkirsz): Possibly ignore _app as well? - ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.js").await?), - ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.jsx").await?), - ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.ts").await?), - ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.tsx").await?), - ])), - ]), - module_rule_match_js_no_url(), - ]), - vec![ModuleRuleEffect::AddEcmascriptTransforms( - EcmascriptInputTransformsVc::cell(vec![strip_transform]), - )], - )) -} - -#[derive(Debug)] -struct NextJsStripPageExports { - export_filter: ExportFilter, -} - -impl CustomTransformer for NextJsStripPageExports { - fn transform(&self, program: &mut Program, _ctx: &TransformContext<'_>) -> Option { - // TODO(alexkirsz) Connect the eliminated_packages to telemetry. - let eliminated_packages = Default::default(); - - let module_program = unwrap_module_program(program); - Some( - module_program.fold_with(&mut next_transform_strip_page_exports( - self.export_filter, - eliminated_packages, - )), - ) - } -} - -/// Returns a rule which applies the Next.js dynamic transform. -pub fn get_next_image_rule() -> ModuleRule { - ModuleRule::new( - ModuleRuleCondition::any(vec![ - ModuleRuleCondition::ResourcePathEndsWith(".jpg".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".jpeg".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".png".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".webp".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".avif".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".apng".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".gif".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".svg".to_string()), - ]), - vec![ModuleRuleEffect::ModuleType(ModuleType::Custom( - StructuredImageModuleTypeVc::new(Value::new(BlurPlaceholderMode::DataUrl)).into(), - ))], - ) -} - -/// Returns a rule which applies the Next.js dynamic transform. -pub async fn get_next_dynamic_transform_rule( - is_development: bool, - is_server: bool, - is_server_components: bool, - pages_dir: Option, -) -> Result { - let dynamic_transform = - EcmascriptInputTransform::Plugin(TransformPluginVc::cell(box NextJsDynamic { - is_development, - is_server, - is_server_components, - pages_dir: match pages_dir { - None => None, - Some(path) => Some(path.await?.path.clone().into()), - }, - })); - Ok(ModuleRule::new( - module_rule_match_js_no_url(), - vec![ModuleRuleEffect::AddEcmascriptTransforms( - EcmascriptInputTransformsVc::cell(vec![dynamic_transform]), - )], - )) -} - -#[derive(Debug)] -struct NextJsDynamic { - is_development: bool, - is_server: bool, - is_server_components: bool, - pages_dir: Option, -} - -impl CustomTransformer for NextJsDynamic { - fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Option { - let module_program = unwrap_module_program(program); - Some(module_program.fold_with(&mut next_dynamic( - self.is_development, - self.is_server, - self.is_server_components, - NextDynamicMode::Turbo, - FileName::Real(ctx.file_path_str.into()), - self.pages_dir.clone(), - ))) - } -} - -/// Returns a rule which applies the Next.js font transform. -pub fn get_next_font_transform_rule() -> ModuleRule { - let font_loaders = vec![ - "next/font/google".into(), - "@next/font/google".into(), - "next/font/local".into(), - "@next/font/local".into(), - ]; - - let transformer = - EcmascriptInputTransform::Plugin(TransformPluginVc::cell(box NextJsFont { font_loaders })); - ModuleRule::new( - // TODO: Only match in pages (not pages/api), app/, etc. - module_rule_match_js_no_url(), - vec![ModuleRuleEffect::AddEcmascriptTransforms( - EcmascriptInputTransformsVc::cell(vec![transformer]), - )], - ) -} - -#[derive(Debug)] -struct NextJsFont { - font_loaders: Vec, -} - -impl CustomTransformer for NextJsFont { - fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Option { - let mut next_font = next_transform_font::next_font_loaders(next_transform_font::Config { - font_loaders: self.font_loaders.clone(), - relative_file_path_from_root: ctx.file_name_str.into(), - }); - - program.visit_mut_with(&mut next_font); - None - } -} - -fn module_rule_match_js_no_url() -> ModuleRuleCondition { - ModuleRuleCondition::all(vec![ - ModuleRuleCondition::not(ModuleRuleCondition::ReferenceType(ReferenceType::Url( - UrlReferenceSubType::Undefined, - ))), - ModuleRuleCondition::any(vec![ - ModuleRuleCondition::ResourcePathEndsWith(".js".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".jsx".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".ts".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".tsx".to_string()), - ]), - ]) -} - -fn unwrap_module_program(program: &mut Program) -> Program { - match program { - Program::Module(module) => Program::Module(module.take()), - Program::Script(s) => Program::Module(Module { - span: s.span, - body: s - .body - .iter() - .map(|stmt| ModuleItem::Stmt(stmt.clone())) - .collect(), - shebang: s.shebang.clone(), - }), - } -} - -#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)] -#[serde(rename_all = "camelCase")] -pub struct ModularizeImportPackageConfig { - pub transform: String, - #[serde(default)] - pub prevent_full_import: bool, - #[serde(default)] - pub skip_default_conversion: bool, -} - -/// Returns a rule which applies the Next.js modularize imports transform. -pub fn get_next_modularize_imports_rule( - modularize_imports_config: &IndexMap, -) -> ModuleRule { - let transformer = EcmascriptInputTransform::Plugin(TransformPluginVc::cell(Box::new( - ModularizeImportsTransformer::new(modularize_imports_config), - ))); - ModuleRule::new( - module_rule_match_js_no_url(), - vec![ModuleRuleEffect::AddEcmascriptTransforms( - EcmascriptInputTransformsVc::cell(vec![transformer]), - )], - ) -} - -#[derive(Debug)] -struct ModularizeImportsTransformer { - packages: HashMap, -} - -impl ModularizeImportsTransformer { - fn new(packages: &IndexMap) -> Self { - Self { - packages: packages - .iter() - .map(|(k, v)| { - ( - k.clone(), - PackageConfig { - transform: v.transform.clone(), - prevent_full_import: v.prevent_full_import, - skip_default_conversion: v.skip_default_conversion, - }, - ) - }) - .collect(), - } - } -} - -impl CustomTransformer for ModularizeImportsTransformer { - fn transform(&self, program: &mut Program, _ctx: &TransformContext<'_>) -> Option { - let p = std::mem::replace(program, Program::Module(Module::dummy())); - *program = p.fold_with(&mut modularize_imports( - turbo_binding::swc::custom_transform::modularize_imports::Config { - packages: self.packages.clone(), - }, - )); - - None - } -} diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs new file mode 100644 index 0000000000000..96293968fe2fa --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs @@ -0,0 +1,70 @@ +pub(crate) mod modularize_imports; +pub(crate) mod next_dynamic; +pub(crate) mod next_font; +pub(crate) mod next_strip_page_exports; +pub(crate) mod relay; + +pub use modularize_imports::{get_next_modularize_imports_rule, ModularizeImportPackageConfig}; +pub use next_dynamic::get_next_dynamic_transform_rule; +pub use next_font::get_next_font_transform_rule; +pub use next_strip_page_exports::get_next_pages_transforms_rule; +pub use relay::get_relay_transform_plugin; +use swc_core::{ + common::util::take::Take, + ecma::ast::{Module, ModuleItem, Program}, +}; +use turbo_binding::turbopack::{ + core::reference_type::{ReferenceType, UrlReferenceSubType}, + turbopack::module_options::{ModuleRule, ModuleRuleCondition, ModuleRuleEffect, ModuleType}, +}; +use turbo_tasks::Value; + +use crate::next_image::{module::BlurPlaceholderMode, StructuredImageModuleTypeVc}; + +/// Returns a rule which applies the Next.js dynamic transform. +pub fn get_next_image_rule() -> ModuleRule { + ModuleRule::new( + ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".jpg".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jpeg".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".png".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".webp".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".avif".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".apng".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".gif".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".svg".to_string()), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Custom( + StructuredImageModuleTypeVc::new(Value::new(BlurPlaceholderMode::DataUrl)).into(), + ))], + ) +} + +pub(crate) fn module_rule_match_js_no_url() -> ModuleRuleCondition { + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::not(ModuleRuleCondition::ReferenceType(ReferenceType::Url( + UrlReferenceSubType::Undefined, + ))), + ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".js".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jsx".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".ts".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".tsx".to_string()), + ]), + ]) +} + +pub(crate) fn unwrap_module_program(program: &mut Program) -> Program { + match program { + Program::Module(module) => Program::Module(module.take()), + Program::Script(s) => Program::Module(Module { + span: s.span, + body: s + .body + .iter() + .map(|stmt| ModuleItem::Stmt(stmt.clone())) + .collect(), + shebang: s.shebang.clone(), + }), + } +} diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs new file mode 100644 index 0000000000000..e4b495035d0ee --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs @@ -0,0 +1,94 @@ +use std::collections::HashMap; + +use anyhow::Result; +use async_trait::async_trait; +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::util::take::Take, + ecma::{ + ast::{Module, Program}, + visit::FoldWith, + }, +}; +use turbo_binding::{ + swc::custom_transform::modularize_imports::{modularize_imports, PackageConfig}, + turbopack::{ + ecmascript::{ + CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransformsVc, + TransformContext, TransformPluginVc, + }, + turbopack::module_options::{ModuleRule, ModuleRuleEffect}, + }, +}; +use turbo_tasks::trace::TraceRawVcs; + +use super::module_rule_match_js_no_url; + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)] +#[serde(rename_all = "camelCase")] +pub struct ModularizeImportPackageConfig { + pub transform: String, + #[serde(default)] + pub prevent_full_import: bool, + #[serde(default)] + pub skip_default_conversion: bool, +} + +/// Returns a rule which applies the Next.js modularize imports transform. +pub fn get_next_modularize_imports_rule( + modularize_imports_config: &IndexMap, +) -> ModuleRule { + let transformer = EcmascriptInputTransform::Plugin(TransformPluginVc::cell(Box::new( + ModularizeImportsTransformer::new(modularize_imports_config), + ))); + ModuleRule::new( + module_rule_match_js_no_url(), + vec![ModuleRuleEffect::AddEcmascriptTransforms( + EcmascriptInputTransformsVc::cell(vec![transformer]), + )], + ) +} + +#[derive(Debug)] +struct ModularizeImportsTransformer { + packages: HashMap, +} + +impl ModularizeImportsTransformer { + fn new(packages: &IndexMap) -> Self { + Self { + packages: packages + .iter() + .map(|(k, v)| { + ( + k.clone(), + PackageConfig { + transform: v.transform.clone(), + prevent_full_import: v.prevent_full_import, + skip_default_conversion: v.skip_default_conversion, + }, + ) + }) + .collect(), + } + } +} + +#[async_trait] +impl CustomTransformer for ModularizeImportsTransformer { + async fn transform( + &self, + program: &mut Program, + _ctx: &TransformContext<'_>, + ) -> Result> { + let p = std::mem::replace(program, Program::Module(Module::dummy())); + *program = p.fold_with(&mut modularize_imports( + turbo_binding::swc::custom_transform::modularize_imports::Config { + packages: self.packages.clone(), + }, + )); + + Ok(None) + } +} diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs new file mode 100644 index 0000000000000..763ece5427777 --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs @@ -0,0 +1,73 @@ +use std::path::PathBuf; + +use anyhow::Result; +use async_trait::async_trait; +use next_transform_dynamic::{next_dynamic, NextDynamicMode}; +use swc_core::{ + common::FileName, + ecma::{ast::Program, visit::FoldWith}, +}; +use turbo_binding::{ + turbo::tasks_fs::FileSystemPathVc, + turbopack::{ + ecmascript::{ + CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransformsVc, + TransformContext, TransformPluginVc, + }, + turbopack::module_options::{ModuleRule, ModuleRuleEffect}, + }, +}; + +use super::{module_rule_match_js_no_url, unwrap_module_program}; + +/// Returns a rule which applies the Next.js dynamic transform. +pub async fn get_next_dynamic_transform_rule( + is_development: bool, + is_server: bool, + is_server_components: bool, + pages_dir: Option, +) -> Result { + let dynamic_transform = + EcmascriptInputTransform::Plugin(TransformPluginVc::cell(box NextJsDynamic { + is_development, + is_server, + is_server_components, + pages_dir: match pages_dir { + None => None, + Some(path) => Some(path.await?.path.clone().into()), + }, + })); + Ok(ModuleRule::new( + module_rule_match_js_no_url(), + vec![ModuleRuleEffect::AddEcmascriptTransforms( + EcmascriptInputTransformsVc::cell(vec![dynamic_transform]), + )], + )) +} + +#[derive(Debug)] +struct NextJsDynamic { + is_development: bool, + is_server: bool, + is_server_components: bool, + pages_dir: Option, +} + +#[async_trait] +impl CustomTransformer for NextJsDynamic { + async fn transform( + &self, + program: &mut Program, + ctx: &TransformContext<'_>, + ) -> Result> { + let module_program = unwrap_module_program(program); + Ok(Some(module_program.fold_with(&mut next_dynamic( + self.is_development, + self.is_server, + self.is_server_components, + NextDynamicMode::Turbo, + FileName::Real(ctx.file_path_str.into()), + self.pages_dir.clone(), + )))) + } +} diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs new file mode 100644 index 0000000000000..b8815b916994f --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs @@ -0,0 +1,54 @@ +use anyhow::Result; +use async_trait::async_trait; +use swc_core::ecma::{ast::Program, atoms::JsWord, visit::VisitMutWith}; +use turbo_binding::turbopack::{ + ecmascript::{ + CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransformsVc, TransformContext, + TransformPluginVc, + }, + turbopack::module_options::{ModuleRule, ModuleRuleEffect}, +}; + +use super::module_rule_match_js_no_url; + +/// Returns a rule which applies the Next.js font transform. +pub fn get_next_font_transform_rule() -> ModuleRule { + let font_loaders = vec![ + "next/font/google".into(), + "@next/font/google".into(), + "next/font/local".into(), + "@next/font/local".into(), + ]; + + let transformer = + EcmascriptInputTransform::Plugin(TransformPluginVc::cell(box NextJsFont { font_loaders })); + ModuleRule::new( + // TODO: Only match in pages (not pages/api), app/, etc. + module_rule_match_js_no_url(), + vec![ModuleRuleEffect::AddEcmascriptTransforms( + EcmascriptInputTransformsVc::cell(vec![transformer]), + )], + ) +} + +#[derive(Debug)] +struct NextJsFont { + font_loaders: Vec, +} + +#[async_trait] +impl CustomTransformer for NextJsFont { + async fn transform( + &self, + program: &mut Program, + ctx: &TransformContext<'_>, + ) -> Result> { + let mut next_font = next_transform_font::next_font_loaders(next_transform_font::Config { + font_loaders: self.font_loaders.clone(), + relative_file_path_from_root: ctx.file_name_str.into(), + }); + + program.visit_mut_with(&mut next_font); + Ok(None) + } +} diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs new file mode 100644 index 0000000000000..7af7f240e799b --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs @@ -0,0 +1,71 @@ +use anyhow::Result; +use async_trait::async_trait; +use next_transform_strip_page_exports::{next_transform_strip_page_exports, ExportFilter}; +use swc_core::ecma::{ast::Program, visit::FoldWith}; +use turbo_binding::{ + turbo::tasks_fs::FileSystemPathVc, + turbopack::{ + ecmascript::{ + CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransformsVc, + TransformContext, TransformPluginVc, + }, + turbopack::module_options::{ModuleRule, ModuleRuleCondition, ModuleRuleEffect}, + }, +}; + +use super::{module_rule_match_js_no_url, unwrap_module_program}; + +/// Returns a rule which applies the Next.js page export stripping transform. +pub async fn get_next_pages_transforms_rule( + pages_dir: FileSystemPathVc, + export_filter: ExportFilter, +) -> Result { + // Apply the Next SSG transform to all pages. + let strip_transform = + EcmascriptInputTransform::Plugin(TransformPluginVc::cell(box NextJsStripPageExports { + export_filter, + })); + Ok(ModuleRule::new( + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::ResourcePathInExactDirectory(pages_dir.await?), + ModuleRuleCondition::not(ModuleRuleCondition::ResourcePathInExactDirectory( + pages_dir.join("api").await?, + )), + ModuleRuleCondition::not(ModuleRuleCondition::any(vec![ + // TODO(alexkirsz): Possibly ignore _app as well? + ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.js").await?), + ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.jsx").await?), + ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.ts").await?), + ModuleRuleCondition::ResourcePathEquals(pages_dir.join("_document.tsx").await?), + ])), + ]), + module_rule_match_js_no_url(), + ]), + vec![ModuleRuleEffect::AddEcmascriptTransforms( + EcmascriptInputTransformsVc::cell(vec![strip_transform]), + )], + )) +} + +#[derive(Debug)] +struct NextJsStripPageExports { + export_filter: ExportFilter, +} + +#[async_trait] +impl CustomTransformer for NextJsStripPageExports { + async fn transform( + &self, + program: &mut Program, + _ctx: &TransformContext<'_>, + ) -> Result> { + // TODO(alexkirsz) Connect the eliminated_packages to telemetry. + let eliminated_packages = Default::default(); + + let module_program = unwrap_module_program(program); + Ok(Some(module_program.fold_with( + &mut next_transform_strip_page_exports(self.export_filter, eliminated_packages), + ))) + } +} diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/relay.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/relay.rs new file mode 100644 index 0000000000000..31c6158fbe0b5 --- /dev/null +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/relay.rs @@ -0,0 +1,50 @@ +use std::path::PathBuf; + +use anyhow::Result; +use turbo_binding::{ + swc::custom_transform::relay::{Config, RelayLanguageConfig}, + turbopack::{ + ecmascript::{OptionTransformPluginVc, TransformPluginVc}, + ecmascript_plugin::transform::relay::RelayTransformer, + }, +}; + +use crate::next_config::{NextConfigVc, RelayLanguage}; + +/// Returns a transform plugin for the relay graphql transform. +#[turbo_tasks::function] +pub async fn get_relay_transform_plugin( + next_config: NextConfigVc, +) -> Result { + let transform_plugin = next_config + .await? + .compiler + .as_ref() + .map(|value| { + value + .relay + .as_ref() + .map(|config| { + // [TODO]: There are config mismatches between RelayConfig to swc_relay::Config + let swc_relay_config = Config { + artifact_directory: config.artifact_directory.as_ref().map(PathBuf::from), + language: config.language.as_ref().map_or( + RelayLanguageConfig::TypeScript, + |v| match v { + RelayLanguage::JavaScript => RelayLanguageConfig::JavaScript, + RelayLanguage::TypeScript => RelayLanguageConfig::TypeScript, + RelayLanguage::Flow => RelayLanguageConfig::Flow, + }, + ), + ..Default::default() + }; + OptionTransformPluginVc::cell(Some(TransformPluginVc::cell(Box::new( + RelayTransformer::new(swc_relay_config), + )))) + }) + .unwrap_or(Default::default()) + }) + .unwrap_or(Default::default()); + + Ok(transform_plugin) +} diff --git a/packages/next-swc/crates/next-core/src/transform_options.rs b/packages/next-swc/crates/next-core/src/transform_options.rs index 88bc9b660094d..4eac2abb0c034 100644 --- a/packages/next-swc/crates/next-core/src/transform_options.rs +++ b/packages/next-swc/crates/next-core/src/transform_options.rs @@ -1,21 +1,24 @@ use anyhow::Result; -use turbo_binding::turbopack::{ - core::{ - asset::AssetVc, - resolve::{find_context_file, node::node_cjs_resolve_options, FindContextFileResult}, - source_asset::SourceAssetVc, - }, - ecmascript::typescript::resolve::{read_from_tsconfigs, read_tsconfigs, tsconfig}, - ecmascript_plugin::transform::emotion::{ - EmotionTransformConfig, EmotionTransformConfigVc, OptionEmotionTransformConfigVc, - }, - turbopack::module_options::{ - DecoratorsKind, DecoratorsOptions, DecoratorsOptionsVc, JsxTransformOptions, - JsxTransformOptionsVc, OptionStyledComponentsTransformConfigVc, - StyledComponentsTransformConfig, TypescriptTransformOptions, TypescriptTransformOptionsVc, +use turbo_binding::{ + turbo::tasks_fs::{FileJsonContentVc, FileSystemPathVc}, + turbopack::{ + core::{ + asset::AssetVc, + resolve::{find_context_file, node::node_cjs_resolve_options, FindContextFileResult}, + source_asset::SourceAssetVc, + }, + ecmascript::typescript::resolve::{read_from_tsconfigs, read_tsconfigs, tsconfig}, + ecmascript_plugin::transform::emotion::{ + EmotionTransformConfig, EmotionTransformConfigVc, OptionEmotionTransformConfigVc, + }, + turbopack::module_options::{ + DecoratorsKind, DecoratorsOptions, DecoratorsOptionsVc, JsxTransformOptions, + JsxTransformOptionsVc, OptionStyledComponentsTransformConfigVc, + StyledComponentsTransformConfig, TypescriptTransformOptions, + TypescriptTransformOptionsVc, + }, }, }; -use turbo_tasks_fs::{FileJsonContentVc, FileSystemPathVc}; use crate::next_config::{ EmotionTransformOptionsOrBoolean, NextConfigVc, StyledComponentsTransformOptionsOrBoolean, diff --git a/packages/next-swc/crates/next-dev-tests/Cargo.toml b/packages/next-swc/crates/next-dev-tests/Cargo.toml index 2f55521d8e8b8..048f36819e761 100644 --- a/packages/next-swc/crates/next-dev-tests/Cargo.toml +++ b/packages/next-swc/crates/next-dev-tests/Cargo.toml @@ -54,6 +54,7 @@ turbo-binding = { workspace = true, features = [ "__turbopack_core_issue_path", "__turbopack_node", "__turbopack_dev_server", + "__swc_transform_relay" ]} turbo-tasks = { workspace = true } url = { workspace = true } diff --git a/packages/next/src/lib/turbopack-warning.ts b/packages/next/src/lib/turbopack-warning.ts index e207436859fec..b7373125227ff 100644 --- a/packages/next/src/lib/turbopack-warning.ts +++ b/packages/next/src/lib/turbopack-warning.ts @@ -8,6 +8,7 @@ const supportedTurbopackNextConfigOptions = [ 'env', 'modularizeImports', 'compiler.emotion', + 'compiler.relay', 'compiler.styledComponents', 'images', 'pageExtensions',