diff --git a/crates/mako/src/transform_in_generate.rs b/crates/mako/src/transform_in_generate.rs index fa09203cc..671c4b1fb 100644 --- a/crates/mako/src/transform_in_generate.rs +++ b/crates/mako/src/transform_in_generate.rs @@ -27,6 +27,7 @@ use crate::swc_helpers::SwcHelpers; use crate::targets; use crate::transformers::transform_async_module::AsyncModule; use crate::transformers::transform_css_handler::CssHandler; +use crate::transformers::transform_css_import_remover::CssImportRemover; use crate::transformers::transform_dep_replacer::{DepReplacer, DependenciesToReplace}; use crate::transformers::transform_dynamic_import::DynamicImport; use crate::transformers::transform_mako_require::MakoRequire; @@ -273,6 +274,12 @@ pub fn transform_js_generate(transform_js_param: TransformJsParam) -> Result<()> }; ast.ast.visit_mut_with(&mut dep_replacer); + ast.ast.visit_mut_with(&mut CssImportRemover { + context, + module_id, + unresolved_mark, + }); + let mut meta_url_replacer = MetaUrlReplacer {}; ast.ast.visit_mut_with(&mut meta_url_replacer); diff --git a/crates/mako/src/transformers/mod.rs b/crates/mako/src/transformers/mod.rs index d66457bdb..131ca337d 100644 --- a/crates/mako/src/transformers/mod.rs +++ b/crates/mako/src/transformers/mod.rs @@ -1,6 +1,7 @@ pub mod transform_async_module; pub mod transform_css_flexbugs; pub mod transform_css_handler; +pub mod transform_css_import_remover; pub mod transform_css_url_replacer; pub mod transform_dep_replacer; pub mod transform_dynamic_import; diff --git a/crates/mako/src/transformers/transform_css_import_remover.rs b/crates/mako/src/transformers/transform_css_import_remover.rs new file mode 100644 index 000000000..e4d15f32b --- /dev/null +++ b/crates/mako/src/transformers/transform_css_import_remover.rs @@ -0,0 +1,79 @@ +use std::sync::Arc; + +use mako_core::swc_common::{Mark, DUMMY_SP}; +use mako_core::swc_ecma_ast::{Expr, ExprOrSpread, Lit}; +use mako_core::swc_ecma_utils::{member_expr, quote_str, ExprFactory}; +use mako_core::swc_ecma_visit::{VisitMut, VisitMutWith}; + +use crate::compiler::Context; +use crate::module::ModuleId; +use crate::plugins::javascript::{is_commonjs_require, is_dynamic_import}; +use crate::task::parse_path; +use crate::transformers::transform_virtual_css_modules::is_css_path; + +pub struct CssImportRemover<'a> { + pub module_id: &'a ModuleId, + pub context: &'a Arc, + pub unresolved_mark: Mark, +} + +impl VisitMut for CssImportRemover<'_> { + fn visit_mut_expr(&mut self, expr: &mut Expr) { + if let Expr::Call(call_expr) = 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; + } + if let ExprOrSpread { + expr: box Expr::Lit(Lit::Str(ref mut source)), + .. + } = &mut call_expr.args[0] + { + let source_string = source.value.clone().to_string(); + + let file_request = parse_path(&source_string).unwrap(); + let is_source_replaceable = is_css_path(&file_request.path) + && (file_request.query.is_empty() || file_request.has_query("modules")); + + if is_source_replaceable { + // remove `require('./xxx.css');` + if is_commonjs_require_flag { + *expr = Expr::Lit(quote_str!("").into()); + return; + } else { + // `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.get_chunk_for_module(&dep_module_id.clone()); + + if let Some(chunk) = chunk { + let chunk_id = chunk.id.id.clone(); + // `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()]); + return; + } else { + *expr = Expr::Lit(quote_str!("").into()); + return; + } + } else { + *expr = Expr::Lit(quote_str!("").into()); + return; + } + } + } + } + } + } + expr.visit_mut_children_with(self); + } +} + +#[cfg(test)] +mod tests {} diff --git a/crates/mako/src/transformers/transform_dep_replacer.rs b/crates/mako/src/transformers/transform_dep_replacer.rs index c1f867d14..f7b491dfd 100644 --- a/crates/mako/src/transformers/transform_dep_replacer.rs +++ b/crates/mako/src/transformers/transform_dep_replacer.rs @@ -13,8 +13,6 @@ use crate::compiler::Context; use crate::module::{Dependency, ModuleId}; use crate::plugins::css::is_url_ignored; use crate::plugins::javascript::{is_commonjs_require, is_dynamic_import}; -use crate::task::parse_path; -use crate::transformers::transform_virtual_css_modules::is_css_path; pub struct DepReplacer<'a> { pub module_id: &'a ModuleId, @@ -108,52 +106,6 @@ impl VisitMut for DepReplacer<'_> { self.replace_source(source); } } - - let is_dep_replaceable = || { - let module_graph = self.context.module_graph.read().unwrap(); - // 必须用 source 来查 dep_module_id , to_replace 数据中的 module id 可能是压缩过的 - let dep_module_id = module_graph - .get_dependency_module_by_source(self.module_id, &source_string); - dep_module_id.map_or(false, |module_id| { - let file_request = parse_path(&module_id.id).unwrap(); - is_css_path(&file_request.path) - && (file_request.query.is_empty() - || file_request.has_query("modules")) - }) - }; - - let file_request = parse_path(&source_string).unwrap(); - let is_source_replaceable = is_css_path(&file_request.path) - && (file_request.query.is_empty() || file_request.has_query("modules")); - - if is_source_replaceable || is_dep_replaceable() { - // remove `require('./xxx.css');` - if is_commonjs_require_flag { - *expr = Expr::Lit(quote_str!("").into()) - } else { - // `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.get_chunk_for_module(&dep_module_id.clone()); - - if let Some(chunk) = chunk { - let chunk_id = chunk.id.id.clone(); - // `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()) - } - } else { - *expr = Expr::Lit(quote_str!("").into()) - } - } - } } } }