From c8c996d40c331a0e737ea80b2b2c6504ee3a9726 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 6 Mar 2024 16:00:23 +0000 Subject: [PATCH] very dynamic requests will only lead to a warning they no longer lead to an additional module not found error --- crates/turbopack-ecmascript/src/lib.rs | 4 + .../src/references/dynamic_expression.rs | 71 ++++++++++++ .../src/references/mod.rs | 101 ++++++++++++++---- crates/turbopack-tests/tests/snapshot.rs | 1 + .../very-dynamic/input/index.js | 17 +++ ... import(FreeVar(Math)[__quo__ra-fcce98.txt | 13 +++ ... require(FreeVar(Math)[__quo__r-fa7bb4.txt | 13 +++ ... fs.readFileSync(FreeVar(Math)[-45dc7a.txt | 12 +++ ... fs.readFileSync(FreeVar(Math)[-d5af53.txt | 13 +++ ... child_process.spawnSync(FreeVa-fa7b47.txt | 13 +++ ...05__ child_process.spawnSync(__-a30479.txt | 17 +++ ... child_process.spawnSync(__quo_-a93044.txt | 13 +++ ... new URL(Variable(unknown##2), -f5ba3f.txt | 10 ++ .../dynamic-request/very-dynamic/options.json | 3 + ...request_very-dynamic_input_index_0d92c3.js | 41 +++++++ ...est_very-dynamic_input_index_0d92c3.js.map | 6 ++ ...request_very-dynamic_input_index_4598f4.js | 11 ++ ...request_very-dynamic_input_index_c551c8.js | 6 ++ ...est_very-dynamic_input_index_c551c8.js.map | 4 + crates/turbopack/src/module_options/mod.rs | 2 + .../module_options/module_options_context.rs | 4 + 21 files changed, 352 insertions(+), 23 deletions(-) create mode 100644 crates/turbopack-ecmascript/src/references/dynamic_expression.rs create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_4598f4.js create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js create mode 100644 crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map diff --git a/crates/turbopack-ecmascript/src/lib.rs b/crates/turbopack-ecmascript/src/lib.rs index 3c74cd46db49a..b7c821cd5196c 100644 --- a/crates/turbopack-ecmascript/src/lib.rs +++ b/crates/turbopack-ecmascript/src/lib.rs @@ -131,6 +131,10 @@ pub struct EcmascriptOptions { /// External imports should used `__turbopack_import__` instead of /// `__turbopack_require__` and become async module references. pub import_externals: bool, + /// Ignore very dynamic requests which doesn't have any static known part. + /// If false, they will reference the whole directory. If true, they won't + /// reference anything and lead to an runtime error instead. + pub ignore_dynamic_requests: bool, } #[turbo_tasks::value(serialization = "auto_for_input")] diff --git a/crates/turbopack-ecmascript/src/references/dynamic_expression.rs b/crates/turbopack-ecmascript/src/references/dynamic_expression.rs new file mode 100644 index 0000000000000..8f5e06e4840c8 --- /dev/null +++ b/crates/turbopack-ecmascript/src/references/dynamic_expression.rs @@ -0,0 +1,71 @@ +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use swc_core::quote; +use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; + +use super::AstPath; +use crate::{ + chunk::EcmascriptChunkingContext, + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, +}; + +#[derive(PartialEq, Eq, TraceRawVcs, Serialize, Deserialize, ValueDebugFormat)] +enum DynamicExpressionType { + Promise, + Normal, +} + +#[turbo_tasks::value] +pub struct DynamicExpression { + path: Vc, + ty: DynamicExpressionType, +} + +#[turbo_tasks::value_impl] +impl DynamicExpression { + #[turbo_tasks::function] + pub fn new(path: Vc) -> Vc { + Self::cell(DynamicExpression { + path, + ty: DynamicExpressionType::Normal, + }) + } + + #[turbo_tasks::function] + pub fn new_promise(path: Vc) -> Vc { + Self::cell(DynamicExpression { + path, + ty: DynamicExpressionType::Promise, + }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for DynamicExpression { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let path = &self.path.await?; + + let visitor = match self.ty { + DynamicExpressionType::Normal => { + create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + *expr = quote!("(() => { const e = new Error(\"Cannot find module as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })()" as Expr); + }) + } + DynamicExpressionType::Promise => { + create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + *expr = quote!("Promise.resolve().then(() => { const e = new Error(\"Cannot find module as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })" as Expr); + }) + } + }; + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .cell()) + } +} diff --git a/crates/turbopack-ecmascript/src/references/mod.rs b/crates/turbopack-ecmascript/src/references/mod.rs index 605a28b2598f0..b89e18c7dea4f 100644 --- a/crates/turbopack-ecmascript/src/references/mod.rs +++ b/crates/turbopack-ecmascript/src/references/mod.rs @@ -3,6 +3,7 @@ pub mod async_module; pub mod cjs; pub mod constant_condition; pub mod constant_value; +pub mod dynamic_expression; pub mod esm; pub mod node; pub mod pattern_mapping; @@ -123,6 +124,7 @@ use crate::{ references::{ async_module::{AsyncModule, OptionAsyncModule}, cjs::{CjsRequireAssetReference, CjsRequireCacheAccess, CjsRequireResolveAssetReference}, + dynamic_expression::DynamicExpression, esm::{module_id::EsmModuleIdAssetReference, EsmBinding, UrlRewriteBehavior}, node::PackageJsonReference, require_context::{RequireContextAssetReference, RequireContextMap}, @@ -337,6 +339,7 @@ struct AnalysisState<'a> { first_import_meta: bool, tree_shaking_mode: Option, import_externals: bool, + ignore_dynamic_requests: bool, } impl<'a> AnalysisState<'a> { @@ -774,6 +777,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( first_import_meta: true, tree_shaking_mode: options.tree_shaking_mode, import_externals: options.import_externals, + ignore_dynamic_requests: options.ignore_dynamic_requests, }; enum Action { @@ -1063,7 +1067,10 @@ pub(crate) async fn analyse_ecmascript_module_internal( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::NEW_URL_IMPORT_META.to_string(), ), - ) + ); + if options.ignore_dynamic_requests { + continue; + } } analysis.add_reference(UrlAssetReference::new( origin, @@ -1131,6 +1138,7 @@ async fn handle_call) + Send + Sync>( origin, source, compile_time_info, + ignore_dynamic_requests, .. } = state; fn explain_args(args: &[JsValue]) -> (String, String) { @@ -1186,7 +1194,13 @@ async fn handle_call) + Send + Sync>( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::DYNAMIC_IMPORT.to_string(), ), - ) + ); + if ignore_dynamic_requests { + analysis.add_code_gen(DynamicExpression::new_promise(Vc::cell( + ast_path.to_vec(), + ))); + return Ok(()); + } } analysis.add_reference(EsmAsyncAssetReference::new( origin, @@ -1219,7 +1233,11 @@ async fn handle_call) + Send + Sync>( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::REQUIRE.to_string(), ), - ) + ); + if ignore_dynamic_requests { + analysis.add_code_gen(DynamicExpression::new(Vc::cell(ast_path.to_vec()))); + return Ok(()); + } } analysis.add_reference(CjsRequireAssetReference::new( origin, @@ -1262,7 +1280,11 @@ async fn handle_call) + Send + Sync>( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::REQUIRE_RESOLVE.to_string(), ), - ) + ); + if ignore_dynamic_requests { + analysis.add_code_gen(DynamicExpression::new(Vc::cell(ast_path.to_vec()))); + return Ok(()); + } } analysis.add_reference(CjsRequireResolveAssetReference::new( origin, @@ -1327,7 +1349,10 @@ async fn handle_call) + Send + Sync>( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::FS_METHOD.to_string(), ), - ) + ); + if ignore_dynamic_requests { + return Ok(()); + } } analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); return Ok(()); @@ -1367,7 +1392,10 @@ async fn handle_call) + Send + Sync>( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::PATH_METHOD.to_string(), ), - ) + ); + if ignore_dynamic_requests { + return Ok(()); + } } analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); return Ok(()); @@ -1398,7 +1426,10 @@ async fn handle_call) + Send + Sync>( DiagnosticId::Lint( errors::failed_to_analyse::ecmascript::PATH_METHOD.to_string(), ), - ) + ); + if ignore_dynamic_requests { + return Ok(()); + } } analysis.add_reference(DirAssetReference::new(source, Pattern::new(pat))); return Ok(()); @@ -1419,17 +1450,27 @@ async fn handle_call) + Send + Sync>( JsValue::member(Box::new(args[1].clone()), Box::new(0_f64.into())); let first_arg = state.link_value(first_arg, in_try).await?; let pat = js_value_to_pattern(&first_arg); - if !pat.has_constant_parts() { + let dynamic = !pat.has_constant_parts(); + if dynamic { show_dynamic_warning = true; } - analysis.add_reference(CjsAssetReference::new( - origin, - Request::parse(Value::new(pat)), - issue_source(source, span), - in_try, - )); + if !dynamic || !ignore_dynamic_requests { + analysis.add_reference(CjsAssetReference::new( + origin, + Request::parse(Value::new(pat)), + issue_source(source, span), + in_try, + )); + } + } + let dynamic = !pat.has_constant_parts(); + if dynamic { + show_dynamic_warning = true; + } + if !dynamic || !ignore_dynamic_requests { + analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); } - if show_dynamic_warning || !pat.has_constant_parts() { + if show_dynamic_warning { let (args, hints) = explain_args(&args); handler.span_warn_with_code( span, @@ -1439,7 +1480,6 @@ async fn handle_call) + Send + Sync>( ), ); } - analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); return Ok(()); } let (args, hints) = explain_args(&args); @@ -1465,6 +1505,9 @@ async fn handle_call) + Send + Sync>( errors::failed_to_analyse::ecmascript::CHILD_PROCESS_SPAWN.to_string(), ), ); + if ignore_dynamic_requests { + return Ok(()); + } } analysis.add_reference(CjsAssetReference::new( origin, @@ -1499,6 +1542,7 @@ async fn handle_call) + Send + Sync>( errors::failed_to_analyse::ecmascript::NODE_PRE_GYP_FIND.to_string(), ), ); + // Always ignore this dynamic request return Ok(()); } analysis.add_reference(NodePreGypConfigReference::new( @@ -1588,6 +1632,7 @@ async fn handle_call) + Send + Sync>( errors::failed_to_analyse::ecmascript::NODE_EXPRESS.to_string(), ), ); + // Always ignore this dynamic request return Ok(()); } match s { @@ -2187,19 +2232,29 @@ async fn value_visitor_inner( if *compile_time_info.environment().node_externals().await? { // TODO check externals match &**name { - "path" => JsValue::WellKnownObject(WellKnownObjectKind::PathModule), - "fs/promises" => JsValue::WellKnownObject(WellKnownObjectKind::FsModule), - "fs" => JsValue::WellKnownObject(WellKnownObjectKind::FsModule), - "child_process" => JsValue::WellKnownObject(WellKnownObjectKind::ChildProcess), - "os" => JsValue::WellKnownObject(WellKnownObjectKind::OsModule), - "process" => JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess), + "node:path" | "path" => { + JsValue::WellKnownObject(WellKnownObjectKind::PathModule) + } + "node:fs/promises" | "fs/promises" => { + JsValue::WellKnownObject(WellKnownObjectKind::FsModule) + } + "node:fs" | "fs" => JsValue::WellKnownObject(WellKnownObjectKind::FsModule), + "node:child_process" | "child_process" => { + JsValue::WellKnownObject(WellKnownObjectKind::ChildProcess) + } + "node:os" | "os" => JsValue::WellKnownObject(WellKnownObjectKind::OsModule), + "node:process" | "process" => { + JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess) + } "@mapbox/node-pre-gyp" => { JsValue::WellKnownObject(WellKnownObjectKind::NodePreGyp) } "node-gyp-build" => { JsValue::WellKnownFunction(WellKnownFunctionKind::NodeGypBuild) } - "bindings" => JsValue::WellKnownFunction(WellKnownFunctionKind::NodeBindings), + "node:bindings" | "bindings" => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeBindings) + } "express" => JsValue::WellKnownFunction(WellKnownFunctionKind::NodeExpress), "strong-globalize" => { JsValue::WellKnownFunction(WellKnownFunctionKind::NodeStrongGlobalize) diff --git a/crates/turbopack-tests/tests/snapshot.rs b/crates/turbopack-tests/tests/snapshot.rs index e332e8a917706..e2afe9756369f 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -261,6 +261,7 @@ async fn run_test(resource: String) -> Result> { ..Default::default() })), preset_env_versions: Some(env), + ignore_dynamic_requests: true, rules: vec![( ContextCondition::InDirectory("node_modules".to_string()), ModuleOptionsContext { diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js new file mode 100644 index 0000000000000..c1174f9211a50 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js @@ -0,0 +1,17 @@ +import child_process from "node:child_process"; +import fs, { readFileSync } from "node:fs"; + +const unknown = Math.random(); + +child_process.spawnSync(unknown); +child_process.spawnSync("node", unknown); +child_process.spawnSync("node", [unknown, unknown]); + +require(unknown); + +import(unknown); + +fs.readFileSync(unknown); +readFileSync(unknown); + +new URL(unknown, import.meta.url); diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt new file mode 100644 index 0000000000000..ef6e8298a5d80 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:12:0 lint TP1001 import(FreeVar(Math)["random"]()) is very dynamic + + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + 10 | require(unknown); + 11 | + + v-------------v + 12 + import(unknown); + + ^-------------^ + 13 | + 14 | fs.readFileSync(unknown); + 15 | readFileSync(unknown); + 16 | \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt new file mode 100644 index 0000000000000..3a5080fea30e1 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:10:0 lint TP1002 require(FreeVar(Math)["random"]()) is very dynamic + + 6 | child_process.spawnSync(unknown); + 7 | child_process.spawnSync("node", unknown); + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + + v--------------v + 10 + require(unknown); + + ^--------------^ + 11 | + 12 | import(unknown); + 13 | + 14 | fs.readFileSync(unknown); \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt new file mode 100644 index 0000000000000..6a31c28da0d86 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt @@ -0,0 +1,12 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:15:0 lint TP1004 fs.readFileSync(FreeVar(Math)["random"]()) is very dynamic + + 11 | + 12 | import(unknown); + 13 | + 14 | fs.readFileSync(unknown); + + v-------------------v + 15 + readFileSync(unknown); + + ^-------------------^ + 16 | + 17 | new URL(unknown, import.meta.url); + 18 | \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt new file mode 100644 index 0000000000000..3c5e2740bce66 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:14:0 lint TP1004 fs.readFileSync(FreeVar(Math)["random"]()) is very dynamic + + 10 | require(unknown); + 11 | + 12 | import(unknown); + 13 | + + v----------------------v + 14 + fs.readFileSync(unknown); + + ^----------------------^ + 15 | readFileSync(unknown); + 16 | + 17 | new URL(unknown, import.meta.url); + 18 | \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt new file mode 100644 index 0000000000000..bbb5163b08b7f --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:6:0 lint TP1005 child_process.spawnSync(FreeVar(Math)["random"]()) is very dynamic + + 2 | import fs, { readFileSync } from "node:fs"; + 3 | + 4 | const unknown = Math.random(); + 5 | + + v------------------------------v + 6 + child_process.spawnSync(unknown); + + ^------------------------------^ + 7 | child_process.spawnSync("node", unknown); + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + 10 | require(unknown); \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt new file mode 100644 index 0000000000000..adab944608ee8 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt @@ -0,0 +1,17 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:8:0 lint TP1005 child_process.spawnSync( + + 4 | const unknown = Math.random(); + 5 | + 6 | child_process.spawnSync(unknown); + 7 | child_process.spawnSync("node", unknown); + + v-------------------------------------------------v + 8 + child_process.spawnSync("node", [unknown, unknown]); + + ^-------------------------------------------------^ + 9 | + 10 | require(unknown); + 11 | + 12 | import(unknown); + + "node", + [FreeVar(Math)["random"](), FreeVar(Math)["random"]()] + ) is very dynamic \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt new file mode 100644 index 0000000000000..abac239782e5c --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:7:0 lint TP1005 child_process.spawnSync("node", FreeVar(Math)["random"]()) is very dynamic + + 3 | + 4 | const unknown = Math.random(); + 5 | + 6 | child_process.spawnSync(unknown); + + v--------------------------------------v + 7 + child_process.spawnSync("node", unknown); + + ^--------------------------------------^ + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + 10 | require(unknown); + 11 | \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt new file mode 100644 index 0000000000000..e96bb52573d90 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt @@ -0,0 +1,10 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:17:0 lint TP1201 new URL(Variable(unknown##2), import.meta.url) is very dynamic + + 13 | + 14 | fs.readFileSync(unknown); + 15 | readFileSync(unknown); + 16 | + + v-------------------------------v + 17 + new URL(unknown, import.meta.url); + + ^-------------------------------^ + 18 | \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json new file mode 100644 index 0000000000000..f530cd0f0bd7b --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json @@ -0,0 +1,3 @@ +{ + "environment": "NodeJs" +} diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js new file mode 100644 index 0000000000000..0d76aca2628b2 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js @@ -0,0 +1,41 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__, k: __turbopack_refresh__ }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__url__external__node$3a$child_process__ = __turbopack_external_require__("node:child_process", true); +var __TURBOPACK__url__external__node$3a$fs__ = __turbopack_external_require__("node:fs", true); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const unknown = Math.random(); +__TURBOPACK__url__external__node$3a$child_process__["default"].spawnSync(unknown); +__TURBOPACK__url__external__node$3a$child_process__["default"].spawnSync("node", unknown); +__TURBOPACK__url__external__node$3a$child_process__["default"].spawnSync("node", [ + unknown, + unknown +]); +(()=>{ + const e = new Error("Cannot find module as expression is too dynamic"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +})(); +Promise.resolve().then(()=>{ + const e = new Error("Cannot find module as expression is too dynamic"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +}); +__TURBOPACK__url__external__node$3a$fs__["default"].readFileSync(unknown); +(0, __TURBOPACK__url__external__node$3a$fs__["readFileSync"])(unknown); +new URL(unknown, __TURBOPACK__import$2e$meta__.url); + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map new file mode 100644 index 0000000000000..38923dcff52ad --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js"],"sourcesContent":["import child_process from \"node:child_process\";\nimport fs, { readFileSync } from \"node:fs\";\n\nconst unknown = Math.random();\n\nchild_process.spawnSync(unknown);\nchild_process.spawnSync(\"node\", unknown);\nchild_process.spawnSync(\"node\", [unknown, unknown]);\n\nrequire(unknown);\n\nimport(unknown);\n\nfs.readFileSync(unknown);\nreadFileSync(unknown);\n\nnew URL(unknown, import.meta.url);\n"],"names":[],"mappings":";;;;;;;;;;;AAGA,MAAM,UAAU,KAAK,MAAM;AAE3B,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC;AACxB,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;AAChC,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;IAAC;IAAS;CAAQ;;;;;;;;;;;AAMlD,wCAAA,CAAA,UAAE,CAAC,YAAY,CAAC;AAChB,CAAA,GAAA,wCAAA,CAAA,eAAY,AAAD,EAAE;AAEb,IAAI,IAAI,SAAS,8BAAY,GAAG"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_4598f4.js b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_4598f4.js new file mode 100644 index 0000000000000..c24de010acfe6 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_4598f4.js @@ -0,0 +1,11 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_4598f4.js", + {}, +]); +(globalThis.TURBOPACK_CHUNK_LISTS = globalThis.TURBOPACK_CHUNK_LISTS || []).push({ + "path": "output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_4598f4.js", + "chunks": [ + "output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js" + ], + "source": "entry" +}); \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js new file mode 100644 index 0000000000000..70b53abe38062 --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map new file mode 100644 index 0000000000000..a12b83d3337ca --- /dev/null +++ b/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map @@ -0,0 +1,4 @@ +{ + "version": 3, + "sections": [] +} \ No newline at end of file diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index 1f324261feda2..df01398db2cad 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -80,6 +80,7 @@ impl ModuleOptions { ref rules, esm_url_rewrite_behavior, import_externals, + ignore_dynamic_requests, use_lightningcss, .. } = *module_options_context.await?; @@ -118,6 +119,7 @@ impl ModuleOptions { tree_shaking_mode, url_rewrite_behavior: esm_url_rewrite_behavior, import_externals, + ignore_dynamic_requests, ..Default::default() }; diff --git a/crates/turbopack/src/module_options/module_options_context.rs b/crates/turbopack/src/module_options/module_options_context.rs index 3a2769d798369..2ed5c00b60ed7 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -153,6 +153,10 @@ pub struct ModuleOptionsContext { /// References to externals from ESM imports should use `import()` and make /// async modules. pub import_externals: bool, + /// Ignore very dynamic requests which doesn't have any static known part. + /// If false, they will reference the whole directory. If true, they won't + /// reference anything and lead to an runtime error instead. + pub ignore_dynamic_requests: bool, pub use_lightningcss: bool, }