diff --git a/crates/mako/src/generate/transform.rs b/crates/mako/src/generate/transform.rs index acf4786dd..a6706a1ed 100644 --- a/crates/mako/src/generate/transform.rs +++ b/crates/mako/src/generate/transform.rs @@ -240,7 +240,9 @@ pub fn transform_js_generate(transform_js_param: TransformJsParam) -> Result<()> let mut meta_url_replacer = MetaUrlReplacer {}; ast.ast.visit_mut_with(&mut meta_url_replacer); - let mut dynamic_import = DynamicImport::new(context.clone(), dep_map); + let mut dynamic_import = DynamicImport { + context: context.clone(), + }; ast.ast.visit_mut_with(&mut dynamic_import); // replace require to __mako_require__ diff --git a/crates/mako/src/plugins/bundless_compiler.rs b/crates/mako/src/plugins/bundless_compiler.rs index 413efc855..f8722042e 100644 --- a/crates/mako/src/plugins/bundless_compiler.rs +++ b/crates/mako/src/plugins/bundless_compiler.rs @@ -236,7 +236,9 @@ fn transform_js_generate( }; ast.ast.visit_mut_with(&mut dep_replacer); - let mut dynamic_import = DynamicImport::new(context.clone(), dep_map); + let mut dynamic_import = DynamicImport { + context: context.clone(), + }; ast.ast.visit_mut_with(&mut dynamic_import); ast.ast diff --git a/crates/mako/src/plugins/context_module.rs b/crates/mako/src/plugins/context_module.rs index 0a10c7750..e9c021a09 100644 --- a/crates/mako/src/plugins/context_module.rs +++ b/crates/mako/src/plugins/context_module.rs @@ -166,7 +166,7 @@ impl VisitMut for ContextModuleVisitor { .as_callee(); // TODO: allow use await in args // eg: import(`./i18n${await xxx()}`) - expr.args = vec![member_expr!(DUMMY_SP, m.default) + expr.args = vec![quote_ident!("m") .as_call(DUMMY_SP, expr.args.clone()) .as_expr() .to_owned() diff --git a/crates/mako/src/visitors/dynamic_import.rs b/crates/mako/src/visitors/dynamic_import.rs index 8db3fa1a4..1d70b0806 100644 --- a/crates/mako/src/visitors/dynamic_import.rs +++ b/crates/mako/src/visitors/dynamic_import.rs @@ -1,74 +1,20 @@ use std::sync::Arc; use mako_core::swc_common::DUMMY_SP; -use mako_core::swc_ecma_ast::{ArrayLit, Expr, ExprOrSpread, Lit, MemberExpr}; +use mako_core::swc_ecma_ast::{ArrayLit, Expr, ExprOrSpread, Lit}; use mako_core::swc_ecma_visit::{VisitMut, VisitMutWith}; -use swc_core::ecma::ast::{Ident, Module, Stmt, VarDeclKind}; -use swc_core::ecma::utils::{ - member_expr, private_ident, quote_ident, quote_str, ExprFactory, IsDirective, -}; -use crate::ast::utils::{is_dynamic_import, member_call, member_prop, promise_all, require_ensure}; +use crate::ast::utils::{ + id, is_dynamic_import, member_call, member_prop, promise_all, require_ensure, +}; use crate::compiler::Context; use crate::generate::chunk::ChunkId; -use crate::visitors::dep_replacer::DependenciesToReplace; -pub struct DynamicImport<'a> { +pub struct DynamicImport { pub context: Arc, - interop: Ident, - changed: bool, - dep_to_replace: &'a DependenciesToReplace, -} - -impl<'a> DynamicImport<'a> { - pub fn new(context: Arc, dep_map: &'a DependenciesToReplace) -> Self { - let interop = private_ident!("interop"); - - Self { - context, - interop, - changed: false, - dep_to_replace: dep_map, - } - } } -impl<'a> VisitMut for DynamicImport<'a> { - fn visit_mut_module(&mut self, n: &mut Module) { - n.visit_mut_children_with(self); - - if self.changed { - let insert_at = n - .body - .iter() - .position(|module_item| { - !module_item - .as_stmt() - .map_or(false, |stmt| stmt.is_directive()) - }) - .unwrap(); - - let (id, _) = self - .dep_to_replace - .resolved - .get("@swc/helpers/_/_interop_require_wildcard") - .unwrap(); - - let require_interop = quote_ident!("__mako_require__") - .as_call(DUMMY_SP, vec![quote_str!(id.clone()).as_arg()]); - - let stmt: Stmt = Expr::Member(MemberExpr { - span: DUMMY_SP, - obj: require_interop.into(), - prop: quote_ident!("_").into(), - }) - .into_var_decl(VarDeclKind::Var, self.interop.clone().into()) - .into(); - - n.body.insert(insert_at, stmt.into()); - } - } - +impl VisitMut for DynamicImport { fn visit_mut_expr(&mut self, expr: &mut Expr) { if let Expr::Call(call_expr) = expr { if is_dynamic_import(call_expr) { @@ -113,7 +59,6 @@ impl<'a> VisitMut for DynamicImport<'a> { chunk_ids }; - self.changed = true; // build new expr // e.g. // Promise.all([ require.ensure("id") ]).then(require.bind(require, "id")) @@ -135,24 +80,26 @@ impl<'a> VisitMut for DynamicImport<'a> { elems: to_ensure_elems, })), }); - - let require_call = member_expr!(DUMMY_SP, __mako_require__.dr).as_call( - DUMMY_SP, + let require_call = member_call( + Expr::Ident(id("__mako_require__")), + member_prop("bind"), vec![ - self.interop.clone().as_arg(), + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(id("__mako_require__"))), + }, ExprOrSpread { spread: None, expr: Box::new(Expr::Lit(Lit::Str(resolved_source.into()))), }, ], ); - member_call( load_promise, member_prop("then"), vec![ExprOrSpread { spread: None, - expr: require_call.into(), + expr: Box::new(require_call), }], ) }; @@ -165,15 +112,12 @@ impl<'a> VisitMut for DynamicImport<'a> { #[cfg(test)] mod tests { - use std::collections::HashMap; - use mako_core::swc_common::GLOBALS; use mako_core::swc_ecma_visit::VisitMutWith; use super::DynamicImport; use crate::ast::tests::TestUtils; use crate::generate::chunk::{Chunk, ChunkType}; - use crate::visitors::dep_replacer::DependenciesToReplace; // TODO: add nested chunk test #[test] @@ -181,10 +125,9 @@ mod tests { assert_eq!( run(r#"import("foo");"#), r#" -var interop = __mako_require__("hashed_helper")._; Promise.all([ __mako_require__.ensure("foo") -]).then(__mako_require__.dr(interop, "foo")); +]).then(__mako_require__.bind(__mako_require__, "foo")); "# .trim() ); @@ -199,17 +142,10 @@ Promise.all([ cg.add_chunk(foo); } let ast = test_utils.ast.js_mut(); - - let dep_to_replace = DependenciesToReplace { - resolved: maplit::hashmap! { - "@swc/helpers/_/_interop_require_wildcard".to_string() => - ("hashed_helper".to_string(), "dummy".into()) - }, - missing: HashMap::new(), - }; - GLOBALS.set(&test_utils.context.meta.script.globals, || { - let mut visitor = DynamicImport::new(test_utils.context.clone(), &dep_to_replace); + let mut visitor = DynamicImport { + context: test_utils.context.clone(), + }; ast.ast.visit_mut_with(&mut visitor); }); let code = test_utils.js_ast_to_code(); diff --git a/crates/mako/templates/app_runtime.stpl b/crates/mako/templates/app_runtime.stpl index 579e0ee79..12edcc080 100644 --- a/crates/mako/templates/app_runtime.stpl +++ b/crates/mako/templates/app_runtime.stpl @@ -59,11 +59,6 @@ function createRuntime(makoModules, entryModuleId, global) { }); }; requireModule.d = Object.defineProperty.bind(Object); - requireModule.dr = function(interop, request) { - return function(){ - return interop(requireModule(request)); - } - }; <% if has_dynamic_chunks || has_hmr { %> /* mako/runtime/ensure chunk */ diff --git a/e2e/fixtures/javascript.require-dynamic/expect.js b/e2e/fixtures/javascript.require-dynamic/expect.js index 5aff33c90..03a76b9ce 100644 --- a/e2e/fixtures/javascript.require-dynamic/expect.js +++ b/e2e/fixtures/javascript.require-dynamic/expect.js @@ -37,7 +37,7 @@ assert.match( assert.match( asyncContent, - moduleReg("src/i18n\\?context&glob=\\*\\*/\\*.json&async", "'./zh-CN.json': ()=>Promise.all([\n.*__mako_require__.ensure(\"src/i18n/zh-CN.json\")\n.*]).then(__mako_require__.dr(interop, \"src/i18n/zh-CN.json\"))", true), + moduleReg("src/i18n\\?context&glob=\\*\\*/\\*.json&async", "'./zh-CN.json': ()=>Promise.all([\n.*__mako_require__.ensure(\"src/i18n/zh-CN.json\")\n.*]).then(__mako_require__.bind(__mako_require__, \"src/i18n/zh-CN.json\"))", true), "should generate context module with correct map in async chunk", ); @@ -49,7 +49,7 @@ assert.match( assert.match( asyncContent, - moduleReg("src/i18n\\?context&glob=\\*\\*/\\*.json&async", "'./en-US.json': ()=>Promise.all([\n.*__mako_require__.ensure(\"src/i18n/en-US.json\")\n.*]).then(__mako_require__.dr(interop, \"src/i18n/en-US.json\"))", true), + moduleReg("src/i18n\\?context&glob=\\*\\*/\\*.json&async", "'./en-US.json': ()=>Promise.all([\n.*__mako_require__.ensure(\"src/i18n/en-US.json\")\n.*]).then(__mako_require__.bind(__mako_require__, \"src/i18n/en-US.json\"))", true), "should generate context module with correct map in async chunk", ); diff --git a/e2e/fixtures/javascript.require-dynamic/src/index.ts b/e2e/fixtures/javascript.require-dynamic/src/index.ts index e295a4af7..ab3d50ee6 100644 --- a/e2e/fixtures/javascript.require-dynamic/src/index.ts +++ b/e2e/fixtures/javascript.require-dynamic/src/index.ts @@ -4,9 +4,7 @@ function loadLang(lang) { function loadLangExt(lang, ext) { // nested dynamic require + with then callback - return import(`./i18n/${lang}.${(require(`./ext/${ext}`)).default}`) - - .then(m => m); + return import(`./i18n/${lang}.${(require(`./ext/${ext}`)).default}`).then(m => m); } function loadFile(file) { @@ -17,7 +15,7 @@ function loadFile2(file) { return require('./fake.js/' + file); } -loadLang('zh-CN').then(console.log); -loadLangExt('zh-CN', 'json').then(console.log); +console.log(loadLang('zh-CN')); +console.log(loadLangExt('zh-CN', 'json')); console.log(loadFile('/zh-CN.json')); console.log(loadFile2('a.js')); diff --git a/e2e/fixtures/runtime.dynamic_import_interop/expect.js b/e2e/fixtures/runtime.dynamic_import_interop/expect.js deleted file mode 100644 index 3977891fe..000000000 --- a/e2e/fixtures/runtime.dynamic_import_interop/expect.js +++ /dev/null @@ -1,16 +0,0 @@ -const assert = require("assert"); -const { - parseBuildResult, - moduleReg, - injectSimpleJest, -} = require("../../../scripts/test-utils"); -const { files } = parseBuildResult(__dirname); - -injectSimpleJest(); - -const index = files["index.js"]; - -expect(index).toContain( - 'var interop = __mako_require__("@swc/helpers/_/_interop_require_wildcard")._;', -); -expect(index).toContain('then(__mako_require__.dr(interop, "src/cjs.js"))'); diff --git a/e2e/fixtures/runtime.dynamic_import_interop/index.js b/e2e/fixtures/runtime.dynamic_import_interop/index.js deleted file mode 100644 index fd39b6447..000000000 --- a/e2e/fixtures/runtime.dynamic_import_interop/index.js +++ /dev/null @@ -1,5 +0,0 @@ -it("should interop cjs module with default", async () => { - let cjs = await import("./src/cjs"); - - expect(cjs).toEqual({ default: { foo: 42 }, foo: 42 }); -}); diff --git a/e2e/fixtures/runtime.dynamic_import_interop/mako.config.json b/e2e/fixtures/runtime.dynamic_import_interop/mako.config.json deleted file mode 100644 index 7856f9a68..000000000 --- a/e2e/fixtures/runtime.dynamic_import_interop/mako.config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "optimization": { - "skipModules": false, - "concatenateModules": false - }, - "entry": { - "index": "./index.js" - }, - "moduleIdStrategy": "named" -} diff --git a/e2e/fixtures/runtime.dynamic_import_interop/src/cjs.js b/e2e/fixtures/runtime.dynamic_import_interop/src/cjs.js deleted file mode 100644 index 0417930f1..000000000 --- a/e2e/fixtures/runtime.dynamic_import_interop/src/cjs.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - foo: 42, - default: "ddd", -}; diff --git a/packages/mako/binding.d.ts b/packages/mako/binding.d.ts index 8e93a5f8e..4252f5ef0 100644 --- a/packages/mako/binding.d.ts +++ b/packages/mako/binding.d.ts @@ -3,6 +3,10 @@ /* auto-generated by NAPI-RS */ +export interface TransformOutput { + code: string; + map?: string; +} export interface JsHooks { load?: (filePath: string) => Promise<{ content: string; type: 'css' | 'js' }>; generateEnd?: (data: {