From 6f44693fb77b3e0470447a614ee6e1c4a3ccf0d3 Mon Sep 17 00:00:00 2001 From: inottn Date: Thu, 26 Sep 2024 00:01:57 +0800 Subject: [PATCH] feat: support wrappedContextRegExp --- crates/node_binding/binding.d.ts | 1 + .../src/options/raw_module/mod.rs | 8 +++++++- crates/rspack_core/src/options/module.rs | 1 + .../dependency/context_dependency_helper.rs | 15 +++++++++------ crates/rspack_util/src/merge.rs | 3 +++ .../tests/__snapshots__/Defaults.test.js.snap | 1 + .../wrapped-context-reg-exp/index.js | 6 ++++++ .../wrapped-context-reg-exp/rspack.config.js | 11 +++++++++++ .../wrapped-context-reg-exp/sub/a1.js | 1 + .../wrapped-context-reg-exp/sub/a2.js | 1 + packages/rspack/src/config/adapter.ts | 1 + packages/rspack/src/config/defaults.ts | 1 + packages/rspack/src/config/types.ts | 5 +++++ packages/rspack/src/config/zod.ts | 2 ++ website/docs/en/config/module.mdx | 9 +++++++++ website/docs/zh/config/module.mdx | 9 +++++++++ 16 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/index.js create mode 100644 packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/rspack.config.js create mode 100644 packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a1.js create mode 100644 packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a2.js diff --git a/crates/node_binding/binding.d.ts b/crates/node_binding/binding.d.ts index 8d2531e0231..0f9be0e0d01 100644 --- a/crates/node_binding/binding.d.ts +++ b/crates/node_binding/binding.d.ts @@ -1436,6 +1436,7 @@ export interface RawJavascriptParserOptions { url?: string exprContextCritical?: boolean wrappedContextCritical?: boolean + wrappedContextRegExp?: RegExp exportsPresence?: string importExportsPresence?: string reexportExportsPresence?: string diff --git a/crates/rspack_binding_options/src/options/raw_module/mod.rs b/crates/rspack_binding_options/src/options/raw_module/mod.rs index e617bb8475d..31d2ca878ba 100644 --- a/crates/rspack_binding_options/src/options/raw_module/mod.rs +++ b/crates/rspack_binding_options/src/options/raw_module/mod.rs @@ -21,6 +21,7 @@ use rspack_core::{ use rspack_error::error; use rspack_napi::regexp::{JsRegExp, JsRegExpExt}; use rspack_napi::threadsafe_function::ThreadsafeFunction; +use rspack_regex::RspackRegex; use tokio::runtime::Handle; use crate::RawResolveOptions; @@ -110,7 +111,7 @@ impl TryFrom for rspack_core::RuleSetCondition { let result = match x { RawRuleSetCondition::string(s) => Self::String(s), RawRuleSetCondition::regexp(r) => { - let reg = rspack_regex::RspackRegex::with_flags(&r.source, &r.flags)?; + let reg = RspackRegex::with_flags(&r.source, &r.flags)?; Self::Regexp(reg) } RawRuleSetCondition::logical(mut l) => { @@ -265,6 +266,8 @@ pub struct RawJavascriptParserOptions { pub url: Option, pub expr_context_critical: Option, pub wrapped_context_critical: Option, + #[napi(ts_type = "RegExp")] + pub wrapped_context_reg_exp: Option, pub exports_presence: Option, pub import_exports_presence: Option, pub reexport_exports_presence: Option, @@ -303,6 +306,9 @@ impl From for JavascriptParserOptions { .map(|x| DynamicImportFetchPriority::from(x.as_str())), url: value.url.map(|v| JavascriptParserUrl::from(v.as_str())), expr_context_critical: value.expr_context_critical, + wrapped_context_reg_exp: value + .wrapped_context_reg_exp + .map(|context_reg_exp| context_reg_exp.to_rspack_regex()), wrapped_context_critical: value.wrapped_context_critical, exports_presence: value .exports_presence diff --git a/crates/rspack_core/src/options/module.rs b/crates/rspack_core/src/options/module.rs index 9a9c5e3013e..6869023b6b1 100644 --- a/crates/rspack_core/src/options/module.rs +++ b/crates/rspack_core/src/options/module.rs @@ -228,6 +228,7 @@ pub struct JavascriptParserOptions { pub url: Option, pub expr_context_critical: Option, pub wrapped_context_critical: Option, + pub wrapped_context_reg_exp: Option, pub exports_presence: Option, pub import_exports_presence: Option, pub reexport_exports_presence: Option, 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 6d805872282..af5e4604ba2 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 @@ -11,15 +11,18 @@ use swc_core::ecma::ast::Expr; use super::create_traceable_error; use crate::utils::eval::{BasicEvaluatedExpression, TemplateStringKind}; -// FIXME: delete this after `parserOptions.wrappedContextRegExp.source` -const DEFAULT_WRAPPED_CONTEXT_REGEXP: &str = ".*"; - pub fn create_context_dependency( param: &BasicEvaluatedExpression, expr: &Expr, parser: &mut crate::visitors::JavascriptParser, ) -> ContextModuleScanResult { let mut critical = None; + let wrapped_context_reg_exp = parser + .javascript_options + .wrapped_context_reg_exp + .as_ref() + .expect("should have wrapped_context_reg_exp") + .source(); if param.is_template_string() { let quasis = param.quasis(); @@ -47,10 +50,10 @@ pub fn create_context_dependency( let reg = format!( "^{}{}{}{}$", quote_meta(&prefix), - DEFAULT_WRAPPED_CONTEXT_REGEXP, + wrapped_context_reg_exp, quasis[1..quasis.len() - 1] .iter() - .map(|q| quote_meta(q.string().as_str()) + DEFAULT_WRAPPED_CONTEXT_REGEXP) + .map(|q| quote_meta(q.string().as_str()) + wrapped_context_reg_exp) .join(""), quote_meta(&postfix) ); @@ -148,7 +151,7 @@ pub fn create_context_dependency( }; let reg = format!( - "^{}{DEFAULT_WRAPPED_CONTEXT_REGEXP}{}$", + "^{}{wrapped_context_reg_exp}{}$", quote_meta(&prefix), quote_meta(&postfix) ); diff --git a/crates/rspack_util/src/merge.rs b/crates/rspack_util/src/merge.rs index d0eb4545917..18d59c6c0ce 100644 --- a/crates/rspack_util/src/merge.rs +++ b/crates/rspack_util/src/merge.rs @@ -1,3 +1,5 @@ +use rspack_regex::RspackRegex; + use crate::atom::Atom; pub trait MergeFrom: Clone { @@ -42,6 +44,7 @@ impl_merge_from!(u8, u16, u32, u64, u128); impl_merge_from!(bool); impl_merge_from!(String); impl_merge_from!(Atom); +impl_merge_from!(RspackRegex); pub fn merge_from_optional_with( base: Option, diff --git a/packages/rspack-test-tools/tests/__snapshots__/Defaults.test.js.snap b/packages/rspack-test-tools/tests/__snapshots__/Defaults.test.js.snap index 4efaad11249..c79ee8a0ab7 100644 --- a/packages/rspack-test-tools/tests/__snapshots__/Defaults.test.js.snap +++ b/packages/rspack-test-tools/tests/__snapshots__/Defaults.test.js.snap @@ -181,6 +181,7 @@ Object { "...", ], "wrappedContextCritical": false, + "wrappedContextRegExp": /\\.\\*/, }, }, "rules": Array [], diff --git a/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/index.js b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/index.js new file mode 100644 index 00000000000..146c2f90d71 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/index.js @@ -0,0 +1,6 @@ +it("should not include foo.js", async () => { + let a1 = 'a1'; + let a2 = 'a2'; + expect(require('./sub/' + a1)).toBe("a1"); + expect(() => require('./sub/' + a2)).toThrow(); +}); diff --git a/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/rspack.config.js b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/rspack.config.js new file mode 100644 index 00000000000..c36e38804e3 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/rspack.config.js @@ -0,0 +1,11 @@ +/** @type {import("@rspack/core").Configuration} */ +module.exports = { + module: { + parser: { + javascript: { + wrappedContextRegExp: /.*1/, + } + } + }, + } + \ No newline at end of file diff --git a/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a1.js b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a1.js new file mode 100644 index 00000000000..43fdf24e11a --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a1.js @@ -0,0 +1 @@ +module.exports = "a1"; diff --git a/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a2.js b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a2.js new file mode 100644 index 00000000000..785a52236e1 --- /dev/null +++ b/packages/rspack-test-tools/tests/configCases/context-module/wrapped-context-reg-exp/sub/a2.js @@ -0,0 +1 @@ +module.exports = "a2"; diff --git a/packages/rspack/src/config/adapter.ts b/packages/rspack/src/config/adapter.ts index f00c088dc48..2aae1f97a81 100644 --- a/packages/rspack/src/config/adapter.ts +++ b/packages/rspack/src/config/adapter.ts @@ -665,6 +665,7 @@ function getRawJavascriptParserOptions( url: parser.url?.toString(), exprContextCritical: parser.exprContextCritical, wrappedContextCritical: parser.wrappedContextCritical, + wrappedContextRegExp: parser.wrappedContextRegExp, exportsPresence: parser.exportsPresence === false ? "false" : parser.exportsPresence, importExportsPresence: diff --git a/packages/rspack/src/config/defaults.ts b/packages/rspack/src/config/defaults.ts index 11f18968572..220dacbba54 100644 --- a/packages/rspack/src/config/defaults.ts +++ b/packages/rspack/src/config/defaults.ts @@ -250,6 +250,7 @@ const applyJavascriptParserOptionsDefaults = ( D(parserOptions, "url", true); D(parserOptions, "exprContextCritical", true); D(parserOptions, "wrappedContextCritical", false); + D(parserOptions, "wrappedContextRegExp", /.*/); D(parserOptions, "strictExportPresence", false); D(parserOptions, "requireAsExpression", true); D(parserOptions, "requireDynamic", true); diff --git a/packages/rspack/src/config/types.ts b/packages/rspack/src/config/types.ts index f563efca52c..cb148970e70 100644 --- a/packages/rspack/src/config/types.ts +++ b/packages/rspack/src/config/types.ts @@ -1001,6 +1001,11 @@ export type JavascriptParserOptions = { * */ wrappedContextCritical?: boolean; + /** + * Set the inner regular expression for partial dynamic dependencies + * */ + wrappedContextRegExp?: RegExp; + /** * Warn or error for using non-existent exports and conflicting re-exports. * @default 'auto' diff --git a/packages/rspack/src/config/zod.ts b/packages/rspack/src/config/zod.ts index 8662b131f84..b4988c5a187 100644 --- a/packages/rspack/src/config/zod.ts +++ b/packages/rspack/src/config/zod.ts @@ -527,6 +527,7 @@ const dynamicImportFetchPriority = z.enum(["low", "high", "auto"]); const javascriptParserUrl = z.union([z.literal("relative"), z.boolean()]); const exprContextCritical = z.boolean(); const wrappedContextCritical = z.boolean(); +const wrappedContextRegExp = z.instanceof(RegExp); const exportsPresence = z.enum(["error", "warn", "auto"]).or(z.literal(false)); const importExportsPresence = z .enum(["error", "warn", "auto"]) @@ -551,6 +552,7 @@ const javascriptParserOptions = z.strictObject({ url: javascriptParserUrl.optional(), exprContextCritical: exprContextCritical.optional(), wrappedContextCritical: wrappedContextCritical.optional(), + wrappedContextRegExp: wrappedContextRegExp.optional(), exportsPresence: exportsPresence.optional(), importExportsPresence: importExportsPresence.optional(), reexportExportsPresence: reexportExportsPresence.optional(), diff --git a/website/docs/en/config/module.mdx b/website/docs/en/config/module.mdx index cb60bb2ace5..eb8ad44c273 100644 --- a/website/docs/en/config/module.mdx +++ b/website/docs/en/config/module.mdx @@ -211,6 +211,15 @@ Enable warnings for full dynamic dependencies (`import(variable)`). Enable warnings for partial dynamic dependencies (`import("./path/to/" + variable)`). +#### module.parser.javascript.wrappedContextRegExp + + + +Set a regular expression to match wrapped dynamic dependencies. + #### module.parser.javascript.importMeta diff --git a/website/docs/zh/config/module.mdx b/website/docs/zh/config/module.mdx index 15035a689f1..c02eef7cbbf 100644 --- a/website/docs/zh/config/module.mdx +++ b/website/docs/zh/config/module.mdx @@ -211,6 +211,15 @@ module.exports = { 启用部分动态依赖(`import("./path/to/" + variable)`)的警告。 +#### module.parser.javascript.wrappedContextRegExp + + + +设置正则表达式,用于匹配包裹的动态依赖。 + #### module.parser.javascript.importMeta