From b74eaf3d9c215d8b0d8801730ff6bfcb67337a11 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 28 Feb 2023 17:05:34 +0800 Subject: [PATCH] Expose module_options and resolve_options in turbotrace --- crates/node-file-trace/src/lib.rs | 190 +++++++++++------- crates/node-file-trace/src/main.rs | 2 +- .../module_options/module_options_context.rs | 17 ++ .../turbopack/src/resolve_options_context.rs | 16 ++ 4 files changed, 152 insertions(+), 73 deletions(-) diff --git a/crates/node-file-trace/src/lib.rs b/crates/node-file-trace/src/lib.rs index 59c0336bdac69b..8d46e8dde32b6d 100644 --- a/crates/node-file-trace/src/lib.rs +++ b/crates/node-file-trace/src/lib.rs @@ -26,7 +26,8 @@ use turbo_tasks::{ NothingVc, TaskId, TransientInstance, TransientValue, TurboTasks, TurboTasksBackendApi, Value, }; use turbo_tasks_fs::{ - glob::GlobVc, DirectoryEntry, DiskFileSystemVc, FileSystem, FileSystemVc, ReadGlobResultVc, + glob::GlobVc, DirectoryEntry, DiskFileSystemVc, FileSystem, FileSystemPathVc, FileSystemVc, + ReadGlobResultVc, }; use turbo_tasks_memory::{ stats::{ReferenceType, Stats}, @@ -128,11 +129,6 @@ pub struct CommonArgs { #[cfg_attr(feature = "node-api", serde(default))] exact: bool, - /// Whether to enable mdx parsing while tracing dependencies - #[cfg_attr(feature = "cli", clap(long))] - #[cfg_attr(feature = "node-api", serde(default))] - enable_mdx: bool, - /// Enable experimental garbage collection with the provided memory limit in /// MB. #[cfg_attr(feature = "cli", clap(long))] @@ -241,60 +237,20 @@ async fn add_glob_results( async fn input_to_modules<'a>( fs: FileSystemVc, input: Vec, - process_cwd: Option, exact: bool, - enable_mdx: bool, + process_cwd: Option, + context: String, + module_options: TransientInstance, + resolve_options: TransientInstance, ) -> Result { let root = fs.root(); - let env = EnvironmentVc::new( - Value::new(ExecutionEnvironment::NodeJsLambda( - NodeJsEnvironment { - cwd: OptionStringVc::cell(process_cwd), - ..Default::default() - } - .into(), - )), - Value::new(EnvironmentIntention::Api), - ); - let compile_time_info = CompileTimeInfo { - environment: env, - defines: CompileTimeDefinesVc::empty(), - } - .cell(); - let glob_mappings = vec![ - ( - root, - GlobVc::new("**/*/next/dist/server/next.js"), - ImportMapping::Ignore.into(), - ), - ( - root, - GlobVc::new("**/*/next/dist/bin/next"), - ImportMapping::Ignore.into(), - ), - ]; - let context: AssetContextVc = ModuleAssetContextVc::new( - TransitionsByNameVc::cell(HashMap::new()), - compile_time_info, - ModuleOptionsContext { - enable_types: true, - enable_mdx, - ..Default::default() - } - .cell(), - ResolveOptionsContext { - emulate_environment: Some(env), - resolved_map: Some( - ResolvedMap { - by_glob: glob_mappings, - } - .cell(), - ), - ..Default::default() - } - .cell(), - ) - .into(); + let process_cwd = process_cwd + .clone() + .map(|p| p.trim_start_matches(&context).to_owned()); + + let context: AssetContextVc = + create_module_asset(root, process_cwd, module_options, resolve_options).into(); + let mut list = Vec::new(); for input in input.iter() { if exact { @@ -353,6 +309,8 @@ fn process_input(dir: &Path, context: &str, input: &[String]) -> Result, turbo_tasks: Option<&Arc>>, + module_options: Option, + resolve_options: Option, ) -> Result> { register(); let &CommonArgs { @@ -437,6 +395,8 @@ pub async fn start( println!("graph.html written"); } }, + module_options, + resolve_options, ) .await } @@ -445,6 +405,8 @@ async fn run>( args: Arc, create_tt: impl Fn() -> Arc>, final_finish: impl FnOnce(Arc>, TaskId, Duration) -> F, + module_options: Option, + resolve_options: Option, ) -> Result> { let &CommonArgs { watch, @@ -497,8 +459,15 @@ async fn run>( let dir = dir.clone(); let args = args.clone(); let sender = sender.clone(); + let module_options = module_options.clone(); + let resolve_options = resolve_options.clone(); Box::pin(async move { - let output = main_operation(TransientValue::new(dir.clone()), args.clone().into()); + let output = main_operation( + TransientValue::new(dir.clone()), + args.clone().into(), + TransientInstance::new(module_options.unwrap_or_default()), + TransientInstance::new(resolve_options.unwrap_or_default()), + ); let source = TransientValue::new(output.into()); let issues = IssueVc::peek_issues_with_path(output) @@ -538,6 +507,8 @@ async fn run>( async fn main_operation( current_dir: TransientValue, args: TransientInstance, + module_options: TransientInstance, + resolve_options: TransientInstance, ) -> Result { let dir = current_dir.into_value(); let args = &*args; @@ -545,21 +516,27 @@ async fn main_operation( ref input, watch, exact, - enable_mdx, ref context_directory, ref process_cwd, .. } = args.common(); let context = process_context(&dir, context_directory.as_ref()).unwrap(); - let process_cwd = process_cwd - .clone() - .map(|p| p.trim_start_matches(&context).to_owned()); + let fs = create_fs("context directory", &context, watch).await?; + match *args { Args::Print { common: _ } => { let input = process_input(&dir, &context, input).unwrap(); let mut result = BTreeSet::new(); - let fs = create_fs("context directory", &context, watch).await?; - let modules = input_to_modules(fs, input, process_cwd, exact, enable_mdx).await?; + let modules = input_to_modules( + fs, + input, + exact, + process_cwd.clone(), + context, + module_options, + resolve_options, + ) + .await?; for module in modules.iter() { let set = all_assets(*module); IssueVc::attach_context(module.path(), "gathering list of assets".to_string(), set) @@ -574,12 +551,19 @@ async fn main_operation( } Args::Annotate { common: _ } => { let input = process_input(&dir, &context, input).unwrap(); - let fs = create_fs("context directory", &context, watch).await?; let mut output_nft_assets = Vec::new(); let mut emits = Vec::new(); - for module in input_to_modules(fs, input, process_cwd, exact, enable_mdx) - .await? - .iter() + for module in input_to_modules( + fs, + input, + exact, + process_cwd.clone(), + context, + module_options, + resolve_options, + ) + .await? + .iter() { let nft_asset = NftJsonAssetVc::new(*module); let path = nft_asset.path().await?.path.clone(); @@ -598,14 +582,21 @@ async fn main_operation( } => { let output = process_context(&dir, Some(output_directory)).unwrap(); let input = process_input(&dir, &context, input).unwrap(); - let fs = create_fs("context directory", &context, watch).await?; let out_fs = create_fs("output directory", &output, watch).await?; let input_dir = fs.root(); let output_dir = out_fs.root(); let mut emits = Vec::new(); - for module in input_to_modules(fs, input, process_cwd, exact, enable_mdx) - .await? - .iter() + for module in input_to_modules( + fs, + input, + exact, + process_cwd.clone(), + context, + module_options, + resolve_options, + ) + .await? + .iter() { let rebased = RebasedAssetVc::new(*module, input_dir, output_dir).into(); emits.push(emit_with_completion(rebased, output_dir)); @@ -620,6 +611,61 @@ async fn main_operation( Ok(StringsVc::cell(Vec::new())) } +#[turbo_tasks::function] +async fn create_module_asset( + root: FileSystemPathVc, + process_cwd: Option, + module_options: TransientInstance, + resolve_options: TransientInstance, +) -> Result { + let env = EnvironmentVc::new( + Value::new(ExecutionEnvironment::NodeJsLambda( + NodeJsEnvironment { + cwd: OptionStringVc::cell(process_cwd.clone()), + ..Default::default() + } + .into(), + )), + Value::new(EnvironmentIntention::Api), + ); + let compile_time_info = CompileTimeInfo { + environment: env, + defines: CompileTimeDefinesVc::empty(), + } + .cell(); + let glob_mappings = vec![ + ( + root, + GlobVc::new("**/*/next/dist/server/next.js"), + ImportMapping::Ignore.into(), + ), + ( + root, + GlobVc::new("**/*/next/dist/bin/next"), + ImportMapping::Ignore.into(), + ), + ]; + let mut resolve_options = ResolveOptionsContext::clone(&*resolve_options); + if resolve_options.emulate_environment.is_none() { + resolve_options.emulate_environment = Some(env); + } + if resolve_options.resolved_map.is_none() { + resolve_options.resolved_map = Some( + ResolvedMap { + by_glob: glob_mappings, + } + .cell(), + ); + } + + Ok(ModuleAssetContextVc::new( + TransitionsByNameVc::cell(HashMap::new()), + compile_time_info, + ModuleOptionsContext::clone(&*module_options).cell(), + resolve_options.cell(), + )) +} + fn register() { turbo_tasks::register(); turbo_tasks_fs::register(); diff --git a/crates/node-file-trace/src/main.rs b/crates/node-file-trace/src/main.rs index cf11376cf8e5a1..15987bdb6efa9e 100644 --- a/crates/node-file-trace/src/main.rs +++ b/crates/node-file-trace/src/main.rs @@ -15,7 +15,7 @@ async fn main() -> Result<()> { console_subscriber::init(); let args = Arc::new(Args::parse()); let should_print = matches!(&*args, Args::Print { .. }); - let result = start(args, None).await?; + let result = start(args, None, None, None).await?; if should_print { for file in result.iter() { println!("{}", file); diff --git a/crates/turbopack/src/module_options/module_options_context.rs b/crates/turbopack/src/module_options/module_options_context.rs index ba1c716b00fb18..d45c8cd2651dee 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -41,25 +41,42 @@ impl WebpackLoadersOptions { #[turbo_tasks::value(shared)] #[derive(Default, Clone)] pub struct ModuleOptionsContext { + #[serde(default)] pub enable_jsx: bool, + #[serde(default)] pub enable_emotion: bool, + #[serde(default)] pub enable_react_refresh: bool, + #[serde(default)] pub enable_styled_components: bool, + #[serde(default)] pub enable_styled_jsx: bool, + #[serde(default)] pub enable_postcss_transform: Option, + #[serde(default)] pub enable_webpack_loaders: Option, + #[serde(default)] pub enable_types: bool, + #[serde(default)] pub enable_typescript_transform: bool, + #[serde(default)] pub enable_mdx: bool, + #[serde(default)] pub preset_env_versions: Option, + #[serde(default)] pub custom_ecmascript_app_transforms: Vec, + #[serde(default)] pub custom_ecmascript_transforms: Vec, + #[serde(default)] /// Custom rules to be applied after all default rules. pub custom_rules: Vec, + #[serde(default)] pub execution_context: Option, + #[serde(default)] /// A list of rules to use a different module option context for certain /// context paths. The first matching is used. pub rules: Vec<(ContextCondition, ModuleOptionsContextVc)>, + #[serde(default)] pub placeholder_for_future_extensions: (), } diff --git a/crates/turbopack/src/resolve_options_context.rs b/crates/turbopack/src/resolve_options_context.rs index ffae56b23ede96..cb0bdb935458f8 100644 --- a/crates/turbopack/src/resolve_options_context.rs +++ b/crates/turbopack/src/resolve_options_context.rs @@ -12,40 +12,56 @@ use crate::condition::ContextCondition; #[turbo_tasks::value(shared)] #[derive(Default, Clone)] pub struct ResolveOptionsContext { + #[serde(default)] pub emulate_environment: Option, + #[serde(default)] pub enable_types: bool, + #[serde(default)] pub enable_typescript: bool, + #[serde(default)] pub enable_react: bool, + #[serde(default)] pub enable_node_native_modules: bool, + #[serde(default)] pub enable_node_modules: bool, + #[serde(default)] /// Mark well-known Node.js modules as external imports and load them using /// native `require`. e.g. url, querystring, os pub enable_node_externals: bool, + #[serde(default)] /// Enables the "browser" field and export condition in package.json pub browser: bool, + #[serde(default)] /// Enables the "module" field and export condition in package.json pub module: bool, + #[serde(default)] pub custom_conditions: Vec, + #[serde(default)] /// An additional import map to use when resolving modules. /// /// If set, this import map will be applied to `ResolveOption::import_map`. /// It is always applied last, so any mapping defined within will take /// precedence over any other (e.g. tsconfig.json `compilerOptions.paths`). pub import_map: Option, + #[serde(default)] /// An import map to fall back to when a request could not be resolved. /// /// If set, this import map will be applied to /// `ResolveOption::fallback_import_map`. It is always applied last, so /// any mapping defined within will take precedence over any other. pub fallback_import_map: Option, + #[serde(default)] /// An additional resolved map to use after modules have been resolved. pub resolved_map: Option, + #[serde(default)] /// A list of rules to use a different resolve option context for certain /// context paths. The first matching is used. pub rules: Vec<(ContextCondition, ResolveOptionsContextVc)>, + #[serde(default)] /// A list of plugins which get applied before (in the future) and after /// resolving. pub plugins: Vec, + #[serde(default)] pub placeholder_for_future_extensions: (), }