From d79f8a2f0381e23ac9b82fb7428f306e7a40a360 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:16:12 -0700 Subject: [PATCH] fix(next-core): allow sass loader for foreign codes (#56679) ### What? - closes https://github.com/vercel/next.js/issues/55785 Similar to https://github.com/vercel/next.js/pull/56539, next.config's sass applies webpack loaders to node_modules implicitly and this PR mimics those for the turbopack. Closes WEB-1753 --- .../next-core/src/next_client/context.rs | 35 ++++++++++++-- .../next-core/src/next_server/context.rs | 47 ++++++++++++++++--- 2 files changed, 71 insertions(+), 11 deletions(-) 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 08069da234d60..87679893aaf41 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 @@ -212,9 +212,29 @@ pub async fn get_client_module_options_context( false, next_config, ); - let webpack_rules = - *maybe_add_babel_loader(project_path, *next_config.webpack_rules().await?).await?; - let webpack_rules = maybe_add_sass_loader(next_config.sass_config(), webpack_rules).await?; + + // A separate webpack rules will be applied to codes matching + // foreign_code_context_condition. This allows to import codes from + // node_modules that requires webpack loaders, which next-dev implicitly + // does by default. + let foreign_webpack_rules = maybe_add_sass_loader( + next_config.sass_config(), + *next_config.webpack_rules().await?, + ) + .await?; + let foreign_webpack_loaders = foreign_webpack_rules.map(|rules| { + WebpackLoadersOptions { + rules, + loader_runner_package: Some(get_external_next_compiled_package_mapping(Vc::cell( + "loader-runner".to_owned(), + ))), + } + .cell() + }); + + // Now creates a webpack rules that applies to all codes. + let webpack_rules = *foreign_webpack_rules.clone(); + let webpack_rules = *maybe_add_babel_loader(project_path, webpack_rules).await?; let enable_webpack_loaders = webpack_rules.map(|rules| { WebpackLoadersOptions { rules, @@ -252,9 +272,14 @@ pub async fn get_client_module_options_context( preset_env_versions: Some(env), execution_context: Some(execution_context), custom_ecma_transform_plugins, + ..Default::default() + }; + + let foreign_codes_options_context = ModuleOptionsContext { + enable_webpack_loaders: foreign_webpack_loaders, // NOTE(WEB-1016) PostCSS transforms should also apply to foreign code. enable_postcss_transform: postcss_transform_options.clone(), - ..Default::default() + ..module_options_context.clone() }; let module_options_context = ModuleOptionsContext { @@ -270,7 +295,7 @@ pub async fn get_client_module_options_context( rules: vec![ ( foreign_code_context_condition(next_config, project_path).await?, - module_options_context.clone().cell(), + foreign_codes_options_context.cell(), ), // If the module is an internal asset (i.e overlay, fallback) coming from the embedded // FS, don't apply user defined transforms. 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 dd2e3da1b3acc..1b37989f9354b 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 @@ -272,9 +272,28 @@ pub async fn get_server_module_options_context( ..Default::default() }); - let webpack_rules = - *maybe_add_babel_loader(project_path, *next_config.webpack_rules().await?).await?; - let webpack_rules = maybe_add_sass_loader(next_config.sass_config(), webpack_rules).await?; + // A separate webpack rules will be applied to codes matching + // foreign_code_context_condition. This allows to import codes from + // node_modules that requires webpack loaders, which next-dev implicitly + // does by default. + let foreign_webpack_rules = maybe_add_sass_loader( + next_config.sass_config(), + *next_config.webpack_rules().await?, + ) + .await?; + let foreign_webpack_loaders = foreign_webpack_rules.map(|rules| { + WebpackLoadersOptions { + rules, + loader_runner_package: Some(get_external_next_compiled_package_mapping(Vc::cell( + "loader-runner".to_owned(), + ))), + } + .cell() + }); + + // Now creates a webpack rules that applies to all codes. + let webpack_rules = *foreign_webpack_rules.clone(); + let webpack_rules = *maybe_add_babel_loader(project_path, webpack_rules).await?; let enable_webpack_loaders = webpack_rules.map(|rules| { WebpackLoadersOptions { rules, @@ -348,6 +367,12 @@ pub async fn get_server_module_options_context( ..Default::default() }; + let foreign_code_module_options_context = ModuleOptionsContext { + custom_rules: internal_custom_rules.clone(), + enable_webpack_loaders: foreign_webpack_loaders, + ..module_options_context.clone() + }; + let internal_module_options_context = ModuleOptionsContext { enable_typescript_transform: Some(TypescriptTransformOptions::default().cell()), enable_jsx: Some(JsxTransformOptions::default().cell()), @@ -365,7 +390,7 @@ pub async fn get_server_module_options_context( rules: vec![ ( foreign_code_context_condition, - module_options_context.clone().cell(), + foreign_code_module_options_context.cell(), ), ( ContextCondition::InPath(next_js_fs().root()), @@ -407,6 +432,11 @@ pub async fn get_server_module_options_context( execution_context: Some(execution_context), ..Default::default() }; + let foreign_code_module_options_context = ModuleOptionsContext { + custom_rules: internal_custom_rules.clone(), + enable_webpack_loaders: foreign_webpack_loaders, + ..module_options_context.clone() + }; let internal_module_options_context = ModuleOptionsContext { enable_typescript_transform: Some(TypescriptTransformOptions::default().cell()), custom_rules: internal_custom_rules, @@ -423,7 +453,7 @@ pub async fn get_server_module_options_context( rules: vec![ ( foreign_code_context_condition, - module_options_context.clone().cell(), + foreign_code_module_options_context.cell(), ), ( ContextCondition::InPath(next_js_fs().root()), @@ -474,6 +504,11 @@ pub async fn get_server_module_options_context( execution_context: Some(execution_context), ..Default::default() }; + let foreign_code_module_options_context = ModuleOptionsContext { + custom_rules: internal_custom_rules.clone(), + enable_webpack_loaders: foreign_webpack_loaders, + ..module_options_context.clone() + }; let internal_module_options_context = ModuleOptionsContext { enable_typescript_transform: Some(TypescriptTransformOptions::default().cell()), custom_rules: internal_custom_rules, @@ -489,7 +524,7 @@ pub async fn get_server_module_options_context( rules: vec![ ( foreign_code_context_condition, - module_options_context.clone().cell(), + foreign_code_module_options_context.cell(), ), ( ContextCondition::InPath(next_js_fs().root()),