From 3766736182bd33064d5af58d3fed450f6cf6be98 Mon Sep 17 00:00:00 2001 From: Jess Date: Wed, 6 Dec 2023 20:07:13 +0800 Subject: [PATCH 1/2] fix: fix dynamic import css --- .../transformers/transform_dep_replacer.rs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/crates/mako/src/transformers/transform_dep_replacer.rs b/crates/mako/src/transformers/transform_dep_replacer.rs index 38c50a67f..8468a9cad 100644 --- a/crates/mako/src/transformers/transform_dep_replacer.rs +++ b/crates/mako/src/transformers/transform_dep_replacer.rs @@ -3,8 +3,8 @@ use std::sync::Arc; use mako_core::swc_common::{Mark, DUMMY_SP}; use mako_core::swc_ecma_ast::{ - AssignOp, BlockStmt, Expr, ExprOrSpread, FnExpr, Function, Ident, ImportDecl, Lit, NamedExport, - NewExpr, Stmt, Str, ThrowStmt, VarDeclKind, + AssignOp, BlockStmt, CallExpr, Callee, Expr, ExprOrSpread, FnExpr, Function, Ident, ImportDecl, + Lit, NamedExport, NewExpr, Stmt, Str, ThrowStmt, VarDeclKind, }; use mako_core::swc_ecma_utils::{member_expr, quote_ident, quote_str, ExprFactory}; use mako_core::swc_ecma_visit::{VisitMut, VisitMutWith}; @@ -107,12 +107,41 @@ impl VisitMut for DepReplacer<'_> { } } - // remove `require('./xxx.css');` let file_request = parse_path(&source_string).unwrap(); if is_css_path(&file_request.path) && (file_request.query.is_empty() || file_request.has_query("modules")) { - *expr = Expr::Lit(quote_str!("").into()) + // remove `require('./xxx.css');` + if is_commonjs_require(call_expr, &self.unresolved_mark) { + *expr = Expr::Lit(quote_str!("").into()) + } else { + // `import('./xxx.css')` => ensure css chunk + let module_id = self.to_replace.resolved.get(&source_string); + if let Some(module_id) = module_id { + let chunk_graph = self.context.chunk_graph.read().unwrap(); + let chunk = chunk_graph.chunk(&module_id.clone().into()); + + if let Some(chunk) = chunk { + let chunk_id = chunk.id.generate(self.context); + *expr = Expr::Call(CallExpr { + span: DUMMY_SP, + type_args: None, + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(Expr::Lit(quote_str!(chunk_id).into())), + }], + callee: Callee::Expr(member_expr!( + DUMMY_SP, + __mako_require__.ensure + )), + }); + } else { + *expr = Expr::Lit(quote_str!("").into()) + } + } else { + *expr = Expr::Lit(quote_str!("").into()) + } + } } } } From e85d6a8fd287eca138e8ddc7584e826091d11cd9 Mon Sep 17 00:00:00 2001 From: Jess Date: Wed, 6 Dec 2023 23:16:33 +0800 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=E6=94=B9=E7=94=A8=20`get=5Fdep?= =?UTF-8?q?endency=5Fmodule=5Fby=5Fsource`=20=E8=8E=B7=E5=8F=96=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E6=A8=A1=E5=9D=97=E7=9A=84=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/mako/src/plugins/bundless_compiler.rs | 3 +- crates/mako/src/plugins/runtime.rs | 2 +- crates/mako/src/transform.rs | 2 +- crates/mako/src/transform_in_generate.rs | 7 +-- .../transformers/transform_dep_replacer.rs | 49 ++++++++++--------- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/crates/mako/src/plugins/bundless_compiler.rs b/crates/mako/src/plugins/bundless_compiler.rs index c8130e979..c068c1291 100644 --- a/crates/mako/src/plugins/bundless_compiler.rs +++ b/crates/mako/src/plugins/bundless_compiler.rs @@ -188,7 +188,7 @@ pub fn transform_modules(module_ids: Vec, context: &Arc) -> R } pub fn transform_js_generate( - _id: &ModuleId, + module_id: &ModuleId, context: &Arc, ast: &mut Ast, dep_map: &DependenciesToReplace, @@ -227,6 +227,7 @@ pub fn transform_js_generate( // ast.ast.visit_mut_with(&mut inject_helpers(unresolved_mark)); let mut dep_replacer = DepReplacer { + module_id, to_replace: dep_map, context, unresolved_mark: ast.unresolved_mark, diff --git a/crates/mako/src/plugins/runtime.rs b/crates/mako/src/plugins/runtime.rs index 723f04642..3389a5f46 100644 --- a/crates/mako/src/plugins/runtime.rs +++ b/crates/mako/src/plugins/runtime.rs @@ -159,7 +159,7 @@ impl MakoRuntime { ignored: vec![], }, async_deps: &Vec::::new(), - _id: &module_id, + module_id: &module_id, context, ast: &mut ast, })?; diff --git a/crates/mako/src/transform.rs b/crates/mako/src/transform.rs index 8103693a3..e3db456fc 100644 --- a/crates/mako/src/transform.rs +++ b/crates/mako/src/transform.rs @@ -788,7 +788,7 @@ const require = window.require; ) .unwrap(); transform_js_generate(TransformJsParam { - _id: &ModuleId::new("test".to_string()), + module_id: &ModuleId::new("test".to_string()), context: &context, ast: &mut ast, dep_map: &DependenciesToReplace { diff --git a/crates/mako/src/transform_in_generate.rs b/crates/mako/src/transform_in_generate.rs index 68c1f2bf1..9cbf438b8 100644 --- a/crates/mako/src/transform_in_generate.rs +++ b/crates/mako/src/transform_in_generate.rs @@ -125,7 +125,7 @@ pub fn transform_modules_in_thread( }; if let ModuleAst::Script(ast) = ast { let ret = transform_js_generate(TransformJsParam { - _id: &module.id, + module_id: &module.id, context: &context, ast, dep_map: &deps_to_replace, @@ -173,7 +173,7 @@ fn insert_swc_helper_replace(map: &mut HashMap, context: &Arc { - pub _id: &'a ModuleId, + pub module_id: &'a ModuleId, pub context: &'a Arc, pub ast: &'a mut Ast, pub dep_map: &'a DependenciesToReplace, @@ -185,7 +185,7 @@ pub struct TransformJsParam<'a> { pub fn transform_js_generate(transform_js_param: TransformJsParam) -> Result<()> { mako_core::mako_profile_function!(); let TransformJsParam { - _id, + module_id, context, ast, dep_map, @@ -246,6 +246,7 @@ pub fn transform_js_generate(transform_js_param: TransformJsParam) -> Result<()> } let mut dep_replacer = DepReplacer { + module_id, to_replace: dep_map, context, unresolved_mark, diff --git a/crates/mako/src/transformers/transform_dep_replacer.rs b/crates/mako/src/transformers/transform_dep_replacer.rs index 8468a9cad..8a44a8aab 100644 --- a/crates/mako/src/transformers/transform_dep_replacer.rs +++ b/crates/mako/src/transformers/transform_dep_replacer.rs @@ -3,20 +3,21 @@ use std::sync::Arc; use mako_core::swc_common::{Mark, DUMMY_SP}; use mako_core::swc_ecma_ast::{ - AssignOp, BlockStmt, CallExpr, Callee, Expr, ExprOrSpread, FnExpr, Function, Ident, ImportDecl, - Lit, NamedExport, NewExpr, Stmt, Str, ThrowStmt, VarDeclKind, + AssignOp, BlockStmt, Expr, ExprOrSpread, FnExpr, Function, Ident, ImportDecl, Lit, NamedExport, + NewExpr, Stmt, Str, ThrowStmt, VarDeclKind, }; use mako_core::swc_ecma_utils::{member_expr, quote_ident, quote_str, ExprFactory}; use mako_core::swc_ecma_visit::{VisitMut, VisitMutWith}; use crate::build::parse_path; use crate::compiler::Context; -use crate::module::Dependency; +use crate::module::{Dependency, ModuleId}; use crate::plugins::css::is_url_ignored; use crate::plugins::javascript::{is_commonjs_require, is_dynamic_import}; use crate::transformers::transform_virtual_css_modules::is_css_path; pub struct DepReplacer<'a> { + pub module_id: &'a ModuleId, pub to_replace: &'a DependenciesToReplace, pub context: &'a Arc, pub unresolved_mark: Mark, @@ -83,8 +84,8 @@ pub fn miss_throw_stmt>(source: T) -> Expr { impl VisitMut for DepReplacer<'_> { fn visit_mut_expr(&mut self, expr: &mut Expr) { if let Expr::Call(call_expr) = expr { - if is_commonjs_require(call_expr, &self.unresolved_mark) || is_dynamic_import(call_expr) - { + let is_commonjs_require_flag = is_commonjs_require(call_expr, &self.unresolved_mark); + if is_commonjs_require_flag || is_dynamic_import(call_expr) { if call_expr.args.is_empty() { return; } @@ -112,29 +113,24 @@ impl VisitMut for DepReplacer<'_> { && (file_request.query.is_empty() || file_request.has_query("modules")) { // remove `require('./xxx.css');` - if is_commonjs_require(call_expr, &self.unresolved_mark) { + if is_commonjs_require_flag { *expr = Expr::Lit(quote_str!("").into()) } else { - // `import('./xxx.css')` => ensure css chunk - let module_id = self.to_replace.resolved.get(&source_string); - if let Some(module_id) = module_id { + // `import('./xxx.css')` 中的 css 模块会被拆分到单独的 chunk, 这里需要改为加载 css chunk + let module_graph = self.context.module_graph.read().unwrap(); + let dep_module_id = module_graph + .get_dependency_module_by_source(self.module_id, &source_string); + + if let Some(dep_module_id) = dep_module_id { let chunk_graph = self.context.chunk_graph.read().unwrap(); - let chunk = chunk_graph.chunk(&module_id.clone().into()); + let chunk = + chunk_graph.get_chunk_for_module(&dep_module_id.clone()); if let Some(chunk) = chunk { let chunk_id = chunk.id.generate(self.context); - *expr = Expr::Call(CallExpr { - span: DUMMY_SP, - type_args: None, - args: vec![ExprOrSpread { - spread: None, - expr: Box::new(Expr::Lit(quote_str!(chunk_id).into())), - }], - callee: Callee::Expr(member_expr!( - DUMMY_SP, - __mako_require__.ensure - )), - }); + // `import('./xxx.css')` => `__mako_require__.ensure('./xxx.css')` + *expr = member_expr!(DUMMY_SP, __mako_require__.ensure) + .as_call(DUMMY_SP, vec![quote_str!(chunk_id).as_arg()]); } else { *expr = Expr::Lit(quote_str!("").into()) } @@ -234,7 +230,7 @@ mod tests { use crate::assert_display_snapshot; use crate::ast::build_js_ast; use crate::compiler::Context; - use crate::module::{Dependency, ResolveType}; + use crate::module::{Dependency, ModuleId, ResolveType}; use crate::test_helper::transform_ast_with; use crate::transformers::test_helper::transform_js_code; use crate::transformers::transform_dep_replacer::{DepReplacer, DependenciesToReplace}; @@ -255,9 +251,11 @@ mod tests { }; let cloned = context.clone(); + let module_id = ModuleId::new("index.jsx".to_string()); let mut visitor: Box = Box::new(chain!( resolver(ast.unresolved_mark, ast.top_level_mark, false), DepReplacer { + module_id: &module_id, to_replace: &to_replace, context: &cloned, unresolved_mark: ast.unresolved_mark, @@ -290,9 +288,11 @@ mod tests { }; let cloned = context.clone(); + let module_id = ModuleId::new("index.jsx".to_string()); let mut visitor: Box = Box::new(chain!( resolver(ast.unresolved_mark, ast.top_level_mark, false), DepReplacer { + module_id: &module_id, to_replace: &to_replace, context: &cloned, unresolved_mark: ast.unresolved_mark, @@ -334,9 +334,11 @@ mod tests { }; let cloned = context.clone(); + let module_id = ModuleId::new("index.jsx".to_string()); let mut visitor: Box = Box::new(chain!( resolver(ast.unresolved_mark, ast.top_level_mark, false), DepReplacer { + module_id: &module_id, to_replace: &to_replace, context: &cloned, unresolved_mark: ast.unresolved_mark, @@ -372,6 +374,7 @@ mod tests { let unresolved_mark = Default::default(); let top_level_mark = Default::default(); let mut visitor = DepReplacer { + module_id: &ModuleId::new("index.jsx".into()), to_replace: &DependenciesToReplace { resolved: hashmap! { "x".to_string() => "/x/index.js".to_string()