From faefec46d3228cca58482cd1787670d121b48b46 Mon Sep 17 00:00:00 2001 From: LingyuCoder Date: Mon, 28 Oct 2024 18:30:13 +0800 Subject: [PATCH] fix: compile time evaluation of require.ensure --- ..._ensure_dependencies_block_parse_plugin.rs | 41 +++++++++++++++++-- .../cases/parsing/typeof/index.js | 10 ++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/require_ensure_dependencies_block_parse_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/require_ensure_dependencies_block_parse_plugin.rs index cfb4fe3f86a..ae2be36dc1b 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/require_ensure_dependencies_block_parse_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/require_ensure_dependencies_block_parse_plugin.rs @@ -2,23 +2,58 @@ use std::borrow::Cow; use either::Either; use rspack_core::{ - AsyncDependenciesBlock, BoxDependency, ChunkGroupOptions, DependencyLocation, GroupOptions, - RealDependencyLocation, + AsyncDependenciesBlock, BoxDependency, ChunkGroupOptions, ConstDependency, DependencyLocation, + GroupOptions, RealDependencyLocation, SpanExt, }; use swc_core::{ common::Spanned, - ecma::ast::{ArrowExpr, BlockStmtOrExpr, CallExpr, Expr, FnExpr}, + ecma::ast::{ArrowExpr, BlockStmtOrExpr, CallExpr, Expr, FnExpr, UnaryExpr}, }; use super::JavascriptParserPlugin; use crate::{ dependency::{RequireEnsureDependency, RequireEnsureItemDependency}, + utils::eval::{self, BasicEvaluatedExpression}, visitors::{expr_matcher::is_require_ensure, JavascriptParser, Statement}, }; pub struct RequireEnsureDependenciesBlockParserPlugin; impl JavascriptParserPlugin for RequireEnsureDependenciesBlockParserPlugin { + fn evaluate_typeof( + &self, + _parser: &mut JavascriptParser, + expr: &UnaryExpr, + for_name: &str, + ) -> Option { + (for_name == "require.ensure").then(|| { + eval::evaluate_to_string( + "function".to_string(), + expr.span.real_lo(), + expr.span.real_hi(), + ) + }) + } + + fn r#typeof( + &self, + parser: &mut JavascriptParser, + expr: &swc_core::ecma::ast::UnaryExpr, + for_name: &str, + ) -> Option { + (for_name == "require.ensure").then(|| { + parser + .presentational_dependencies + .push(Box::new(ConstDependency::new( + expr.span().real_lo(), + expr.span.real_hi(), + "'function'".into(), + None, + ))); + true + }) + } + fn call(&self, parser: &mut JavascriptParser, expr: &CallExpr, _for_name: &str) -> Option { if expr .callee diff --git a/tests/webpack-test/cases/parsing/typeof/index.js b/tests/webpack-test/cases/parsing/typeof/index.js index 678525a14d9..ed3856958a8 100644 --- a/tests/webpack-test/cases/parsing/typeof/index.js +++ b/tests/webpack-test/cases/parsing/typeof/index.js @@ -23,9 +23,9 @@ it("should answer typeof exports correctly", function () { // it("should answer typeof require.include correctly", function () { // expect(typeof require.include).toBe("function"); // }); -// it("should answer typeof require.ensure correctly", function () { -// expect(typeof require.ensure).toBe("function"); -// }); +it("should answer typeof require.ensure correctly", function () { + expect(typeof require.ensure).toBe("function"); +}); it("should answer typeof require.resolve correctly", function () { expect(typeof require.resolve).toBe("function"); }); @@ -43,6 +43,6 @@ it("should not parse filtered stuff", function () { if (typeof module != "object") module = require("fail"); if (typeof exports == "undefined") exports = require("fail"); // if (typeof require.include !== "function") require.include("fail"); - // if (typeof require.ensure !== "function") - // require.ensure(["fail"], function () { }); + if (typeof require.ensure !== "function") + require.ensure(["fail"], function () { }); });