diff --git a/crates/mako/src/build/transform.rs b/crates/mako/src/build/transform.rs index b02ce7469..dd6bbe227 100644 --- a/crates/mako/src/build/transform.rs +++ b/crates/mako/src/build/transform.rs @@ -28,6 +28,7 @@ use crate::features; use crate::module::ModuleAst; use crate::plugin::PluginTransformJsParam; use crate::plugins::context_module::ContextModuleVisitor; +use crate::visitors::amd_define_overrides::amd_define_overrides; use crate::visitors::css_assets::CSSAssets; use crate::visitors::css_flexbugs::CSSFlexbugs; use crate::visitors::css_px2rem::Px2Rem; @@ -246,6 +247,7 @@ impl Transform { ..Default::default() }, )), + Box::new(amd_define_overrides(unresolved_mark)), ]; ast.transform( &mut vec![], diff --git a/crates/mako/src/generate/transform.rs b/crates/mako/src/generate/transform.rs index 5fa73050f..f0ca9c4a8 100644 --- a/crates/mako/src/generate/transform.rs +++ b/crates/mako/src/generate/transform.rs @@ -258,7 +258,6 @@ pub fn transform_js_generate(transform_js_param: TransformJsParam) -> Result<()> let origin_comments = context.meta.script.origin_comments.read().unwrap(); let swc_comments = origin_comments.get_swc_comments(); ast.ast.visit_mut_with(&mut fixer(Some(swc_comments))); - Ok(()) }) }) diff --git a/crates/mako/src/visitors.rs b/crates/mako/src/visitors.rs index 9e4edbf0a..eed5b3e1f 100644 --- a/crates/mako/src/visitors.rs +++ b/crates/mako/src/visitors.rs @@ -1,3 +1,4 @@ +pub(crate) mod amd_define_overrides; pub(crate) mod async_module; pub(crate) mod common_js; pub(crate) mod css_assets; diff --git a/crates/mako/src/visitors/amd_define_overrides.rs b/crates/mako/src/visitors/amd_define_overrides.rs new file mode 100644 index 000000000..a5feb1550 --- /dev/null +++ b/crates/mako/src/visitors/amd_define_overrides.rs @@ -0,0 +1,82 @@ +use swc_core::common::{Mark, DUMMY_SP}; +use swc_core::ecma::ast::*; +use swc_core::ecma::visit::{as_folder, Fold, VisitMut}; + +use crate::ast::utils::is_ident_undefined; + +pub struct AmdDefineOverrides { + unresolved_mark: Mark, +} + +pub fn amd_define_overrides(unresolved_mark: Mark) -> impl VisitMut + Fold { + as_folder(AmdDefineOverrides { unresolved_mark }) +} + +impl VisitMut for AmdDefineOverrides { + fn visit_mut_unary_expr(&mut self, node: &mut UnaryExpr) { + if node.op == UnaryOp::TypeOf + && let Some(arg_ident) = node.arg.as_ident() + && is_ident_undefined(arg_ident, "define", &self.unresolved_mark) + { + node.arg = Expr::undefined(DUMMY_SP) + } + } +} + +#[cfg(test)] +mod tests { + use swc_core::common::GLOBALS; + use swc_core::ecma::visit::VisitMutWith; + + use super::*; + use crate::ast::tests::TestUtils; + + #[test] + fn unresolve_typeof_define_change_to_undefined() { + let mut tu = TestUtils::gen_js_ast( + r#"if(typeof define ==="function" && define.amd) { + console.log("amd") + }"#, + ); + let js = tu.ast.js_mut(); + let unresolved_mark = js.unresolved_mark; + GLOBALS.set(&tu.context.meta.script.globals, || { + js.ast + .visit_mut_with(&mut amd_define_overrides(unresolved_mark)); + }); + + let code = tu.js_ast_to_code(); + + assert_eq!( + code, + r#"if (typeof void 0 === "function" && define.amd) { + console.log("amd"); +}"# + ) + } + + #[test] + fn id_define_is_declared() { + let mut tu = TestUtils::gen_js_ast( + r#"let define = 1; if(typeof define ==="number") { + console.log("number") + }"#, + ); + let js = tu.ast.js_mut(); + let unresolved_mark = js.unresolved_mark; + GLOBALS.set(&tu.context.meta.script.globals, || { + js.ast + .visit_mut_with(&mut amd_define_overrides(unresolved_mark)); + }); + + let code = tu.js_ast_to_code(); + + assert_eq!( + code, + r#"let define = 1; +if (typeof define === "number") { + console.log("number"); +}"# + ); + } +} diff --git a/e2e/fixtures/javascript.transform.amd/expect.js b/e2e/fixtures/javascript.transform.amd/expect.js new file mode 100644 index 000000000..3d9074aa7 --- /dev/null +++ b/e2e/fixtures/javascript.transform.amd/expect.js @@ -0,0 +1,6 @@ +const {parseBuildResult, injectSimpleJest} = require("../../../scripts/test-utils"); +const {distDir} = parseBuildResult(__dirname); + +injectSimpleJest() +require('./dist/index.js'); + diff --git a/e2e/fixtures/javascript.transform.amd/mako.config.json b/e2e/fixtures/javascript.transform.amd/mako.config.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/e2e/fixtures/javascript.transform.amd/mako.config.json @@ -0,0 +1 @@ +{} diff --git a/e2e/fixtures/javascript.transform.amd/src/a.ts b/e2e/fixtures/javascript.transform.amd/src/a.ts new file mode 100644 index 000000000..02d9bd021 --- /dev/null +++ b/e2e/fixtures/javascript.transform.amd/src/a.ts @@ -0,0 +1,13 @@ +// @ts-nocheck +(function (root, definition) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define(definition); + } else if (typeof module === 'object' && module.exports) { + module.exports = definition(); + } else { + root.log = definition(); + } +}(this, function () { + return 1 +})) diff --git a/e2e/fixtures/javascript.transform.amd/src/index.ts b/e2e/fixtures/javascript.transform.amd/src/index.ts new file mode 100644 index 000000000..93e037b5a --- /dev/null +++ b/e2e/fixtures/javascript.transform.amd/src/index.ts @@ -0,0 +1,6 @@ +// @ts-ignore +import a from './a' + +it("amd/umd should be exports as commonjs", () => { + expect(a).toEqual(1) +});