From 3af1332c179fe40ed23493d3595c2f5eb520e496 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 8 May 2023 14:24:10 +0000 Subject: [PATCH 1/6] fix error propagation in ContextCondition --- crates/turbopack/src/condition.rs | 31 ++++++++++------------ crates/turbopack/src/module_options/mod.rs | 2 +- crates/turbopack/src/resolve.rs | 2 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/crates/turbopack/src/condition.rs b/crates/turbopack/src/condition.rs index ca1da5f6dff72..4b732ece7d25f 100644 --- a/crates/turbopack/src/condition.rs +++ b/crates/turbopack/src/condition.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use async_recursion::async_recursion; use futures::{stream, StreamExt}; use serde::{Deserialize, Serialize}; @@ -32,32 +33,28 @@ impl ContextCondition { #[async_recursion] /// Returns true if the condition matches the context. - pub async fn matches(&self, context: &FileSystemPath) -> bool { + pub async fn matches(&self, context: &FileSystemPath) -> Result { match self { ContextCondition::All(conditions) => { stream::iter(conditions) - .all(|c| async move { c.matches(context).await }) + .fold(Ok(true), |acc, c| async move { + Ok(acc? && c.matches(context).await?) + }) .await } ContextCondition::Any(conditions) => { stream::iter(conditions) - .any(|c| async move { c.matches(context).await }) + .fold(Ok(true), |acc, c| async move { + Ok(acc? || c.matches(context).await?) + }) .await } - ContextCondition::Not(condition) => !condition.matches(context).await, - ContextCondition::InPath(path) => { - if let Ok(path) = path.await { - context.is_inside(&path) - } else { - false - } - } - ContextCondition::InDirectory(dir) => { - context.path.starts_with(&format!("{dir}/")) - || context.path.contains(&format!("/{dir}/")) - || context.path.ends_with(&format!("/{dir}")) - || context.path == *dir - } + ContextCondition::Not(condition) => condition.matches(context).await.map(|b| !b), + ContextCondition::InPath(path) => Ok(context.is_inside(&*path.await?)), + ContextCondition::InDirectory(dir) => Ok(context.path.starts_with(&format!("{dir}/")) + || context.path.contains(&format!("/{dir}/")) + || context.path.ends_with(&format!("/{dir}")) + || context.path == *dir), } } } diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index 3a134873c59e0..d91a4265fd8a4 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -81,7 +81,7 @@ impl ModuleOptionsVc { let path_value = path.await?; for (condition, new_context) in rules.iter() { - if condition.matches(&path_value).await { + if condition.matches(&path_value).await? { return Ok(ModuleOptionsVc::new(path, *new_context)); } } diff --git a/crates/turbopack/src/resolve.rs b/crates/turbopack/src/resolve.rs index b98809b4bb533..ba7d516636706 100644 --- a/crates/turbopack/src/resolve.rs +++ b/crates/turbopack/src/resolve.rs @@ -238,7 +238,7 @@ pub async fn resolve_options( if !options_context_value.rules.is_empty() { let context_value = &*context.await?; for (condition, new_options_context) in options_context_value.rules.iter() { - if condition.matches(context_value).await { + if condition.matches(context_value).await? { return Ok(resolve_options(context, *new_options_context)); } } From 0558aad0f80e5c3fba18044ecf729e2cc29f3e66 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 9 May 2023 15:04:20 +0000 Subject: [PATCH 2/6] improve JSON deserialization error message --- crates/turbopack-node/js/src/ipc/evaluate.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/turbopack-node/js/src/ipc/evaluate.ts b/crates/turbopack-node/js/src/ipc/evaluate.ts index d3f219a988743..c03704c3c277c 100644 --- a/crates/turbopack-node/js/src/ipc/evaluate.ts +++ b/crates/turbopack-node/js/src/ipc/evaluate.ts @@ -49,7 +49,8 @@ export const run = async ( const value = await getValue(ipc, ...msg.args); await ipc.send({ type: "end", - data: value === undefined ? undefined : JSON.stringify(value), + data: + value === undefined ? undefined : JSON.stringify(value, null, 2), }); } catch (e) { await ipc.sendError(e as Error); From 5081085374e14db1551a0d903d080126652e278c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 9 May 2023 15:23:41 +0000 Subject: [PATCH 3/6] fix glob matching --- crates/turbo-tasks-fs/src/glob.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/turbo-tasks-fs/src/glob.rs b/crates/turbo-tasks-fs/src/glob.rs index 0400029250e9b..461f6d2a81c09 100644 --- a/crates/turbo-tasks-fs/src/glob.rs +++ b/crates/turbo-tasks-fs/src/glob.rs @@ -50,8 +50,7 @@ impl Glob { pub fn execute(&self, path: &str) -> bool { let match_partial = path.ends_with('/'); self.iter_matches(path, true, match_partial) - .next() - .is_some() + .any(|result| matches!(result, ("", _))) } fn iter_matches<'a>( @@ -416,4 +415,14 @@ mod tests { assert!(glob.execute(path)); } + + #[rstest] + #[case::early_end("*.raw", "hello.raw.js")] + fn glob_not_matching(#[case] glob: &str, #[case] path: &str) { + let glob = Glob::parse(glob).unwrap(); + + println!("{glob:?} {path}"); + + assert!(!glob.execute(path)); + } } From 0fc96fed924c55a828e7928f10284f431441e863 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 9 May 2023 15:37:20 +0000 Subject: [PATCH 4/6] refactor webpack loader exection allow to rename assets and apply pipeline on renamed asset --- crates/turbopack-core/src/ident.rs | 17 ++ .../turbopack-node/src/transforms/webpack.rs | 48 ++-- crates/turbopack/src/lib.rs | 206 ++++++++++-------- crates/turbopack/src/module_options/mod.rs | 17 +- .../module_options/module_options_context.rs | 40 ++-- .../src/module_options/module_rule.rs | 1 - .../src/module_options/rule_condition.rs | 28 ++- 7 files changed, 215 insertions(+), 142 deletions(-) diff --git a/crates/turbopack-core/src/ident.rs b/crates/turbopack-core/src/ident.rs index 31b20d464eaef..19a054ba3ab58 100644 --- a/crates/turbopack-core/src/ident.rs +++ b/crates/turbopack-core/src/ident.rs @@ -31,6 +31,16 @@ impl AssetIdent { pub fn add_asset(&mut self, key: StringVc, asset: AssetIdentVc) { self.assets.push((key, asset)); } + + pub async fn rename_as(&mut self, pattern: &str) -> Result<()> { + let root = self.path.root(); + let path = self.path.await?; + self.path = root + .join(&pattern.replace("*", &path.path)) + .resolve() + .await?; + Ok(()) + } } #[turbo_tasks::value_impl] @@ -95,6 +105,13 @@ impl AssetIdentVc { Ok(Self::new(Value::new(this))) } + #[turbo_tasks::function] + pub async fn rename_as(self, pattern: &str) -> Result { + let mut this = self.await?.clone_value(); + this.rename_as(pattern).await?; + Ok(Self::new(Value::new(this))) + } + #[turbo_tasks::function] pub async fn path(self) -> Result { Ok(self.await?.path) diff --git a/crates/turbopack-node/src/transforms/webpack.rs b/crates/turbopack-node/src/transforms/webpack.rs index 9785bbcebc602..e57a03d1866f2 100644 --- a/crates/turbopack-node/src/transforms/webpack.rs +++ b/crates/turbopack-node/src/transforms/webpack.rs @@ -35,25 +35,22 @@ struct WebpackLoadersProcessingResult { } #[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] -#[serde(untagged)] -pub enum WebpackLoaderConfigItem { - LoaderName(String), - LoaderNameWithOptions { - loader: String, - #[turbo_tasks(trace_ignore)] - options: serde_json::Map, - }, +pub struct WebpackLoaderItem { + pub loader: String, + #[turbo_tasks(trace_ignore)] + pub options: serde_json::Map, } #[derive(Debug, Clone)] #[turbo_tasks::value(shared, transparent)] -pub struct WebpackLoaderConfigItems(pub Vec); +pub struct WebpackLoaderItems(pub Vec); #[turbo_tasks::value] pub struct WebpackLoaders { evaluate_context: AssetContextVc, execution_context: ExecutionContextVc, - loaders: WebpackLoaderConfigItemsVc, + loaders: WebpackLoaderItemsVc, + rename_as: Option, } #[turbo_tasks::value_impl] @@ -62,12 +59,14 @@ impl WebpackLoadersVc { pub fn new( evaluate_context: AssetContextVc, execution_context: ExecutionContextVc, - loaders: WebpackLoaderConfigItemsVc, + loaders: WebpackLoaderItemsVc, + rename_as: Option, ) -> Self { WebpackLoaders { evaluate_context, execution_context, loaders, + rename_as, } .cell() } @@ -76,11 +75,9 @@ impl WebpackLoadersVc { #[turbo_tasks::value_impl] impl SourceTransform for WebpackLoaders { #[turbo_tasks::function] - fn transform(&self, source: AssetVc) -> AssetVc { + fn transform(self_vc: WebpackLoadersVc, source: AssetVc) -> AssetVc { WebpackLoadersProcessedAsset { - evaluate_context: self.evaluate_context, - execution_context: self.execution_context, - loaders: self.loaders, + transform: self_vc, source, } .cell() @@ -90,17 +87,21 @@ impl SourceTransform for WebpackLoaders { #[turbo_tasks::value] struct WebpackLoadersProcessedAsset { - evaluate_context: AssetContextVc, - execution_context: ExecutionContextVc, - loaders: WebpackLoaderConfigItemsVc, + transform: WebpackLoadersVc, source: AssetVc, } #[turbo_tasks::value_impl] impl Asset for WebpackLoadersProcessedAsset { #[turbo_tasks::function] - fn ident(&self) -> AssetIdentVc { - self.source.ident() + async fn ident(&self) -> Result { + Ok( + if let Some(rename_as) = self.transform.await?.rename_as.as_deref() { + self.source.ident().rename_as(rename_as) + } else { + self.source.ident() + }, + ) } #[turbo_tasks::function] @@ -135,12 +136,13 @@ impl WebpackLoadersProcessedAssetVc { #[turbo_tasks::function] async fn process(self) -> Result { let this = self.await?; + let transform = this.transform.await?; let ExecutionContext { project_path, chunking_context, env, - } = *this.execution_context.await?; + } = *transform.execution_context.await?; let source_content = this.source.content(); let AssetContent::File(file) = *source_content.await? else { bail!("Webpack Loaders transform only support transforming files"); @@ -152,12 +154,12 @@ impl WebpackLoadersProcessedAssetVc { }.cell()); }; let content = content.content().to_str()?; - let context = this.evaluate_context; + let context = transform.evaluate_context; let webpack_loaders_executor = webpack_loaders_executor(context); let resource_fs_path = this.source.ident().path().await?; let resource_path = resource_fs_path.path.as_str(); - let loaders = this.loaders.await?; + let loaders = transform.loaders.await?; let config_value = evaluate( webpack_loaders_executor, project_path, diff --git a/crates/turbopack/src/lib.rs b/crates/turbopack/src/lib.rs index 12494649d9eb8..191cb73df544c 100644 --- a/crates/turbopack/src/lib.rs +++ b/crates/turbopack/src/lib.rs @@ -259,113 +259,129 @@ impl ModuleAssetContextVc { } #[turbo_tasks::function] - async fn process_default( + fn process_default( self_vc: ModuleAssetContextVc, source: AssetVc, reference_type: Value, - ) -> Result { - let ident = source.ident().resolve().await?; - let options = ModuleOptionsVc::new(ident.path().parent(), self_vc.module_options_context()); - - let reference_type = reference_type.into_value(); - let part = match &reference_type { - ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::ImportPart( - part, - )) => Some(*part), - _ => None, - }; - let mut current_source = source; - let mut current_module_type = None; - for rule in options.await?.rules.iter() { - if rule - .matches(source, &*ident.path().await?, &reference_type) - .await? - { - for effect in rule.effects() { - match effect { - ModuleRuleEffect::SourceTransforms(transforms) => { - current_source = transforms.transform(current_source); - if current_source.ident().resolve().await? != ident { - // The ident has been changed, so we need to apply new rules. - return Ok(self_vc - .process_default(current_source, Value::new(reference_type))); - } - } - ModuleRuleEffect::ModuleType(module) => { - current_module_type = Some(*module); + ) -> AssetVc { + process_default(self_vc, source, reference_type, Vec::new()) + } +} + +#[turbo_tasks::function] +async fn process_default( + context: ModuleAssetContextVc, + source: AssetVc, + reference_type: Value, + processed_rules: Vec, +) -> Result { + let ident = source.ident().resolve().await?; + let options = ModuleOptionsVc::new(ident.path().parent(), context.module_options_context()); + + let reference_type = reference_type.into_value(); + let part = match &reference_type { + ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::ImportPart(part)) => { + Some(*part) + } + _ => None, + }; + let mut current_source = source; + let mut current_module_type = None; + for (i, rule) in options.await?.rules.iter().enumerate() { + if processed_rules.contains(&i) { + continue; + } + if rule + .matches(source, &*ident.path().await?, &reference_type) + .await? + { + for effect in rule.effects() { + match effect { + ModuleRuleEffect::SourceTransforms(transforms) => { + current_source = transforms.transform(current_source); + if current_source.ident().resolve().await? != ident { + // The ident has been changed, so we need to apply new rules. + let mut processed_rules = processed_rules.clone(); + processed_rules.push(i); + return Ok(process_default( + context, + current_source, + Value::new(reference_type), + processed_rules, + )); } - ModuleRuleEffect::AddEcmascriptTransforms(additional_transforms) => { - current_module_type = match current_module_type { - Some(ModuleType::Ecmascript { - transforms, - options, - }) => Some(ModuleType::Ecmascript { - transforms: transforms.extend(*additional_transforms), - options, - }), - Some(ModuleType::Typescript { - transforms, - options, - }) => Some(ModuleType::Typescript { - transforms: transforms.extend(*additional_transforms), - options, - }), - Some(ModuleType::TypescriptWithTypes { - transforms, - options, - }) => Some(ModuleType::TypescriptWithTypes { - transforms: transforms.extend(*additional_transforms), - options, - }), - Some(module_type) => { - ModuleIssue { - ident, - title: StringVc::cell("Invalid module type".to_string()), - description: StringVc::cell( - "The module type must be Ecmascript or Typescript to \ - add Ecmascript transforms" - .to_string(), - ), - } - .cell() - .as_issue() - .emit(); - Some(module_type) + } + ModuleRuleEffect::ModuleType(module) => { + current_module_type = Some(*module); + } + ModuleRuleEffect::AddEcmascriptTransforms(additional_transforms) => { + current_module_type = match current_module_type { + Some(ModuleType::Ecmascript { + transforms, + options, + }) => Some(ModuleType::Ecmascript { + transforms: transforms.extend(*additional_transforms), + options, + }), + Some(ModuleType::Typescript { + transforms, + options, + }) => Some(ModuleType::Typescript { + transforms: transforms.extend(*additional_transforms), + options, + }), + Some(ModuleType::TypescriptWithTypes { + transforms, + options, + }) => Some(ModuleType::TypescriptWithTypes { + transforms: transforms.extend(*additional_transforms), + options, + }), + Some(module_type) => { + ModuleIssue { + ident, + title: StringVc::cell("Invalid module type".to_string()), + description: StringVc::cell( + "The module type must be Ecmascript or Typescript to add \ + Ecmascript transforms" + .to_string(), + ), } - None => { - ModuleIssue { - ident, - title: StringVc::cell("Missing module type".to_string()), - description: StringVc::cell( - "The module type effect must be applied before adding \ - Ecmascript transforms" - .to_string(), - ), - } - .cell() - .as_issue() - .emit(); - None + .cell() + .as_issue() + .emit(); + Some(module_type) + } + None => { + ModuleIssue { + ident, + title: StringVc::cell("Missing module type".to_string()), + description: StringVc::cell( + "The module type effect must be applied before adding \ + Ecmascript transforms" + .to_string(), + ), } - }; - } - ModuleRuleEffect::Custom => { - todo!("Custom module rule effects are not yet supported"); - } + .cell() + .as_issue() + .emit(); + None + } + }; } } } } + } - let module_type = current_module_type.unwrap_or(ModuleType::Raw).cell(); + let module_type = current_module_type.unwrap_or(ModuleType::Raw).cell(); - Ok(apply_module_type( - current_source, - self_vc, - module_type, - part, - )) - } + Ok(apply_module_type( + current_source, + context, + module_type, + part, + )) } #[turbo_tasks::value_impl] diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index d91a4265fd8a4..0b2be4ff23d90 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -7,7 +7,7 @@ pub use module_options_context::*; pub use module_rule::*; pub use rule_condition::*; use turbo_tasks::primitives::{OptionStringVc, StringsVc}; -use turbo_tasks_fs::FileSystemPathVc; +use turbo_tasks_fs::{glob::GlobVc, FileSystemPathVc}; use turbopack_core::{ reference_type::{ReferenceType, UrlReferenceSubType}, resolve::options::{ImportMap, ImportMapVc, ImportMapping, ImportMappingVc}, @@ -429,6 +429,7 @@ impl ModuleOptionsVc { } if let Some(webpack_loaders_options) = enable_webpack_loaders { + let webpack_loaders_options = webpack_loaders_options.await?; let execution_context = execution_context .context("execution_context is required for webpack_loaders")? .with_layer("webpack_loaders"); @@ -439,10 +440,17 @@ impl ModuleOptionsVc { } else { package_import_map_from_context("loader-runner", path) }; - for (ext, loaders) in webpack_loaders_options.extension_to_loaders.iter() { + for (glob, rule) in webpack_loaders_options.rules.await?.iter() { rules.push(ModuleRule::new( ModuleRuleCondition::All(vec![ - ModuleRuleCondition::ResourcePathEndsWith(ext.to_string()), + if !glob.contains("/") { + ModuleRuleCondition::ResourceBasePathGlob(GlobVc::new(glob).await?) + } else { + ModuleRuleCondition::ResourcePathGlob { + base: execution_context.project_path().await?, + glob: GlobVc::new(glob).await?, + } + }, ModuleRuleCondition::not(ModuleRuleCondition::ResourceIsVirtualAsset), ]), vec![ @@ -463,7 +471,8 @@ impl ModuleOptionsVc { None, ), execution_context, - *loaders, + rule.loaders, + rule.rename_as.clone(), ) .into(), ])), diff --git a/crates/turbopack/src/module_options/module_options_context.rs b/crates/turbopack/src/module_options/module_options_context.rs index 91e66f74dfbaf..135efbdf1e325 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -7,7 +7,7 @@ use turbopack_ecmascript_plugins::transform::{ emotion::EmotionTransformConfigVc, styled_components::StyledComponentsTransformConfigVc, }; use turbopack_node::{ - execution_context::ExecutionContextVc, transforms::webpack::WebpackLoaderConfigItemsVc, + execution_context::ExecutionContextVc, transforms::webpack::WebpackLoaderItemsVc, }; use super::ModuleRule; @@ -19,14 +19,31 @@ pub struct PostCssTransformOptions { pub placeholder_for_future_extensions: (), } +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +pub struct LoaderRuleItem { + pub loaders: WebpackLoaderItemsVc, + pub rename_as: Option, +} + +#[derive(Default)] +#[turbo_tasks::value(transparent)] +pub struct WebpackRules(IndexMap); + +#[derive(Default)] +#[turbo_tasks::value(transparent)] +pub struct OptionWebpackRules(Option); + #[turbo_tasks::value(shared)] -#[derive(Default, Clone, Debug)] +#[derive(Clone, Debug)] pub struct WebpackLoadersOptions { - pub extension_to_loaders: IndexMap, + pub rules: WebpackRulesVc, pub loader_runner_package: Option, - pub placeholder_for_future_extensions: (), } +#[derive(Default)] +#[turbo_tasks::value(transparent)] +pub struct OptionWebpackLoadersOptions(Option); + /// The kind of decorators transform to use. /// [TODO]: might need bikeshed for the name (Ecma) #[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] @@ -92,20 +109,7 @@ impl Default for TypescriptTransformOptionsVc { } } -impl WebpackLoadersOptions { - pub fn is_empty(&self) -> bool { - self.extension_to_loaders.is_empty() - } - - pub fn clone_if(&self) -> Option { - if self.is_empty() { - None - } else { - Some(self.clone()) - } - } -} - +// [TODO]: should enabled_react_refresh belong to this options? #[turbo_tasks::value(shared)] #[derive(Default, Clone, Debug)] pub struct JsxTransformOptions { diff --git a/crates/turbopack/src/module_options/module_rule.rs b/crates/turbopack/src/module_options/module_rule.rs index b97dd29277c39..fc7223dd0ed5c 100644 --- a/crates/turbopack/src/module_options/module_rule.rs +++ b/crates/turbopack/src/module_options/module_rule.rs @@ -43,7 +43,6 @@ pub enum ModuleRuleEffect { ModuleType(ModuleType), AddEcmascriptTransforms(EcmascriptInputTransformsVc), SourceTransforms(SourceTransformsVc), - Custom, } #[turbo_tasks::value(serialization = "auto_for_input", shared)] diff --git a/crates/turbopack/src/module_options/rule_condition.rs b/crates/turbopack/src/module_options/rule_condition.rs index 6e7f54c6437f1..05a6df90bfaad 100644 --- a/crates/turbopack/src/module_options/rule_condition.rs +++ b/crates/turbopack/src/module_options/rule_condition.rs @@ -2,7 +2,7 @@ use anyhow::Result; use async_recursion::async_recursion; use serde::{Deserialize, Serialize}; use turbo_tasks::{primitives::Regex, trace::TraceRawVcs}; -use turbo_tasks_fs::{FileSystemPath, FileSystemPathReadRef}; +use turbo_tasks_fs::{glob::GlobReadRef, FileSystemPath, FileSystemPathReadRef}; use turbopack_core::{ asset::AssetVc, reference_type::ReferenceType, virtual_asset::VirtualAssetVc, }; @@ -20,6 +20,18 @@ pub enum ModuleRuleCondition { ResourcePathInDirectory(String), ResourcePathInExactDirectory(FileSystemPathReadRef), ResourcePathRegex(#[turbo_tasks(trace_ignore)] Regex), + /// For paths that are within the same filesystem as the `base`, it need to + /// match the relative path from base to resource. This includes `./` or + /// `../` prefix. For paths in a different filesystem, it need to match + /// the resource path in that filesystem without any prefix. This means + /// any glob starting with `./` or `../` will only match paths in the + /// project. Globs starting with `**` can match any path. + ResourcePathGlob { + base: FileSystemPathReadRef, + #[turbo_tasks(trace_ignore)] + glob: GlobReadRef, + }, + ResourceBasePathGlob(#[turbo_tasks(trace_ignore)] GlobReadRef), } impl ModuleRuleCondition { @@ -90,6 +102,20 @@ impl ModuleRuleCondition { ModuleRuleCondition::ResourceIsVirtualAsset => { VirtualAssetVc::resolve_from(source).await?.is_some() } + ModuleRuleCondition::ResourcePathGlob { glob, base } => { + if let Some(path) = base.get_relative_path_to(path) { + glob.execute(&path) + } else { + glob.execute(&path.path) + } + } + ModuleRuleCondition::ResourceBasePathGlob(glob) => { + let basename = path + .path + .rsplit_once('/') + .map_or(path.path.as_str(), |(_, b)| b); + glob.execute(basename) + } _ => todo!("not implemented yet"), }) } From 171e491d26891f48abd8d4c55aaa02a5d8ca2ff5 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 23 May 2023 07:33:58 +0000 Subject: [PATCH 5/6] un-special case sass --- crates/turbopack/src/module_options/mod.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index 0b2be4ff23d90..b0644c9cb615e 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -454,15 +454,12 @@ impl ModuleOptionsVc { ModuleRuleCondition::not(ModuleRuleCondition::ResourceIsVirtualAsset), ]), vec![ - // [TODO]: should accept rules as an option - if ext == ".scss" || ext == ".sass" { - ModuleRuleEffect::ModuleType(ModuleType::Css(css_transforms)) - } else { - ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { - transforms: app_transforms, - options: ecmascript_options.clone(), - }) - }, + // By default, loaders are expected to return ecmascript code. + // This can be overriden by specifying e. g. `as: "*.css"` in the rule. + ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { + transforms: app_transforms, + options: ecmascript_options.clone(), + }), ModuleRuleEffect::SourceTransforms(SourceTransformsVc::cell(vec![ WebpackLoadersVc::new( node_evaluate_asset_context( From 23eebaec3f1f66ce60be78f29aafc5a73806abdf Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 23 May 2023 07:44:18 +0000 Subject: [PATCH 6/6] rebase fixes --- crates/turbopack-cli/src/dev/web_entry_source.rs | 7 ++----- crates/turbopack/src/module_options/mod.rs | 2 +- .../turbopack/src/module_options/module_options_context.rs | 5 +---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/crates/turbopack-cli/src/dev/web_entry_source.rs b/crates/turbopack-cli/src/dev/web_entry_source.rs index e7f6585758192..14345a8378dce 100644 --- a/crates/turbopack-cli/src/dev/web_entry_source.rs +++ b/crates/turbopack-cli/src/dev/web_entry_source.rs @@ -36,11 +36,8 @@ use turbopack_dev_server::{ source::{asset_graph::AssetGraphContentSourceVc, ContentSourceVc}, }; use turbopack_ecmascript_plugins::transform::{ - emotion::{EmotionTransformConfig, EmotionTransformConfigVc, EmotionTransformer}, - styled_components::{ - StyledComponentsTransformConfig, StyledComponentsTransformConfigVc, - StyledComponentsTransformer, - }, + emotion::{EmotionTransformConfig, EmotionTransformer}, + styled_components::{StyledComponentsTransformConfig, StyledComponentsTransformer}, styled_jsx::StyledJsxTransformer, }; use turbopack_node::execution_context::ExecutionContextVc; diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index b0644c9cb615e..cb1e158d48c7a 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -6,7 +6,7 @@ use anyhow::{Context, Result}; pub use module_options_context::*; pub use module_rule::*; pub use rule_condition::*; -use turbo_tasks::primitives::{OptionStringVc, StringsVc}; +use turbo_tasks::primitives::OptionStringVc; use turbo_tasks_fs::{glob::GlobVc, FileSystemPathVc}; use turbopack_core::{ reference_type::{ReferenceType, UrlReferenceSubType}, diff --git a/crates/turbopack/src/module_options/module_options_context.rs b/crates/turbopack/src/module_options/module_options_context.rs index 135efbdf1e325..646a28460e68b 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -3,9 +3,6 @@ use serde::{Deserialize, Serialize}; use turbo_tasks::trace::TraceRawVcs; use turbopack_core::{environment::EnvironmentVc, resolve::options::ImportMappingVc}; use turbopack_ecmascript::TransformPluginVc; -use turbopack_ecmascript_plugins::transform::{ - emotion::EmotionTransformConfigVc, styled_components::StyledComponentsTransformConfigVc, -}; use turbopack_node::{ execution_context::ExecutionContextVc, transforms::webpack::WebpackLoaderItemsVc, }; @@ -155,7 +152,7 @@ impl MdxTransformModuleOptionsVc { pub struct ModuleOptionsContext { pub enable_jsx: Option, pub enable_postcss_transform: Option, - pub enable_webpack_loaders: Option, + pub enable_webpack_loaders: Option, pub enable_types: bool, pub enable_typescript_transform: Option, pub decorators: Option,