diff --git a/packages/next-swc/crates/core/src/lib.rs b/packages/next-swc/crates/core/src/lib.rs index ddc76edec38a8..32c6c02218955 100644 --- a/packages/next-swc/crates/core/src/lib.rs +++ b/packages/next-swc/crates/core/src/lib.rs @@ -185,6 +185,7 @@ where next_dynamic::next_dynamic( opts.is_development, opts.is_server, + opts.server_components.is_some(), file.name.clone(), opts.pages_dir.clone() ), diff --git a/packages/next-swc/crates/core/src/next_dynamic.rs b/packages/next-swc/crates/core/src/next_dynamic.rs index ecc3d726cdcf4..7e0588c02b03b 100644 --- a/packages/next-swc/crates/core/src/next_dynamic.rs +++ b/packages/next-swc/crates/core/src/next_dynamic.rs @@ -17,12 +17,14 @@ use swc_core::{ pub fn next_dynamic( is_development: bool, is_server: bool, + is_server_components: bool, filename: FileName, pages_dir: Option, ) -> impl Fold { NextDynamicPatcher { is_development, is_server, + is_server_components, pages_dir, filename, dynamic_bindings: vec![], @@ -35,6 +37,7 @@ pub fn next_dynamic( struct NextDynamicPatcher { is_development: bool, is_server: bool, + is_server_components: bool, pages_dir: Option, filename: FileName, dynamic_bindings: Vec, @@ -279,9 +282,18 @@ impl Fold for NextDynamicPatcher { props.extend(options_props.iter().cloned()); } } - // Don't need to strip the `loader` argument if suspense is true - // See https://github.com/vercel/next.js/issues/36636 for background - if has_ssr_false && !has_suspense && self.is_server { + + // Don't strip the `loader` argument if suspense is true + // See https://github.com/vercel/next.js/issues/36636 for background. + + // Also don't strip the `loader` argument for server components (both + // server/client layers), since they're aliased to a + // React.lazy implementation. + if has_ssr_false + && !has_suspense + && self.is_server + && !self.is_server_components + { expr.args[0] = Lit::Null(Null { span: DUMMY_SP }).as_arg(); } diff --git a/packages/next-swc/crates/core/tests/errors.rs b/packages/next-swc/crates/core/tests/errors.rs index 303262c1356e6..8bee4c9b5bf8e 100644 --- a/packages/next-swc/crates/core/tests/errors.rs +++ b/packages/next-swc/crates/core/tests/errors.rs @@ -46,6 +46,7 @@ fn next_dynamic_errors(input: PathBuf) { next_dynamic( true, false, + false, FileName::Real(PathBuf::from("/some-project/src/some-file.js")), Some("/some-project/src".into()), ) diff --git a/packages/next-swc/crates/core/tests/fixture.rs b/packages/next-swc/crates/core/tests/fixture.rs index cc7f9cd85b334..478f667c1ccd0 100644 --- a/packages/next-swc/crates/core/tests/fixture.rs +++ b/packages/next-swc/crates/core/tests/fixture.rs @@ -49,6 +49,7 @@ fn next_dynamic_fixture(input: PathBuf) { next_dynamic( true, false, + false, FileName::Real(PathBuf::from("/some-project/src/some-file.js")), Some("/some-project/src".into()), ) @@ -61,6 +62,7 @@ fn next_dynamic_fixture(input: PathBuf) { syntax(), &|_tr| { next_dynamic( + false, false, false, FileName::Real(PathBuf::from("/some-project/src/some-file.js")), @@ -77,6 +79,7 @@ fn next_dynamic_fixture(input: PathBuf) { next_dynamic( false, true, + false, FileName::Real(PathBuf::from("/some-project/src/some-file.js")), Some("/some-project/src".into()), ) diff --git a/test/e2e/app-dir/app/app/dashboard/index/dynamic-imports/dynamic-server.js b/test/e2e/app-dir/app/app/dashboard/index/dynamic-imports/dynamic-server.js index 665da40efa5d2..267a1febc5daa 100644 --- a/test/e2e/app-dir/app/app/dashboard/index/dynamic-imports/dynamic-server.js +++ b/test/e2e/app-dir/app/app/dashboard/index/dynamic-imports/dynamic-server.js @@ -1,6 +1,8 @@ import dynamic from 'next/dynamic' -const Dynamic = dynamic(() => import('../text-dynamic-server')) +const Dynamic = dynamic(() => import('../text-dynamic-server'), { + ssr: false, +}) export function NextDynamicServerComponent() { return