Skip to content

Commit

Permalink
Turbopack: import webpack loader rules conditions (#64205)
Browse files Browse the repository at this point in the history
### What?

* remove custom next-* conditions
* add `foreign` condition
* allow `false` in turbo.rules
* improve schema for turbo.rules

### Why?

### How?



Closes PACK-2913

---------

Co-authored-by: Tim Neutkens <[email protected]>
  • Loading branch information
sokra and timneutkens authored Apr 11, 2024
1 parent 265d7b9 commit b912492
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 163 deletions.
2 changes: 0 additions & 2 deletions packages/next-swc/crates/next-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

pub mod app_segment_config;
pub mod app_structure;
mod babel;
mod bootstrap;
mod embed_js;
mod emit;
Expand All @@ -33,7 +32,6 @@ mod next_shared;
pub mod next_telemetry;
mod page_loader;
pub mod pages_structure;
mod sass;
pub mod tracing_presets;
mod transform_options;
pub mod url_node;
Expand Down
63 changes: 20 additions & 43 deletions packages/next-swc/crates/next-core/src/next_client/context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::iter::once;

use anyhow::Result;
use indexmap::IndexMap;
use turbo_tasks::{Value, Vc};
Expand Down Expand Up @@ -25,7 +27,6 @@ use turbopack_binding::{
module_options::{
module_options_context::ModuleOptionsContext, JsxTransformOptions,
MdxTransformModuleOptions, ModuleRule, TypescriptTransformOptions,
WebpackLoadersOptions,
},
resolve_options_context::ResolveOptionsContext,
},
Expand All @@ -34,10 +35,9 @@ use turbopack_binding::{

use super::transforms::get_next_client_transforms_rules;
use crate::{
babel::maybe_add_babel_loader,
embed_js::next_js_fs,
mode::NextMode,
next_build::{get_external_next_compiled_package_mapping, get_postcss_package_mapping},
next_build::get_postcss_package_mapping,
next_client::runtime_entry::{RuntimeEntries, RuntimeEntry},
next_config::NextConfig,
next_import_map::{
Expand All @@ -55,8 +55,8 @@ use crate::{
styled_jsx::get_styled_jsx_transform_rule,
swc_ecma_transform_plugins::get_swc_ecma_transform_plugin_rule,
},
webpack_rules::webpack_loader_options,
},
sass::maybe_add_sass_loader,
transform_options::{
get_decorators_transform_options, get_jsx_transform_options,
get_typescript_transform_options,
Expand Down Expand Up @@ -134,17 +134,6 @@ pub enum ClientContextType {
Other,
}

impl ClientContextType {
pub fn conditions(&self) -> &'static [&'static str] {
match self {
ClientContextType::Pages { .. } => &["next-client", "next-pages"],
ClientContextType::App { .. } => &["next-client", "next-app"],
ClientContextType::Fallback => &["next-client", "next-fallback"],
ClientContextType::Other => &["next-client", "next-other"],
}
}
}

#[turbo_tasks::function]
pub async fn get_client_resolve_options_context(
project_path: Vc<FileSystemPath>,
Expand All @@ -158,8 +147,7 @@ pub async fn get_client_resolve_options_context(
let next_client_fallback_import_map = get_next_client_fallback_import_map(ty);
let next_client_resolved_map =
get_next_client_resolved_map(project_path, project_path, *mode.await?);
let mut custom_conditions = vec![mode.await?.condition().to_string()];
custom_conditions.extend(ty.conditions().iter().map(ToString::to_string));
let custom_conditions = vec![mode.await?.condition().to_string()];
let module_options_context = ResolveOptionsContext {
enable_node_modules: Some(project_path.root().resolve().await?),
custom_conditions,
Expand Down Expand Up @@ -226,33 +214,22 @@ pub async fn get_client_module_options_context(
// foreign_code_context_condition. This allows to import codes from
// node_modules that requires webpack loaders, which next-dev implicitly
// does by default.
let mut conditions = vec!["browser".to_string(), mode.await?.condition().to_string()];
conditions.extend(ty.conditions().iter().map(ToString::to_string));
let foreign_webpack_rules = *next_config.webpack_rules(conditions).await?;
let foreign_webpack_rules =
maybe_add_sass_loader(next_config.sass_config(), foreign_webpack_rules).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()
});
let conditions = vec!["browser".to_string(), mode.await?.condition().to_string()];
let foreign_enable_webpack_loaders = webpack_loader_options(
project_path,
next_config,
true,
conditions
.iter()
.cloned()
.chain(once("foreign".to_string()))
.collect(),
)
.await?;

// 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,
loader_runner_package: Some(get_external_next_compiled_package_mapping(Vc::cell(
"loader-runner".to_owned(),
))),
}
.cell()
});
let enable_webpack_loaders =
webpack_loader_options(project_path, next_config, false, conditions).await?;

let use_swc_css = *next_config.use_swc_css().await?;
let target_browsers = env.runtime_versions();
Expand Down Expand Up @@ -299,7 +276,7 @@ pub async fn get_client_module_options_context(

// node_modules context
let foreign_codes_options_context = ModuleOptionsContext {
enable_webpack_loaders: foreign_webpack_loaders,
enable_webpack_loaders: foreign_enable_webpack_loaders,
enable_postcss_transform: enable_foreign_postcss_transform,
custom_rules: foreign_next_client_rules,
// NOTE(WEB-1016) PostCSS transforms should also apply to foreign code.
Expand Down
27 changes: 19 additions & 8 deletions packages/next-swc/crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ pub enum RuleConfigItemOrShortcut {
pub enum RuleConfigItem {
Options(RuleConfigItemOptions),
Conditional(IndexMap<String, RuleConfigItem>),
Boolean(bool),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TraceRawVcs)]
Expand Down Expand Up @@ -736,25 +737,35 @@ impl NextConfig {
.collect(),
)
}
enum FindRuleResult<'a> {
Found(&'a RuleConfigItemOptions),
NotFound,
Break,
}
fn find_rule<'a>(
rule: &'a RuleConfigItem,
active_conditions: &HashSet<String>,
) -> Option<&'a RuleConfigItemOptions> {
) -> FindRuleResult<'a> {
match rule {
RuleConfigItem::Options(rule) => {
return Some(rule);
}
RuleConfigItem::Options(rule) => FindRuleResult::Found(rule),
RuleConfigItem::Conditional(map) => {
for (condition, rule) in map.iter() {
if condition == "default" || active_conditions.contains(condition) {
if let Some(rule) = find_rule(rule, active_conditions) {
return Some(rule);
match find_rule(rule, active_conditions) {
FindRuleResult::Found(rule) => {
return FindRuleResult::Found(rule);
}
FindRuleResult::Break => {
return FindRuleResult::Break;
}
FindRuleResult::NotFound => {}
}
}
}
FindRuleResult::NotFound
}
RuleConfigItem::Boolean(_) => FindRuleResult::Break,
}
None
}
match rule {
RuleConfigItemOrShortcut::Loaders(loaders) => {
Expand All @@ -767,7 +778,7 @@ impl NextConfig {
);
}
RuleConfigItemOrShortcut::Advanced(rule) => {
if let Some(RuleConfigItemOptions { loaders, rename_as }) =
if let FindRuleResult::Found(RuleConfigItemOptions { loaders, rename_as }) =
find_rule(rule, &active_conditions)
{
rules.insert(
Expand Down
14 changes: 8 additions & 6 deletions packages/next-swc/crates/next-core/src/next_edge/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::{
ModuleFeatureReportResolvePlugin, NextSharedRuntimeResolvePlugin,
UnsupportedModulesResolvePlugin,
},
util::foreign_code_context_condition,
util::{foreign_code_context_condition, NextRuntime},
};

fn defines(define_env: &IndexMap<String, String>) -> CompileTimeDefines {
Expand Down Expand Up @@ -100,11 +100,13 @@ pub async fn get_edge_resolve_options_context(
let ty = ty.into_value();

// https://github.com/vercel/next.js/blob/bf52c254973d99fed9d71507a2e818af80b8ade7/packages/next/src/build/webpack-config.ts#L96-L102
let mut custom_conditions = vec![
mode.await?.condition().to_string(),
"edge-light".to_string(),
"worker".to_string(),
];
let mut custom_conditions = vec![mode.await?.condition().to_string()];
custom_conditions.extend(
NextRuntime::Edge
.conditions()
.iter()
.map(ToString::to_string),
);

match ty {
ServerContextType::AppRSC { .. } => custom_conditions.push("react-server".to_string()),
Expand Down
22 changes: 3 additions & 19 deletions packages/next-swc/crates/next-core/src/next_import_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use turbopack_binding::{
core::{
reference_type::{CommonJsReferenceSubType, ReferenceType},
resolve::{
options::{ConditionValue, ImportMap, ImportMapping, ResolveOptions, ResolvedMap},
node::node_cjs_resolve_options,
options::{ConditionValue, ImportMap, ImportMapping, ResolvedMap},
parse::Request,
pattern::Pattern,
resolve, AliasPattern, ExternalType, ResolveAliasMap, SubpathValue,
},
source::Source,
},
node::execution_context::ExecutionContext,
turbopack::{resolve_options, resolve_options_context::ResolveOptionsContext},
},
};

Expand Down Expand Up @@ -915,22 +915,6 @@ async fn insert_next_shared_aliases(
Ok(())
}

#[turbo_tasks::function]
async fn package_lookup_resolve_options(
project_path: Vc<FileSystemPath>,
) -> Result<Vc<ResolveOptions>> {
Ok(resolve_options(
project_path,
ResolveOptionsContext {
enable_node_modules: Some(project_path.root().resolve().await?),
enable_node_native_modules: true,
custom_conditions: vec!["development".to_string()],
..Default::default()
}
.cell(),
))
}

#[turbo_tasks::function]
pub async fn get_next_package(context_directory: Vc<FileSystemPath>) -> Result<Vc<FileSystemPath>> {
let result = resolve(
Expand All @@ -939,7 +923,7 @@ pub async fn get_next_package(context_directory: Vc<FileSystemPath>) -> Result<V
Request::parse(Value::new(Pattern::Constant(
"next/package.json".to_string(),
))),
package_lookup_resolve_options(context_directory),
node_cjs_resolve_options(context_directory.root()),
);
let source = result
.first_source()
Expand Down
Loading

0 comments on commit b912492

Please sign in to comment.