Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] fix: treeshaking & skipmodule should jump the async module #1661

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/examples/*/.umi-production
/client/node_modules
/e2e/*/*/dist
/e2e/**/node_modules
/e2e/fixtures.umi/*/node_modules/.cache
/e2e/fixtures.umi/stable-hash/node_modules
/e2e/fixtures.umi/*/.umi
Expand Down
4 changes: 4 additions & 0 deletions crates/mako/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::ast::file::win_path;
use crate::config::{Config, ModuleIdStrategy, OutputMode};
use crate::generate::chunk_graph::ChunkGraph;
use crate::generate::optimize_chunk::OptimizeChunksInfo;
use crate::module::{Dependency, ModuleId};
use crate::module_graph::ModuleGraph;
use crate::plugin::{Plugin, PluginDriver, PluginGenerateEndParams};
use crate::plugins;
Expand All @@ -32,6 +33,7 @@ pub struct Context {
pub chunk_graph: RwLock<ChunkGraph>,
pub assets_info: Mutex<HashMap<String, String>>,
pub modules_with_missing_deps: RwLock<Vec<String>>,
pub async_deps_map: RwLock<HashMap<ModuleId, Vec<Dependency>>>,
pub config: Config,
pub numeric_ids_map: RwLock<HashMap<String, usize>>,
pub args: Args,
Expand Down Expand Up @@ -125,6 +127,7 @@ impl Default for Context {
module_graph: RwLock::new(ModuleGraph::new()),
chunk_graph: RwLock::new(ChunkGraph::new()),
assets_info: Mutex::new(HashMap::new()),
async_deps_map: RwLock::new(HashMap::new()),
modules_with_missing_deps: RwLock::new(Vec::new()),
meta: Meta::new(),
plugin_driver: Default::default(),
Expand Down Expand Up @@ -360,6 +363,7 @@ impl Compiler {
module_graph: RwLock::new(ModuleGraph::new()),
chunk_graph: RwLock::new(ChunkGraph::new()),
assets_info: Mutex::new(HashMap::new()),
async_deps_map: RwLock::new(HashMap::new()),
modules_with_missing_deps: RwLock::new(Vec::new()),
meta: Meta::new(),
plugin_driver,
Expand Down
20 changes: 3 additions & 17 deletions crates/mako/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ use crate::compiler::{Compiler, Context};
use crate::config::{DevtoolConfig, OutputMode, TreeShakingStrategy};
use crate::dev::update::UpdateResult;
use crate::generate::generate_chunks::{ChunkFile, ChunkFileType};
use crate::module::{Dependency, ModuleId};
use crate::module::ModuleId;
use crate::plugins::bundless_compiler::BundlessCompiler;
use crate::stats::StatsJsonMap;
use crate::utils::base64_encode;
use crate::visitors::async_module::mark_async;

#[derive(Serialize)]
struct ChunksUrlMap {
Expand All @@ -53,18 +52,6 @@ impl Compiler {
Ok(stats)
}

fn mark_async(&self) -> HashMap<ModuleId, Vec<Dependency>> {
let module_ids = {
let module_graph = self.context.module_graph.read().unwrap();
let (mut module_ids, _) = module_graph.toposort();
// start from the leaf nodes, so reverser the sort
module_ids.reverse();
drop(module_graph);
module_ids
};
mark_async(&module_ids, &self.context)
}

pub fn generate(&self) -> Result<StatsJsonMap> {
debug!("generate");
let t_generate = Instant::now();
Expand All @@ -82,8 +69,6 @@ impl Compiler {
debug!("tree_shaking");
let t_tree_shaking = Instant::now();

let async_dep_map = self.mark_async();

// Disable tree shaking in watch mode temporarily
// ref: https://github.com/umijs/mako/issues/396
if !self.context.args.watch {
Expand Down Expand Up @@ -139,7 +124,8 @@ impl Compiler {
// 因为放 chunks 的循环里,一个 module 可能存在于多个 chunk 里,可能会被编译多遍
let t_transform_modules = Instant::now();
debug!("transform all modules");
self.transform_all(async_dep_map)?;
self.transform_all()?;

let t_transform_modules = t_transform_modules.elapsed();

// ensure output dir exists
Expand Down
18 changes: 10 additions & 8 deletions crates/mako/src/generate/transform.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::ops::DerefMut;
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::time::Instant;
Expand Down Expand Up @@ -34,7 +35,7 @@
use crate::visitors::optimize_define_utils::OptimizeDefineUtils;

impl Compiler {
pub fn transform_all(&self, async_deps_map: HashMap<ModuleId, Vec<Dependency>>) -> Result<()> {
pub fn transform_all(&self) -> Result<()> {
let t = Instant::now();
let context = &self.context;
let module_ids = {
Expand All @@ -47,39 +48,40 @@
.collect::<Vec<_>>()
};

transform_modules_in_thread(&module_ids, context, async_deps_map)?;
transform_modules_in_thread(&module_ids, context)?;
debug!(">> transform modules in {}ms", t.elapsed().as_millis());
Ok(())
}
}

pub fn transform_modules(module_ids: Vec<ModuleId>, context: &Arc<Context>) -> Result<()> {
let t = Instant::now();
let async_deps_by_module_id = mark_async(&module_ids, context);
let mut module_graph = context.module_graph.write().unwrap();
mark_async(module_graph.deref_mut(), &module_ids, context);

Check warning on line 60 in crates/mako/src/generate/transform.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/transform.rs#L59-L60

Added lines #L59 - L60 were not covered by tests
Comment on lines +59 to +60
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

建议改进 mark_async 的错误处理

直接使用 write().unwrap() 获取锁可能在锁竞争或毒锁情况下导致程序崩溃。

建议添加适当的错误处理:

-    let mut module_graph = context.module_graph.write().unwrap();
+    let mut module_graph = context.module_graph.write().map_err(|e| {
+        anyhow::anyhow!("获取 module_graph 写锁失败: {}", e)
+    })?;

Committable suggestion was skipped due to low confidence.

debug!(">> mark async in {}ms", t.elapsed().as_millis());
let t = Instant::now();
transform_modules_in_thread(&module_ids, context, async_deps_by_module_id)?;
transform_modules_in_thread(&module_ids, context)?;

Check warning on line 63 in crates/mako/src/generate/transform.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/generate/transform.rs#L63

Added line #L63 was not covered by tests
debug!(">> transform modules in {}ms", t.elapsed().as_millis());
Ok(())
}

pub fn transform_modules_in_thread(
module_ids: &Vec<ModuleId>,
context: &Arc<Context>,
async_deps_by_module_id: HashMap<ModuleId, Vec<Dependency>>,
) -> Result<()> {
crate::mako_profile_function!();

let (rs, rr) = channel::<Result<(ModuleId, ModuleAst)>>();

for module_id in module_ids {
let async_deps_by_module_id = context.async_deps_map.read().unwrap();
let context = context.clone();
let rs = rs.clone();
let module_id = module_id.clone();
let async_deps = async_deps_by_module_id
.get(&module_id)
.expect(&module_id.id)
.clone();
.cloned()
.unwrap_or(vec![]);

Comment on lines +76 to +84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

建议优化异步依赖的获取逻辑

当前实现中有以下几个需要注意的地方:

  1. 使用了 unwrap() 获取读锁,缺少错误处理
  2. 克隆整个依赖向量可能会带来不必要的性能开销

建议改进实现:

-    let async_deps_by_module_id = context.async_deps_map.read().unwrap();
-    let async_deps = async_deps_by_module_id
-        .get(&module_id)
-        .cloned()
-        .unwrap_or(vec![]);
+    let async_deps = context.async_deps_map
+        .read()
+        .map_err(|e| anyhow::anyhow!("获取 async_deps_map 读锁失败: {}", e))?
+        .get(&module_id)
+        .map(|deps| deps.as_slice())
+        .unwrap_or(&[])
+        .to_vec();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let async_deps_by_module_id = context.async_deps_map.read().unwrap();
let context = context.clone();
let rs = rs.clone();
let module_id = module_id.clone();
let async_deps = async_deps_by_module_id
.get(&module_id)
.expect(&module_id.id)
.clone();
.cloned()
.unwrap_or(vec![]);
let context = context.clone();
let rs = rs.clone();
let module_id = module_id.clone();
let async_deps = context.async_deps_map
.read()
.map_err(|e| anyhow::anyhow!("获取 async_deps_map 读锁失败: {}", e))?
.get(&module_id)
.map(|deps| deps.as_slice())
.unwrap_or(&[])
.to_vec();

thread_pool::spawn(move || {
let module_graph = context.module_graph.read().unwrap();
let deps = module_graph.get_dependencies(&module_id);
Expand Down
8 changes: 7 additions & 1 deletion crates/mako/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,13 @@

impl Debug for Module {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "id={}({:?})", self.id.id, self.get_module_type())
write!(

Check warning on line 494 in crates/mako/src/module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/module.rs#L494

Added line #L494 was not covered by tests
f,
"id={}({:?}) is_async={:?}",
self.id.id,
self.get_module_type(),
self.info.as_ref().unwrap().is_async

Check warning on line 499 in crates/mako/src/module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/module.rs#L498-L499

Added lines #L498 - L499 were not covered by tests
)
Comment on lines +494 to +500
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

注意:Debug 实现中存在潜在的 panic 风险

当前的 Debug 实现中使用了 unwrap() 来访问 info 字段,这可能在 infoNone 时导致程序崩溃。虽然在正常情况下 info 应该总是 Some,但为了代码的健壮性,建议使用更安全的方式处理这种情况。

建议修改为以下实现:

-        write!(
-            f,
-            "id={}({:?}) is_async={:?}",
-            self.id.id,
-            self.get_module_type(),
-            self.info.as_ref().unwrap().is_async
-        )
+        write!(
+            f,
+            "id={}({:?}) is_async={:?}",
+            self.id.id,
+            self.get_module_type(),
+            self.info.as_ref().map_or(false, |info| info.is_async)
+        )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
write!(
f,
"id={}({:?}) is_async={:?}",
self.id.id,
self.get_module_type(),
self.info.as_ref().unwrap().is_async
)
write!(
f,
"id={}({:?}) is_async={:?}",
self.id.id,
self.get_module_type(),
self.info.as_ref().map_or(false, |info| info.is_async)
)

}
}

Expand Down
14 changes: 11 additions & 3 deletions crates/mako/src/plugins/tree_shaking/shake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,33 @@
use crate::plugins::tree_shaking::shake::module_concatenate::optimize_module_graph;
use crate::plugins::tree_shaking::statement_graph::{ExportInfo, ExportSpecifierInfo, ImportInfo};
use crate::plugins::tree_shaking::{module, remove_useless_stmts, statement_graph};
use crate::visitors::async_module::mark_async;
use crate::{mako_profile_function, mako_profile_scope};

type TreeShakingModuleMap = HashMap<ModuleId, RefCell<TreeShakeModule>>;

pub fn optimize_modules(module_graph: &mut ModuleGraph, context: &Arc<Context>) -> Result<()> {
let module_ids = {
let (mut module_ids, _) = module_graph.toposort();
// start from the leaf nodes, so reverser the sort
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

修正注释中的拼写错误

注释中“reverser”应为“reverse”,请修正拼写错误。

建议修改为:

- // start from the leaf nodes, so reverser the sort
+ // start from the leaf nodes, so reverse the sort
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// start from the leaf nodes, so reverser the sort
// start from the leaf nodes, so reverse the sort

module_ids.reverse();
module_ids
};
mark_async(module_graph, &module_ids, context);
let (topo_sorted_modules, _cyclic_modules) = {
mako_profile_scope!("tree shake topo-sort");
module_graph.toposort()
};

let (_skipped, tree_shake_modules_ids): (Vec<ModuleId>, Vec<ModuleId>) =
topo_sorted_modules.into_iter().partition(|module_id| {
let module = module_graph.get_module(module_id).unwrap();

let module_type = module.get_module_type();

// skip non script modules and external modules
if module_type != ModuleType::Script || module.is_external() {
if module_type != ModuleType::Script && !module.is_external() {
let is_async = &module.info.as_ref().unwrap().is_async;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

避免使用可能导致崩溃的 unwrap()

使用 unwrap() 可能会在 module.infoNone 时导致程序崩溃。建议处理 Option 类型以提高代码的健壮性。

可以考虑修改为:

-let is_async = &module.info.as_ref().unwrap().is_async;
+let is_async = module.info.as_ref().map_or(&false, |info| &info.is_async);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let is_async = &module.info.as_ref().unwrap().is_async;
let is_async = module.info.as_ref().map_or(&false, |info| &info.is_async);

if module_type != ModuleType::Script || module.is_external() || *is_async {
if module_type != ModuleType::Script && !module.is_external() || *is_async {

Check warning on line 50 in crates/mako/src/plugins/tree_shaking/shake.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/plugins/tree_shaking/shake.rs#L50

Added line #L50 was not covered by tests
// mark all non script modules' script dependencies as side_effects
for dep_id in module_graph.dependence_module_ids(module_id) {
let dep_module = module_graph.get_module_mut(&dep_id).unwrap();
Expand Down
1 change: 0 additions & 1 deletion crates/mako/src/plugins/tree_shaking/shake/skip_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,6 @@ pub(super) fn skip_module_optimize(
if module_graph.has_module(module_id) {
// stmt_id is reversed order
for to_replace in replaces.iter() {
// println!("{} apply with {:?}", module_id.id, to_replace.1);
apply_replace(to_replace, module_id, module_graph, context);
}

Expand Down
92 changes: 62 additions & 30 deletions crates/mako/src/visitors/async_module.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{HashSet, VecDeque};
use std::sync::Arc;

use swc_core::common::util::take::Take;
Expand All @@ -14,6 +14,7 @@
use crate::ast::DUMMY_CTXT;
use crate::compiler::Context;
use crate::module::{Dependency, ModuleId};
use crate::module_graph::ModuleGraph;

const ASYNC_IMPORTED_MODULE: &str = "_async__mako_imported_module_";

Expand Down Expand Up @@ -205,30 +206,61 @@
}
}

pub fn mark_async(
module_ids: &[ModuleId],
context: &Arc<Context>,
) -> HashMap<ModuleId, Vec<Dependency>> {
let mut async_deps_by_module_id = HashMap::new();
let mut module_graph = context.module_graph.write().unwrap();
// TODO: 考虑成环的场景
pub fn mark_async(module_graph: &mut ModuleGraph, module_ids: &[ModuleId], context: &Arc<Context>) {
let mut to_visit_queue = module_graph
.modules()
.iter()
.filter_map(|m| {
m.info
.as_ref()
.and_then(|i| if i.is_async { Some(m.id.clone()) } else { None })
})
.collect::<VecDeque<_>>();
let mut visited = HashSet::new();

// polluted async to dependants
while let Some(module_id) = to_visit_queue.pop_front() {
if visited.contains(&module_id) {

Check warning on line 223 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L223

Added line #L223 was not covered by tests
continue;
}

module_graph

Check warning on line 227 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L227

Added line #L227 was not covered by tests
.get_dependents(&module_id)
.iter()
.filter_map(|(dependant, dependency)| {
if !dependency.resolve_type.is_sync_esm() {
return None;

Check warning on line 232 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L230-L232

Added lines #L230 - L232 were not covered by tests
}
if !visited.contains(*dependant) {
Some((*dependant).clone())

Check warning on line 235 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L234-L235

Added lines #L234 - L235 were not covered by tests
} else {
None

Check warning on line 237 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L237

Added line #L237 was not covered by tests
}
})

Check warning on line 239 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L239

Added line #L239 was not covered by tests
.collect::<Vec<_>>()
.iter()
.for_each(|module_id| {
let m = module_graph.get_module_mut(module_id).unwrap();
m.info.as_mut().unwrap().is_async = true;

Check warning on line 244 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L242-L244

Added lines #L242 - L244 were not covered by tests
Comment on lines +243 to +244
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

建议避免在生产代码中使用unwrap()

在第243行,module_graph.get_module_mut(module_id).unwrap()如果找不到对应的模块,将会导致程序崩溃,这在生产环境中是不安全的。建议使用匹配处理Option类型,以安全地处理可能的None情况。

您可以将代码修改为:

-let m = module_graph.get_module_mut(module_id).unwrap();
+if let Some(m) = module_graph.get_module_mut(module_id) {
+    m.info.as_mut().unwrap().is_async = true;
+    // 继续处理
+} else {
+    // 处理未找到模块的情况,例如记录日志或跳过
+    continue;
+}

Committable suggestion was skipped due to low confidence.


to_visit_queue.push_back(module_id.clone());
});

Check warning on line 247 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L246-L247

Added lines #L246 - L247 were not covered by tests

visited.insert(module_id.clone());

Check warning on line 249 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L249

Added line #L249 was not covered by tests
}

Comment on lines +209 to +251
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

发现未更新的mark_async调用

在代码库中发现一处调用尚未更新:

  • crates/mako/src/plugins/tree_shaking/shake.rs 中的调用仍使用旧的签名格式:mark_async(module_graph, &module_ids, context),需要更新为 mark_async(module_graph.deref_mut(), &module_ids, context)
🔗 Analysis chain

确认mark_async函数的所有调用已更新

mark_async函数的签名已更改,增加了module_graph的可变引用参数。请确保代码库中所有对mark_async的调用都已更新,传入了新的参数。

运行以下脚本以查找未更新的mark_async调用:

该脚本将帮助您定位可能遗漏更新的函数调用,以确保新签名在整个代码库中一致使用。


Let me analyze the actual usage and definition of the mark_async function to verify if all calls have been properly updated.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 描述:查找未传入`module_graph`参数的`mark_async`函数调用

# 期望结果:所有调用都包含`module_graph`参数

rg 'mark_async\s*\(\s*module_ids' -A1

Length of output: 39


Script:

#!/bin/bash
# 搜索所有mark_async的调用
rg "mark_async\(" -A 2

# 搜索mark_async函数的定义
ast-grep --pattern 'fn mark_async($$$)'

Length of output: 919

module_ids.iter().for_each(|module_id| {
let deps = module_graph.get_dependencies_info(module_id);
let mut async_deps_map = context.async_deps_map.write().unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

处理写锁获取失败的情况

在第254行,使用了context.async_deps_map.write().unwrap(),如果获取写锁失败(例如发生PoisonError),程序将会崩溃。为了提高代码的健壮性,建议处理可能的错误,提供适当的错误处理逻辑。

您可以将代码修改为:

-let mut async_deps_map = context.async_deps_map.write().unwrap();
+let mut async_deps_map = match context.async_deps_map.write() {
+    Ok(lock) => lock,
+    Err(e) => {
+        // 处理获取锁失败的情况,例如记录错误并返回
+        eprintln!("Failed to acquire write lock: {}", e);
+        return;
+    }
+};

Committable suggestion was skipped due to low confidence.

let async_deps: Vec<Dependency> = deps
.into_iter()
.filter(|(_, dep, is_async)| dep.resolve_type.is_sync_esm() && *is_async)
.map(|(_, dep, _)| dep.clone())
.collect();
let module = module_graph.get_module_mut(module_id).unwrap();
if let Some(info) = module.info.as_mut() {
// a module with async deps need to be polluted into async module
if !info.is_async && !async_deps.is_empty() {
info.is_async = true;
}
async_deps_by_module_id.insert(module_id.clone(), async_deps);
if !async_deps.is_empty() {
async_deps_map.insert(module_id.clone(), async_deps);

Check warning on line 261 in crates/mako/src/visitors/async_module.rs

View check run for this annotation

Codecov / codecov/patch

crates/mako/src/visitors/async_module.rs#L261

Added line #L261 was not covered by tests
}
});
async_deps_by_module_id
}

#[cfg(test)]
Expand All @@ -255,8 +287,8 @@
"#
.trim());
assert_eq!(
code,
r#"
code,
r#"
__mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{
"use strict";
Object.defineProperty(exports, "__esModule", {
Expand All @@ -273,7 +305,7 @@
asyncResult();
}, true);
"#.trim()
);
);
}

#[test]
Expand All @@ -286,8 +318,8 @@
"#
.trim());
assert_eq!(
code,
r#"
code,
r#"
__mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{
"use strict";
Object.defineProperty(exports, "__esModule", {
Expand All @@ -308,8 +340,8 @@
asyncResult();
}, true);
"#
.trim()
);
.trim()
);
}

#[test]
Expand All @@ -321,8 +353,8 @@
"#
.trim());
assert_eq!(
code,
r#"
code,
r#"
__mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{
"use strict";
Object.defineProperty(exports, "__esModule", {
Expand All @@ -340,8 +372,8 @@
asyncResult();
}, true);
"#
.trim()
);
.trim()
);
}

#[test]
Expand Down Expand Up @@ -374,8 +406,8 @@
"#
.trim());
assert_eq!(
code,
r#"
code,
r#"
__mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{
"use strict";
Object.defineProperty(exports, "__esModule", {
Expand All @@ -393,7 +425,7 @@
asyncResult();
}, true);
"#.trim()
);
);
}

fn run(js_code: &str) -> String {
Expand Down
Loading
Loading