diff --git a/crates/rspack_plugin_javascript/src/utils/eval/eval_unary_expr.rs b/crates/rspack_plugin_javascript/src/utils/eval/eval_unary_expr.rs index 37d38b52f947..6c8ef0a63ac2 100644 --- a/crates/rspack_plugin_javascript/src/utils/eval/eval_unary_expr.rs +++ b/crates/rspack_plugin_javascript/src/utils/eval/eval_unary_expr.rs @@ -30,6 +30,10 @@ fn eval_typeof( let mut res = BasicEvaluatedExpression::with_range(expr.span.real_lo(), expr.span.hi.0); res.set_string("string".to_string()); Some(res) + } else if arg.is_undefined() { + let mut res = BasicEvaluatedExpression::with_range(expr.span.real_lo(), expr.span.hi.0); + res.set_string("undefined".to_string()); + Some(res) } else { // TODO: `arg.is_wrapped()`... None diff --git a/crates/rspack_plugin_javascript/src/utils/eval/mod.rs b/crates/rspack_plugin_javascript/src/utils/eval/mod.rs index 475089ea5275..23daba862ebc 100644 --- a/crates/rspack_plugin_javascript/src/utils/eval/mod.rs +++ b/crates/rspack_plugin_javascript/src/utils/eval/mod.rs @@ -218,7 +218,7 @@ impl BasicEvaluatedExpression { pub fn as_bool(&self) -> Option { if self.truthy { Some(true) - } else if self.falsy || self.nullish == Some(true) || self.is_null() { + } else if self.falsy || self.nullish == Some(true) || self.is_null() || self.is_undefined() { Some(false) } else { self.boolean @@ -284,6 +284,11 @@ impl BasicEvaluatedExpression { self.side_effects = false } + pub fn set_undefined(&mut self) { + self.ty = Ty::Undefined; + self.side_effects = false; + } + pub fn set_number(&mut self, number: Number) { self.ty = Ty::Number; self.number = Some(number); diff --git a/crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs b/crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs index 1151e4bb43b4..59af738487e4 100644 --- a/crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs +++ b/crates/rspack_plugin_javascript/src/visitors/dependency/parser/mod.rs @@ -758,10 +758,16 @@ impl JavascriptParser<'_> { .or_else(|| { let mut eval = BasicEvaluatedExpression::with_range(ident.span.real_lo(), ident.span.hi.0); - eval.set_identifier( - ident.sym.to_string(), - ExportedVariableInfo::Name(ident.sym.to_string()), - ); + + if ident.sym.eq("undefined") { + eval.set_undefined(); + } else { + eval.set_identifier( + ident.sym.to_string(), + ExportedVariableInfo::Name(ident.sym.to_string()), + ); + } + Some(eval) }); }; diff --git a/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/a.js b/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/a.js new file mode 100644 index 000000000000..6cd1d0075d40 --- /dev/null +++ b/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/index.js b/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/index.js new file mode 100644 index 000000000000..e0e3f96fd7a6 --- /dev/null +++ b/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/index.js @@ -0,0 +1,4 @@ +it("should evaluate null", function () { + expect(null ? require("fail") : require("./a.js")).toBe("a"); + if (null) require("fail"); +}); diff --git a/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/webpack.config.js b/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/webpack.config.js new file mode 100644 index 000000000000..0ed6583dd314 --- /dev/null +++ b/packages/rspack/tests/configCases/parsing/eval-null-in-none-mode/webpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + mode: "none" +}; diff --git a/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/a.js b/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/a.js new file mode 100644 index 000000000000..6cd1d0075d40 --- /dev/null +++ b/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/index.js b/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/index.js new file mode 100644 index 000000000000..3a707bffa842 --- /dev/null +++ b/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/index.js @@ -0,0 +1,7 @@ +it("should evaluate undefined", function () { + expect(undefined ? require("fail") : require("./a")).toBe("a"); + if (undefined) require("fail"); + undefined && require("fail"); + typeof undefined === "undefined" ? require("./a") : require("fail"); + if (typeof undefined !== "undefined") require("fail"); +}); diff --git a/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/webpack.config.js b/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/webpack.config.js new file mode 100644 index 000000000000..0ed6583dd314 --- /dev/null +++ b/packages/rspack/tests/configCases/parsing/eval-undefined-in-none-mode/webpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + mode: "none" +};