Skip to content

Commit

Permalink
refactor: 🎨 add struct ReslvedReplaceInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
stormslowly committed Nov 5, 2024
1 parent d1ef84a commit 7fe969d
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 104 deletions.
62 changes: 31 additions & 31 deletions crates/mako/src/generate/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::utils::thread_pool;
use crate::visitors::async_module::{mark_async, AsyncModule};
use crate::visitors::common_js::common_js;
use crate::visitors::css_imports::CSSImports;
use crate::visitors::dep_replacer::{DepReplacer, DependenciesToReplace};
use crate::visitors::dep_replacer::{DepReplacer, DependenciesToReplace, ResolvedReplaceInfo};
use crate::visitors::dynamic_import::DynamicImport;
use crate::visitors::mako_require::MakoRequire;
use crate::visitors::meta_url_replacer::MetaUrlReplacer;
Expand Down Expand Up @@ -84,36 +84,27 @@ pub fn transform_modules_in_thread(
thread_pool::spawn(move || {
let module_graph = context.module_graph.read().unwrap();
let deps = module_graph.get_dependencies(&module_id);
let mut resolved_deps: HashMap<String, (String, String)> = deps
let mut resolved_deps: HashMap<String, ResolvedReplaceInfo> = deps
.into_iter()
.map(|(id, dep)| {
(
dep.source.clone(),
(
match &dep.resolve_type {
ResolveType::Worker(import_options) => {
let chunk_id = match import_options.get_chunk_name() {
Some(chunk_name) => {
generate_module_id(chunk_name, &context)
}
None => id.generate(&context),
};
let chunk_graph = context.chunk_graph.read().unwrap();
chunk_graph.chunk(&chunk_id.into()).unwrap().filename()
}
ResolveType::DynamicImport(import_options) => {
match import_options.get_chunk_name() {
Some(chunk_name) => {
generate_module_id(chunk_name, &context)
}
None => id.generate(&context),
}
}
_ => id.generate(&context),
},
id.id.clone(),
),
)
let to_replace_source = match &dep.resolve_type {
ResolveType::Worker(import_options) => {
let chunk_id = match import_options.get_chunk_name() {
Some(chunk_name) => generate_module_id(chunk_name, &context),
None => id.generate(&context),
};
let chunk_graph = context.chunk_graph.read().unwrap();
chunk_graph.chunk(&chunk_id.into()).unwrap().filename()
}
_ => id.generate(&context),
};

let resolve_replace_info = ResolvedReplaceInfo {
to_replace_source,
resolved_module_id: id.clone(),
};

(dep.source.clone(), resolve_replace_info)
})
.collect();
insert_swc_helper_replace(&mut resolved_deps, &context);
Expand Down Expand Up @@ -162,10 +153,19 @@ pub fn transform_modules_in_thread(
Ok(())
}

fn insert_swc_helper_replace(map: &mut HashMap<String, (String, String)>, context: &Arc<Context>) {
fn insert_swc_helper_replace(
map: &mut HashMap<String, ResolvedReplaceInfo>,
context: &Arc<Context>,
) {
SWC_HELPERS.into_iter().for_each(|h| {
let m_id: ModuleId = h.to_string().into();
map.insert(m_id.id.clone(), (m_id.generate(context), h.to_string()));
map.insert(
m_id.id.clone(),
ResolvedReplaceInfo {
to_replace_source: m_id.generate(context),
resolved_module_id: m_id,
},
);
});
}

Expand Down
12 changes: 9 additions & 3 deletions crates/mako/src/plugins/bundless_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::compiler::{Args, Context};
use crate::config::Config;
use crate::module::{ModuleAst, ModuleId};
use crate::plugin::{Plugin, PluginTransformJsParam};
use crate::visitors::dep_replacer::{DepReplacer, DependenciesToReplace};
use crate::visitors::dep_replacer::{DepReplacer, DependenciesToReplace, ResolvedReplaceInfo};
use crate::visitors::dynamic_import::DynamicImport;

pub struct BundlessCompiler {
Expand Down Expand Up @@ -80,11 +80,17 @@ impl BundlessCompiler {
}
};

Ok((dep.source.clone(), (replacement.clone(), replacement)))
Ok((
dep.source.clone(),
ResolvedReplaceInfo {
to_replace_source: replacement,
resolved_module_id: id.clone(),
},
))
})
.collect::<Result<Vec<_>>>();

let resolved_deps: HashMap<String, (String, String)> =
let resolved_deps: HashMap<String, ResolvedReplaceInfo> =
resolved_deps?.into_iter().collect();

drop(module_graph);
Expand Down
34 changes: 17 additions & 17 deletions crates/mako/src/visitors/dep_replacer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ pub struct DepReplacer<'a> {
pub unresolved_mark: Mark,
}

type ResolvedModuleId = String;
type ResolvedModulePath = String;
#[derive(Debug, Clone)]
pub struct ResolvedReplaceInfo {
pub to_replace_source: String,
pub resolved_module_id: ModuleId,
}

#[derive(Debug, Clone)]
pub struct DependenciesToReplace {
// resolved stores the "source" maps to (generate_id, raw_module_id)
// e.g. "react" => ("hashed_id", "/abs/to/react/index.js")
pub resolved: HashMap<String, (ResolvedModuleId, ResolvedModulePath)>,
pub resolved: HashMap<String, ResolvedReplaceInfo>,
pub missing: HashMap<String, Dependency>,
}

Expand Down Expand Up @@ -124,8 +127,9 @@ impl VisitMut for DepReplacer<'_> {
// css
// TODO: add testcases for this
let is_replaceable_css =
if let Some((_, raw_id)) = self.to_replace.resolved.get(&source_string) {
let (path, _search, query, _) = parse_path(raw_id).unwrap();
if let Some(replace_info) = self.to_replace.resolved.get(&source_string) {
let (path, _search, query, _) =
parse_path(&replace_info.resolved_module_id.id).unwrap();
// when inline_css is enabled
// css is parsed as js modules
self.context.config.inline_css.is_none()
Expand Down Expand Up @@ -194,7 +198,7 @@ impl VisitMut for DepReplacer<'_> {
impl DepReplacer<'_> {
fn replace_source(&mut self, source: &mut Str) {
if let Some(replacement) = self.to_replace.resolved.get(&source.value.to_string()) {
let module_id = replacement.0.clone();
let module_id = replacement.to_replace_source.clone();
let span = source.span;
*source = Str::from(module_id);
source.span = span;
Expand Down Expand Up @@ -247,7 +251,7 @@ mod tests {
use swc_core::common::GLOBALS;
use swc_core::ecma::visit::VisitMutWith;

use super::{DepReplacer, DependenciesToReplace, ResolvedModuleId, ResolvedModulePath};
use super::{DepReplacer, DependenciesToReplace, ResolvedReplaceInfo};
use crate::ast::tests::TestUtils;
use crate::module::{Dependency, ImportType, ModuleId, ResolveType};

Expand Down Expand Up @@ -339,17 +343,13 @@ try {
);
}

fn build_resolved(
key: &str,
module_id: &str,
) -> HashMap<String, (ResolvedModuleId, ResolvedModulePath)> {
fn build_resolved(key: &str, module_id: &str) -> HashMap<String, ResolvedReplaceInfo> {
hashmap! {
key.to_string() =>
(

module_id.to_string(),
"".to_string()
)
ResolvedReplaceInfo {
to_replace_source: module_id.into(),
resolved_module_id: "".into(),
}
}
}

Expand All @@ -367,7 +367,7 @@ try {

fn run(
js_code: &str,
resolved: HashMap<String, (ResolvedModuleId, ResolvedModulePath)>,
resolved: HashMap<String, ResolvedReplaceInfo>,
missing: HashMap<String, Dependency>,
) -> String {
let mut test_utils = TestUtils::gen_js_ast(js_code);
Expand Down
115 changes: 62 additions & 53 deletions crates/mako/src/visitors/dynamic_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::dep_replacer::miss_throw_stmt;
use crate::ast::utils::{is_dynamic_import, promise_all, require_ensure};
use crate::ast::DUMMY_CTXT;
use crate::compiler::Context;
use crate::generate::chunk::ChunkId;
use crate::module::ModuleId;
use crate::visitors::dep_replacer::DependenciesToReplace;

pub struct DynamicImport<'a> {
Expand Down Expand Up @@ -47,14 +47,16 @@ impl<'a> VisitMut for DynamicImport<'a> {
.position(|module_item| !module_item.directive_continue())
.unwrap();

let (id, _) = self
let interop_replace = 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 require_interop = quote_ident!("__mako_require__").as_call(
DUMMY_SP,
vec![quote_str!(interop_replace.to_replace_source.clone()).as_arg()],
);

let stmt: Stmt = Expr::Member(MemberExpr {
span: DUMMY_SP,
Expand All @@ -74,7 +76,6 @@ impl<'a> VisitMut for DynamicImport<'a> {
if call_expr.args.is_empty() {
return;
}

if let ExprOrSpread {
expr: box Expr::Lit(Lit::Str(ref mut source)),
..
Expand Down Expand Up @@ -106,60 +107,28 @@ impl<'a> VisitMut for DynamicImport<'a> {
// it must be resolved, so unwrap is safe here.
.unwrap();

let resolved_source = &resolved_info.0;
let _chunk_ids = {
let chunk_id: ChunkId = resolved_source.clone().into();
let chunk_graph = &self.context.chunk_graph.read().unwrap();
let chunk = chunk_graph.chunk(&chunk_id);
let chunk_ids = match chunk {
Some(chunk) => {
[
chunk_graph.sync_dependencies_chunk(&chunk.id),
vec![chunk.id.clone()],
]
.concat()
.iter()
.filter_map(|chunk_id| {
// skip empty chunk because it will not be generated
if chunk_graph
.chunk(chunk_id)
.is_some_and(|c| !c.modules.is_empty())
{
Some(chunk_id.id.clone())
} else {
None
}
})
.collect::<Vec<_>>()
}
// None means the original chunk has been optimized to entry chunk
None => vec![],
};
chunk_ids
};

self.changed = true;
// build new expr
// e.g.
// Promise.all([ require.ensure("id") ]).then(require.bind(require, "id"))
// Promise.all([ require.ensure("d1"), require.ensure("id)]).then(require.bind(require, "id"))

// version 2
// require.ensure2("id").then(require.bind(require,"id"))

let generated_module_id = resolved_info.to_replace_source.clone();
*expr = {
// let load_promise = self.make_load_promise(&chunk_ids);
let load_promise = self.make_load_promise_2(resolved_source);

let load_promise = if self.context.args.watch
&& self.context.config.experimental.central_ensure
{
self.central_ensure(&generated_module_id)
} else {
self.inline_ensure(&resolved_info.resolved_module_id, &self.context)
};

let lazy_require_call =
member_expr!(DUMMY_CTXT, DUMMY_SP, __mako_require__.bind).as_call(
DUMMY_SP,
vec![
quote_ident!("__mako_require__").as_arg(),
quote_str!(resolved_source.clone()).as_arg(),
quote_str!(generated_module_id).as_arg(),
],
);

let dr_call = member_expr!(DUMMY_CTXT, DUMMY_SP, __mako_require__.dr)
.as_call(
DUMMY_SP,
Expand All @@ -177,12 +146,47 @@ impl<'a> VisitMut for DynamicImport<'a> {
}

impl DynamicImport<'_> {
fn make_load_promise_2(&self, module_id: &str) -> Expr {
// require.ensure2("id").then(require.bind(require,"id"))
fn central_ensure(&self, module_id: &str) -> Expr {
member_expr!(DUMMY_CTXT, DUMMY_SP, __mako_require__.ensure2)
.as_call(DUMMY_SP, vec![quote_str!(module_id).as_arg()])
}

fn make_load_promise(&self, chunk_ids: &[String]) -> Expr {
// build the Promise.all([...]) part
// Promise.all([ require.ensure("id") ]).then(require.bind(require, "id"))
// Promise.all([ require.ensure("d1"), require.ensure("id)]).then(require.bind(require, "id"))
fn inline_ensure(&self, module_id: &ModuleId, context: &Arc<Context>) -> Expr {
let chunk_graph = context.chunk_graph.read().unwrap();

let chunk_ids = {
let chunk = chunk_graph.get_chunk_for_module(module_id);
let chunk_ids = match chunk {
Some(chunk) => {
[
chunk_graph.sync_dependencies_chunk(&chunk.id),
vec![chunk.id.clone()],
]
.concat()
.iter()
.filter_map(|chunk_id| {
// skip empty chunk because it will not be generated
if chunk_graph
.chunk(chunk_id)
.is_some_and(|c| !c.modules.is_empty())
{
Some(chunk_id.id.clone())
} else {
None
}
})
.collect::<Vec<_>>()
}
// None means the original chunk has been optimized to entry chunk
None => vec![],
};
chunk_ids
};

let to_ensure_elems = chunk_ids
.iter()
.map(|c_id| {
Expand Down Expand Up @@ -213,7 +217,7 @@ mod tests {
use super::DynamicImport;
use crate::ast::tests::TestUtils;
use crate::generate::chunk::{Chunk, ChunkType};
use crate::visitors::dep_replacer::DependenciesToReplace;
use crate::visitors::dep_replacer::{DependenciesToReplace, ResolvedReplaceInfo};

// TODO: add nested chunk test
#[test]
Expand Down Expand Up @@ -242,9 +246,14 @@ Promise.all([

let dep_to_replace = DependenciesToReplace {
resolved: maplit::hashmap! {
"@swc/helpers/_/_interop_require_wildcard".to_string() =>
("hashed_helper".to_string(), "dummy".into()),
"foo".to_string() => ("foo".to_string(), "foo".to_string())
"@swc/helpers/_/_interop_require_wildcard".to_string() => ResolvedReplaceInfo {
to_replace_source: "hashed_helper".to_string(),
resolved_module_id:"dummy".into()
},
"foo".to_string() => ResolvedReplaceInfo {
to_replace_source: "foo".into(),
resolved_module_id: "foo".into()
}
},
missing: HashMap::new(),
};
Expand Down

0 comments on commit 7fe969d

Please sign in to comment.