From 5f57ec97c97e344be7dd52ce8d61d9b010b53ffa Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 17:14:15 +0800 Subject: [PATCH 1/9] Walk tpl expressions with odd index --- .../common_js_imports_parse_plugin.rs | 6 ++-- .../src/parser_plugin/import_parser_plugin.rs | 4 +-- .../dependency/context_dependency_helper.rs | 30 +++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs index 75199a68b0c..1fa879f2387 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs @@ -20,12 +20,13 @@ use crate::visitors::{extract_require_call_info, is_require_call_start}; fn create_commonjs_require_context_dependency( parser: &mut JavascriptParser, param: &BasicEvaluatedExpression, + expr: &Expr, callee_start: u32, callee_end: u32, args_end: u32, span: Option, ) -> CommonJsRequireContextDependency { - let result = create_context_dependency(param, parser); + let result = create_context_dependency(param, expr, parser); let options = ContextOptions { mode: ContextMode::Sync, recursive: true, @@ -137,14 +138,13 @@ impl CommonJsImportsParserPlugin { let dep = create_commonjs_require_context_dependency( parser, param, + &argument_expr, call_expr.callee.span().real_lo(), call_expr.callee.span().real_hi(), call_expr.span.real_hi(), Some(call_expr.span.into()), ); parser.dependencies.push(Box::new(dep)); - // FIXME: align `parser.walk_expression` to webpack, which put into `context_dependency_helper` - parser.walk_expression(argument_expr); Some(true) } diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/import_parser_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/import_parser_plugin.rs index c0887b84ffb..fce8c2d1e85 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/import_parser_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/import_parser_plugin.rs @@ -113,7 +113,7 @@ impl JavascriptParserPlugin for ImportParserPlugin { query, fragment, replaces, - } = create_context_dependency(¶m, parser); + } = create_context_dependency(¶m, &dyn_imported.expr, parser); parser .dependencies .push(Box::new(ImportContextDependency::new( @@ -146,8 +146,6 @@ impl JavascriptParserPlugin for ImportParserPlugin { Some(node.span.into()), parser.in_try, ))); - // FIXME: align `parser.walk_expression` to webpack, which put into `context_dependency_helper` - parser.walk_expression(&dyn_imported.expr); Some(true) } } diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index ab1d90d5aeb..a7ad6ee194d 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -2,8 +2,13 @@ use std::borrow::Cow; use itertools::Itertools; use rspack_core::parse_resource; +use rspack_core::SpanExt; use rspack_error::Severity; use rspack_util::json_stringify; +use swc_core::common::Spanned; +use swc_core::ecma::ast::Expr; +use swc_core::ecma::visit::Visit; +use swc_core::ecma::visit::VisitWith; use super::context_helper::{quote_meta, split_context_from_prefix}; use super::{create_traceable_error, ContextModuleScanResult}; @@ -14,6 +19,7 @@ const DEFAULT_WRAPPED_CONTEXT_REGEXP: &str = ".*"; pub fn create_context_dependency( param: &BasicEvaluatedExpression, + expr: &Expr, parser: &mut crate::visitors::JavascriptParser, ) -> ContextModuleScanResult { if param.is_template_string() { @@ -79,6 +85,12 @@ pub fn create_context_dependency( } } + let mut walker = ExprSpanFinder { + targets: vec![&parts[1]], + on_visit: |n| parser.walk_expression(n), + }; + expr.visit_with(&mut walker); + if parser.javascript_options.wrapped_context_critical { let range = param.range(); parser.warning_diagnostics.push(Box::new( @@ -190,3 +202,21 @@ pub fn create_context_dependency( } } } + +struct ExprSpanFinder<'a, F: FnMut(&Expr) -> ()> { + targets: Vec<&'a BasicEvaluatedExpression>, + on_visit: F, +} + +impl<'a, F: FnMut(&Expr) -> ()> Visit for ExprSpanFinder<'a, F> { + fn visit_expr(&mut self, n: &Expr) { + for t in self.targets.iter() { + let span = n.span(); + let (lo, hi) = t.range(); + if span.real_lo() == lo && span.hi().0 == hi { + (self.on_visit)(n); + } + } + n.visit_children_with(self); + } +} From bdbeaf256f47537cb31d683079ff242d385f24a9 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 17:19:56 +0800 Subject: [PATCH 2/9] Walk tpl expressions with odd index --- .../dependency/context_dependency_helper.rs | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index a7ad6ee194d..ac32e6eda18 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -57,36 +57,38 @@ pub fn create_context_dependency( ); let mut replaces = Vec::new(); - let parts = param.parts(); - for (i, part) in parts.iter().enumerate() { - if i % 2 == 0 { - if i == 0 { - let value = format!( - "{}{prefix}", - match param.template_string_kind() { - TemplateStringKind::Cooked => "`", - TemplateStringKind::Raw => "String.raw`", - } - ); - replaces.push((value, param.range().0, part.range().1)); - } else if i == parts.len() - 1 { - let value = format!("{postfix}`"); - replaces.push((value, part.range().0, param.range().1)); - } else { - let value = match param.template_string_kind() { - TemplateStringKind::Cooked => { - json_stringify(part.string()).trim_matches('"').to_owned() - } - TemplateStringKind::Raw => part.string().to_owned(), - }; - let range = part.range(); - replaces.push((value, range.0, range.1)); - } + let (even_parts, odd_parts): (Vec<_>, Vec<_>) = param + .parts() + .into_iter() + .enumerate() + .partition(|&(index, _)| index % 2 == 0); + let last_index = even_parts.len() - 1; + + for (i, part) in even_parts { + if i == 0 { + let value = format!( + "{}{prefix}", + match param.template_string_kind() { + TemplateStringKind::Cooked => "`", + TemplateStringKind::Raw => "String.raw`", + } + ); + replaces.push((value, param.range().0, part.range().1)); + } else if i == last_index { + let value = format!("{postfix}`"); + replaces.push((value, part.range().0, param.range().1)); + } else { + let value = match param.template_string_kind() { + TemplateStringKind::Cooked => json_stringify(part.string()).trim_matches('"').to_owned(), + TemplateStringKind::Raw => part.string().to_owned(), + }; + let range = part.range(); + replaces.push((value, range.0, range.1)); } } let mut walker = ExprSpanFinder { - targets: vec![&parts[1]], + targets: odd_parts.into_iter().map(|(_, part)| part).collect_vec(), on_visit: |n| parser.walk_expression(n), }; expr.visit_with(&mut walker); From a8b9a4215d7f093c0968256f5b31788adcf50c21 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 17:25:48 +0800 Subject: [PATCH 3/9] Add logic to walk wrapped inner expressions in visitor --- .../visitors/dependency/context_dependency_helper.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index ac32e6eda18..453c4f9ad9c 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -174,6 +174,14 @@ pub fn create_context_dependency( )); } + if let Some(wrapped_inner_expressions) = param.wrapped_inner_expressions() { + let mut walker = ExprSpanFinder { + targets: wrapped_inner_expressions.iter().collect_vec(), + on_visit: |n| parser.walk_expression(n), + }; + expr.visit_with(&mut walker); + } + ContextModuleScanResult { context, reg, @@ -181,7 +189,6 @@ pub fn create_context_dependency( fragment, replaces, } - // TODO: handle `param.wrappedInnerExpressions` } else { if parser.javascript_options.expr_context_critical { let range = param.range(); @@ -195,6 +202,7 @@ pub fn create_context_dependency( .with_severity(Severity::Warn), )); } + parser.walk_expression(expr); ContextModuleScanResult { context: String::from("."), reg: String::new(), From 1b580aae97a9d785481cf1cc09d1da9e3f90658d Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 17:37:24 +0800 Subject: [PATCH 4/9] Update testcase --- .../tests/builtinCases/rspack/dynamic-import/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/index.js b/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/index.js index 553b27b29c7..d6e0cdcd5a1 100644 --- a/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/index.js +++ b/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/index.js @@ -4,9 +4,12 @@ import(`./child/b.js`).then(({ b }) => console.log("Template Literal", b)); import(`./child/${request}.js`).then(({ a }) => console.log("context_module_tpl", a) ); +import(`./child/${true ? "a" : "b"}.js`).then(({ a }) => + console.log("context_module_tpl_with_cond", a) +); import("./child/" + request + ".js").then(({ a }) => console.log("context_module_bin", a) ); import("./child/".concat(request, ".js")).then(({ a }) => console.log("context_module_concat", a) -); +); \ No newline at end of file From 774975a21cf6c922dcda450c07fe5b3f001df856 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 21:04:50 +0800 Subject: [PATCH 5/9] Fix index --- .../dependency/context_dependency_helper.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index 453c4f9ad9c..213edf2aa84 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use itertools::Either; use itertools::Itertools; use rspack_core::parse_resource; use rspack_core::SpanExt; @@ -61,10 +62,16 @@ pub fn create_context_dependency( .parts() .into_iter() .enumerate() - .partition(|&(index, _)| index % 2 == 0); + .partition_map(|(index, part)| { + if index % 2 == 0 { + Either::Left(part) + } else { + Either::Right(part) + } + }); let last_index = even_parts.len() - 1; - for (i, part) in even_parts { + for (i, part) in even_parts.into_iter().enumerate() { if i == 0 { let value = format!( "{}{prefix}", @@ -88,7 +95,7 @@ pub fn create_context_dependency( } let mut walker = ExprSpanFinder { - targets: odd_parts.into_iter().map(|(_, part)| part).collect_vec(), + targets: odd_parts, on_visit: |n| parser.walk_expression(n), }; expr.visit_with(&mut walker); From af4d31788c96b5c14c0a04c97e2050c3ba0d8d40 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 21:06:17 +0800 Subject: [PATCH 6/9] Update name --- .../src/visitors/dependency/context_dependency_helper.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index 213edf2aa84..696a2c82775 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -94,7 +94,7 @@ pub fn create_context_dependency( } } - let mut walker = ExprSpanFinder { + let mut walker = BasicEvaluatedExpressionVisitor { targets: odd_parts, on_visit: |n| parser.walk_expression(n), }; @@ -182,7 +182,7 @@ pub fn create_context_dependency( } if let Some(wrapped_inner_expressions) = param.wrapped_inner_expressions() { - let mut walker = ExprSpanFinder { + let mut walker = BasicEvaluatedExpressionVisitor { targets: wrapped_inner_expressions.iter().collect_vec(), on_visit: |n| parser.walk_expression(n), }; @@ -220,12 +220,12 @@ pub fn create_context_dependency( } } -struct ExprSpanFinder<'a, F: FnMut(&Expr) -> ()> { +struct BasicEvaluatedExpressionVisitor<'a, F: FnMut(&Expr) -> ()> { targets: Vec<&'a BasicEvaluatedExpression>, on_visit: F, } -impl<'a, F: FnMut(&Expr) -> ()> Visit for ExprSpanFinder<'a, F> { +impl<'a, F: FnMut(&Expr) -> ()> Visit for BasicEvaluatedExpressionVisitor<'a, F> { fn visit_expr(&mut self, n: &Expr) { for t in self.targets.iter() { let span = n.span(); From b3b1b77c8fc5970a26d48fd114c92138e037d3b3 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 21:17:13 +0800 Subject: [PATCH 7/9] Remove success expr for performance --- .../src/visitors/dependency/context_dependency_helper.rs | 8 +++++--- .../rspack/dynamic-import/__snapshots__/output.snap.txt | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index 696a2c82775..767e6f91b31 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -227,13 +227,15 @@ struct BasicEvaluatedExpressionVisitor<'a, F: FnMut(&Expr) -> ()> { impl<'a, F: FnMut(&Expr) -> ()> Visit for BasicEvaluatedExpressionVisitor<'a, F> { fn visit_expr(&mut self, n: &Expr) { - for t in self.targets.iter() { + self.targets.retain(|evaluted_expr| { let span = n.span(); - let (lo, hi) = t.range(); + let (lo, hi) = evaluted_expr.range(); if span.real_lo() == lo && span.hi().0 == hi { (self.on_visit)(n); + return false; } - } + true + }); n.visit_children_with(self); } } diff --git a/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/__snapshots__/output.snap.txt b/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/__snapshots__/output.snap.txt index 1b1817fba1d..c8b815a0dfc 100644 --- a/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/__snapshots__/output.snap.txt +++ b/packages/rspack-test-tools/tests/builtinCases/rspack/dynamic-import/__snapshots__/output.snap.txt @@ -71,6 +71,9 @@ __webpack_require__.e(/* import() */ "child_b_js").then(__webpack_require__.bind __webpack_require__("./child lazy recursive ^\\.\\/.*\\.js$")(`./${request}.js`).then(({ a }) => console.log("context_module_tpl", a) ); +__webpack_require__.e(/* import() */ "child_a_js").then(__webpack_require__.bind(__webpack_require__, "./child/a.js")).then(({ a }) => + console.log("context_module_tpl_with_cond", a) +); __webpack_require__("./child lazy recursive ^\\.\\/.*\\.js$")("./" + request + ".js").then(({ a }) => console.log("context_module_bin", a) ); @@ -78,7 +81,6 @@ __webpack_require__("./child lazy recursive ^\\.\\/.*\\.js$")("./".concat(reques console.log("context_module_concat", a) ); - }), },function(__webpack_require__) { From 3cdae65ff675fd6dc27691b1c8f3905bee90541c Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 27 Jun 2024 21:40:40 +0800 Subject: [PATCH 8/9] Fix typo --- .../src/visitors/dependency/context_dependency_helper.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index 767e6f91b31..9fe49c3ef14 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -227,9 +227,9 @@ struct BasicEvaluatedExpressionVisitor<'a, F: FnMut(&Expr) -> ()> { impl<'a, F: FnMut(&Expr) -> ()> Visit for BasicEvaluatedExpressionVisitor<'a, F> { fn visit_expr(&mut self, n: &Expr) { - self.targets.retain(|evaluted_expr| { + self.targets.retain(|evaluated_expr| { let span = n.span(); - let (lo, hi) = evaluted_expr.range(); + let (lo, hi) = evaluated_expr.range(); if span.real_lo() == lo && span.hi().0 == hi { (self.on_visit)(n); return false; From 85456ac0ae016f9076e1f419d62eee204bf6a804 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Fri, 28 Jun 2024 12:05:00 +0800 Subject: [PATCH 9/9] Fix clippy --- .../common_js_imports_parse_plugin.rs | 2 +- .../dependency/context_dependency_helper.rs | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs index 1fa879f2387..390e734c0de 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs @@ -138,7 +138,7 @@ impl CommonJsImportsParserPlugin { let dep = create_commonjs_require_context_dependency( parser, param, - &argument_expr, + argument_expr, call_expr.callee.span().real_lo(), call_expr.callee.span().real_hi(), call_expr.span.real_hi(), diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs index 9fe49c3ef14..78cbab833f2 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/context_dependency_helper.rs @@ -58,17 +58,18 @@ pub fn create_context_dependency( ); let mut replaces = Vec::new(); - let (even_parts, odd_parts): (Vec<_>, Vec<_>) = param - .parts() - .into_iter() - .enumerate() - .partition_map(|(index, part)| { - if index % 2 == 0 { - Either::Left(part) - } else { - Either::Right(part) - } - }); + let (even_parts, odd_parts): (Vec<_>, Vec<_>) = + param + .parts() + .iter() + .enumerate() + .partition_map(|(index, part)| { + if index % 2 == 0 { + Either::Left(part) + } else { + Either::Right(part) + } + }); let last_index = even_parts.len() - 1; for (i, part) in even_parts.into_iter().enumerate() { @@ -220,12 +221,12 @@ pub fn create_context_dependency( } } -struct BasicEvaluatedExpressionVisitor<'a, F: FnMut(&Expr) -> ()> { +struct BasicEvaluatedExpressionVisitor<'a, F: FnMut(&Expr)> { targets: Vec<&'a BasicEvaluatedExpression>, on_visit: F, } -impl<'a, F: FnMut(&Expr) -> ()> Visit for BasicEvaluatedExpressionVisitor<'a, F> { +impl<'a, F: FnMut(&Expr)> Visit for BasicEvaluatedExpressionVisitor<'a, F> { fn visit_expr(&mut self, n: &Expr) { self.targets.retain(|evaluated_expr| { let span = n.span();