From cc6a69ce7249fc9cdd18c050a1d62235f7d01001 Mon Sep 17 00:00:00 2001 From: pshu Date: Fri, 25 Oct 2024 01:11:39 +0800 Subject: [PATCH 1/6] =?UTF-8?q?test:=20=E2=9C=85=20add=20test=20async=20mo?= =?UTF-8?q?dule=20in=20circular=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- e2e/fixtures/javascript.async_module_in_loop/async.js | 11 +++++++++++ .../javascript.async_module_in_loop/component.js | 11 +++++++++++ .../javascript.async_module_in_loop/expect.js | 9 +++++++++ e2e/fixtures/javascript.async_module_in_loop/index.js | 6 ++++++ .../javascript.async_module_in_loop/mako.config.json | 5 +++++ e2e/fixtures/javascript.async_module_in_loop/utils.js | 9 +++++++++ 6 files changed, 51 insertions(+) create mode 100644 e2e/fixtures/javascript.async_module_in_loop/async.js create mode 100644 e2e/fixtures/javascript.async_module_in_loop/component.js create mode 100644 e2e/fixtures/javascript.async_module_in_loop/expect.js create mode 100644 e2e/fixtures/javascript.async_module_in_loop/index.js create mode 100644 e2e/fixtures/javascript.async_module_in_loop/mako.config.json create mode 100644 e2e/fixtures/javascript.async_module_in_loop/utils.js diff --git a/e2e/fixtures/javascript.async_module_in_loop/async.js b/e2e/fixtures/javascript.async_module_in_loop/async.js new file mode 100644 index 000000000..36e73e402 --- /dev/null +++ b/e2e/fixtures/javascript.async_module_in_loop/async.js @@ -0,0 +1,11 @@ +let x = await new Promise((resolve)=>{ + resolve("default") +}) + +let named = await new Promise((resolve)=>{ + resolve("named") +}) + +export default x; + +export {named} diff --git a/e2e/fixtures/javascript.async_module_in_loop/component.js b/e2e/fixtures/javascript.async_module_in_loop/component.js new file mode 100644 index 000000000..dba222359 --- /dev/null +++ b/e2e/fixtures/javascript.async_module_in_loop/component.js @@ -0,0 +1,11 @@ +import { listKeys } from "./utils" + +import { named } from "./async" + +export const config = { + key: "value" +} + +export function displayConfig() { + return listKeys() +} \ No newline at end of file diff --git a/e2e/fixtures/javascript.async_module_in_loop/expect.js b/e2e/fixtures/javascript.async_module_in_loop/expect.js new file mode 100644 index 000000000..50c0ed6f4 --- /dev/null +++ b/e2e/fixtures/javascript.async_module_in_loop/expect.js @@ -0,0 +1,9 @@ +const { + injectSimpleJest, + parseBuildResult, + moduleDefinitionOf, +} = require("../../../scripts/test-utils"); +const { files } = parseBuildResult(__dirname); +injectSimpleJest(); + +require("./dist/index.js"); diff --git a/e2e/fixtures/javascript.async_module_in_loop/index.js b/e2e/fixtures/javascript.async_module_in_loop/index.js new file mode 100644 index 000000000..33413af77 --- /dev/null +++ b/e2e/fixtures/javascript.async_module_in_loop/index.js @@ -0,0 +1,6 @@ +import {displayConfig} from "./component"; + +it("should require looped async moule", () => { + expect(displayConfig()).toStrictEqual(["key"]) +}) + diff --git a/e2e/fixtures/javascript.async_module_in_loop/mako.config.json b/e2e/fixtures/javascript.async_module_in_loop/mako.config.json new file mode 100644 index 000000000..4b0659f7b --- /dev/null +++ b/e2e/fixtures/javascript.async_module_in_loop/mako.config.json @@ -0,0 +1,5 @@ +{ + "entry": { + "index": "./index.js" + } +} diff --git a/e2e/fixtures/javascript.async_module_in_loop/utils.js b/e2e/fixtures/javascript.async_module_in_loop/utils.js new file mode 100644 index 000000000..f13959b5b --- /dev/null +++ b/e2e/fixtures/javascript.async_module_in_loop/utils.js @@ -0,0 +1,9 @@ +import {config} from "./component" + +export function listKeys() { + if(config){ + + return Object.keys(config) + } + return ["oops"] +} \ No newline at end of file From 2156563f3a87c4668bf4d9e067c1110157190ad1 Mon Sep 17 00:00:00 2001 From: pshu Date: Fri, 25 Oct 2024 01:17:39 +0800 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20=F0=9F=8E=A8=20handle=20async?= =?UTF-8?q?=20polution=20by=20traversal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/mako/src/visitors/async_module.rs | 82 +++++++++++++++++------- 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/crates/mako/src/visitors/async_module.rs b/crates/mako/src/visitors/async_module.rs index bde3ce1ee..870085d09 100644 --- a/crates/mako/src/visitors/async_module.rs +++ b/crates/mako/src/visitors/async_module.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet, VecDeque}; use std::sync::Arc; use swc_core::common::util::take::Take; @@ -211,7 +211,49 @@ pub fn mark_async( ) -> HashMap> { let mut async_deps_by_module_id = HashMap::new(); let mut module_graph = context.module_graph.write().unwrap(); - // TODO: 考虑成环的场景 + + 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::>(); + let mut visited = HashSet::new(); + + // polluted async to dependants + while let Some(module_id) = to_visit_queue.pop_front() { + if visited.contains(&module_id) { + continue; + } + + module_graph + .get_dependents(&module_id) + .iter() + .filter_map(|(dependant, dependency)| { + if !dependency.resolve_type.is_sync_esm() { + return None; + } + if !visited.contains(*dependant) { + Some((*dependant).clone()) + } else { + None + } + }) + .collect::>() + .iter() + .for_each(|module_id| { + let m = module_graph.get_module_mut(module_id).unwrap(); + m.info.as_mut().unwrap().is_async = true; + + to_visit_queue.push_back(module_id.clone()); + }); + + visited.insert(module_id.clone()); + } + module_ids.iter().for_each(|module_id| { let deps = module_graph.get_dependencies_info(module_id); let async_deps: Vec = deps @@ -219,15 +261,11 @@ pub fn mark_async( .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; - } + if !async_deps.is_empty() { async_deps_by_module_id.insert(module_id.clone(), async_deps); } }); + async_deps_by_module_id } @@ -255,8 +293,8 @@ add(1, 2); "# .trim()); assert_eq!( - code, - r#" + code, + r#" __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -273,7 +311,7 @@ __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ asyncResult(); }, true); "#.trim() - ); + ); } #[test] @@ -286,8 +324,8 @@ console.log(foo) "# .trim()); assert_eq!( - code, - r#" + code, + r#" __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -308,8 +346,8 @@ __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ asyncResult(); }, true); "# - .trim() - ); + .trim() + ); } #[test] @@ -321,8 +359,8 @@ add(1, 2); "# .trim()); assert_eq!( - code, - r#" + code, + r#" __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -340,8 +378,8 @@ __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ asyncResult(); }, true); "# - .trim() - ); + .trim() + ); } #[test] @@ -374,8 +412,8 @@ const async = require('./miexed_async'); "# .trim()); assert_eq!( - code, - r#" + code, + r#" __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -393,7 +431,7 @@ __mako_require__._async(module, async (handleAsyncDeps, asyncResult)=>{ asyncResult(); }, true); "#.trim() - ); + ); } fn run(js_code: &str) -> String { From 16e8927bde899a1f70dfd4745e953414c4f06cbd Mon Sep 17 00:00:00 2001 From: pshu Date: Fri, 25 Oct 2024 01:40:01 +0800 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20=F0=9F=8E=A8=20use=20default=20?= =?UTF-8?q?over=20expect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/mako/src/generate/transform.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/mako/src/generate/transform.rs b/crates/mako/src/generate/transform.rs index f0ca9c4a8..972740311 100644 --- a/crates/mako/src/generate/transform.rs +++ b/crates/mako/src/generate/transform.rs @@ -78,8 +78,9 @@ pub fn transform_modules_in_thread( 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![]); + thread_pool::spawn(move || { let module_graph = context.module_graph.read().unwrap(); let deps = module_graph.get_dependencies(&module_id); From 193ccecd0e97ce81838597da12dce292d9c19ba4 Mon Sep 17 00:00:00 2001 From: Jinbao1001 Date: Fri, 25 Oct 2024 14:05:12 +0800 Subject: [PATCH 4/6] fix: adjust mark_asyc --- .gitignore | 1 + crates/mako/src/compiler.rs | 4 ++++ crates/mako/src/generate.rs | 19 ++---------------- crates/mako/src/generate/transform.rs | 11 +++++----- crates/mako/src/plugins/tree_shaking/shake.rs | 11 ++++++++++ .../plugins/tree_shaking/shake/skip_module.rs | 1 - crates/mako/src/visitors/async_module.rs | 12 ++++------- e2e/fixtures/tla/mako.config.json | 8 ++++++++ e2e/fixtures/tla/package.json | 6 ++++++ e2e/fixtures/tla/src/index.ts | 8 ++++++++ e2e/fixtures/tla/src/proxy.ts | 2 ++ packages/mako/src/binding.d.ts | 20 +++++++++++++++++++ 12 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 e2e/fixtures/tla/mako.config.json create mode 100644 e2e/fixtures/tla/package.json create mode 100644 e2e/fixtures/tla/src/index.ts create mode 100644 e2e/fixtures/tla/src/proxy.ts diff --git a/.gitignore b/.gitignore index 884cadd0d..f51ee3fc3 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/crates/mako/src/compiler.rs b/crates/mako/src/compiler.rs index 18fab8c70..e2018657a 100644 --- a/crates/mako/src/compiler.rs +++ b/crates/mako/src/compiler.rs @@ -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; @@ -32,6 +33,7 @@ pub struct Context { pub chunk_graph: RwLock, pub assets_info: Mutex>, pub modules_with_missing_deps: RwLock>, + pub async_deps_map: RwLock>>, pub config: Config, pub numeric_ids_map: RwLock>, pub args: Args, @@ -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(), @@ -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, diff --git a/crates/mako/src/generate.rs b/crates/mako/src/generate.rs index d3c454892..2a35b9600 100644 --- a/crates/mako/src/generate.rs +++ b/crates/mako/src/generate.rs @@ -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 { @@ -53,18 +52,6 @@ impl Compiler { Ok(stats) } - fn mark_async(&self) -> HashMap> { - 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 { debug!("generate"); let t_generate = Instant::now(); @@ -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 { @@ -139,7 +124,7 @@ 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 diff --git a/crates/mako/src/generate/transform.rs b/crates/mako/src/generate/transform.rs index f0ca9c4a8..ffc70fc37 100644 --- a/crates/mako/src/generate/transform.rs +++ b/crates/mako/src/generate/transform.rs @@ -34,7 +34,7 @@ use crate::visitors::meta_url_replacer::MetaUrlReplacer; use crate::visitors::optimize_define_utils::OptimizeDefineUtils; impl Compiler { - pub fn transform_all(&self, async_deps_map: HashMap>) -> Result<()> { + pub fn transform_all(&self) -> Result<()> { let t = Instant::now(); let context = &self.context; let module_ids = { @@ -47,7 +47,7 @@ impl Compiler { .collect::>() }; - 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(()) } @@ -55,10 +55,10 @@ impl Compiler { pub fn transform_modules(module_ids: Vec, context: &Arc) -> Result<()> { let t = Instant::now(); - let async_deps_by_module_id = mark_async(&module_ids, context); + mark_async(&module_ids, context); 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)?; debug!(">> transform modules in {}ms", t.elapsed().as_millis()); Ok(()) } @@ -66,12 +66,11 @@ pub fn transform_modules(module_ids: Vec, context: &Arc) -> R pub fn transform_modules_in_thread( module_ids: &Vec, context: &Arc, - async_deps_by_module_id: HashMap>, ) -> Result<()> { crate::mako_profile_function!(); let (rs, rr) = channel::>(); - + let async_deps_by_module_id = context.async_deps_map.read().unwrap(); for module_id in module_ids { let context = context.clone(); let rs = rs.clone(); diff --git a/crates/mako/src/plugins/tree_shaking/shake.rs b/crates/mako/src/plugins/tree_shaking/shake.rs index ecefe1886..e90288ac2 100644 --- a/crates/mako/src/plugins/tree_shaking/shake.rs +++ b/crates/mako/src/plugins/tree_shaking/shake.rs @@ -21,6 +21,7 @@ use crate::plugins::tree_shaking::module::{AllExports, ModuleSystem, TreeShakeMo 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>; @@ -176,6 +177,16 @@ pub fn optimize_modules(module_graph: &mut ModuleGraph, context: &Arc) } } + // mark async should before concatenate && after skip module + + let module_ids = { + let (mut module_ids, _) = module_graph.toposort(); + // start from the leaf nodes, so reverser the sort + module_ids.reverse(); + module_ids + }; + mark_async(&module_ids, context); + if context .config .optimization diff --git a/crates/mako/src/plugins/tree_shaking/shake/skip_module.rs b/crates/mako/src/plugins/tree_shaking/shake/skip_module.rs index 94f2d76ac..5b02a9137 100644 --- a/crates/mako/src/plugins/tree_shaking/shake/skip_module.rs +++ b/crates/mako/src/plugins/tree_shaking/shake/skip_module.rs @@ -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); } diff --git a/crates/mako/src/visitors/async_module.rs b/crates/mako/src/visitors/async_module.rs index bde3ce1ee..345b4e7b8 100644 --- a/crates/mako/src/visitors/async_module.rs +++ b/crates/mako/src/visitors/async_module.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::sync::Arc; use swc_core::common::util::take::Take; @@ -205,11 +204,7 @@ impl VisitMut for AsyncModule<'_> { } } -pub fn mark_async( - module_ids: &[ModuleId], - context: &Arc, -) -> HashMap> { - let mut async_deps_by_module_id = HashMap::new(); +pub fn mark_async(module_ids: &[ModuleId], context: &Arc) { let mut module_graph = context.module_graph.write().unwrap(); // TODO: 考虑成环的场景 module_ids.iter().for_each(|module_id| { @@ -220,15 +215,16 @@ pub fn mark_async( .map(|(_, dep, _)| dep.clone()) .collect(); let module = module_graph.get_module_mut(module_id).unwrap(); + let mut async_deps_map = context.async_deps_map.write().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); + + async_deps_map.insert(module_id.clone(), async_deps); } }); - async_deps_by_module_id } #[cfg(test)] diff --git a/e2e/fixtures/tla/mako.config.json b/e2e/fixtures/tla/mako.config.json new file mode 100644 index 000000000..00e31dc36 --- /dev/null +++ b/e2e/fixtures/tla/mako.config.json @@ -0,0 +1,8 @@ +{ + "minify": false, + "moduleIdStrategy": "named", + "optimization": { + "skipModules": true, + "concatenateModules": false + } +} \ No newline at end of file diff --git a/e2e/fixtures/tla/package.json b/e2e/fixtures/tla/package.json new file mode 100644 index 000000000..74470a546 --- /dev/null +++ b/e2e/fixtures/tla/package.json @@ -0,0 +1,6 @@ +{ + "repository": "git@github.com:umijs/mako.git", + "dependencies": { + "@alipay/huamei-components": "^3.6.2" + } +} diff --git a/e2e/fixtures/tla/src/index.ts b/e2e/fixtures/tla/src/index.ts new file mode 100644 index 000000000..50dc05d4b --- /dev/null +++ b/e2e/fixtures/tla/src/index.ts @@ -0,0 +1,8 @@ +import { useHuameiTemplatePicker } from './proxy' + + + + + + +console.log(19233456, useHuameiTemplatePicker) \ No newline at end of file diff --git a/e2e/fixtures/tla/src/proxy.ts b/e2e/fixtures/tla/src/proxy.ts new file mode 100644 index 000000000..c50bd24ae --- /dev/null +++ b/e2e/fixtures/tla/src/proxy.ts @@ -0,0 +1,2 @@ +// @ts-nocheck +export { useHuameiTemplatePicker } from '@alipay/huamei-components' diff --git a/packages/mako/src/binding.d.ts b/packages/mako/src/binding.d.ts index b99643f94..fa889880d 100644 --- a/packages/mako/src/binding.d.ts +++ b/packages/mako/src/binding.d.ts @@ -5,6 +5,7 @@ export interface JsHooks { name?: string; + enforce?: string; load?: ( filePath: string, ) => Promise<{ content: string; type: 'css' | 'js' } | void> | void; @@ -50,13 +51,24 @@ export interface JsHooks { endTime: number; }; }) => void; + writeBundle?: () => Promise; + watchChanges?: ( + id: string, + change: { event: 'create' | 'delete' | 'update' }, + ) => Promise | void; onGenerateFile?: (path: string, content: Buffer) => Promise; buildStart?: () => Promise; + buildEnd?: () => Promise; resolveId?: ( source: string, importer: string, { isEntry: bool }, ) => Promise<{ id: string }>; + transform?: ( + content: { content: string; type: 'css' | 'js' }, + path: string, + ) => Promise<{ content: string; type: 'css' | 'js' } | void> | void; + transformInclude?: (filePath: string) => Promise | bool; } export interface WriteFile { path: string; @@ -66,6 +78,9 @@ export interface LoadResult { content: string; type: string; } +export interface WatchChangesParams { + event: string; +} export interface ResolveIdResult { id: string; external: boolean | null; @@ -73,6 +88,10 @@ export interface ResolveIdResult { export interface ResolveIdParams { isEntry: boolean; } +export interface TransformResult { + content: string; + type: string; +} export interface BuildParams { root: string; config: { @@ -146,6 +165,7 @@ export interface BuildParams { providers?: Record; publicPath?: string; inlineLimit?: number; + inlineExcludesExtensions?: string[]; targets?: Record; platform?: 'node' | 'browser'; hmr?: false | {}; From c58106282f94a521cc8cc8bc0cf3875cb7a95f7c Mon Sep 17 00:00:00 2001 From: Jinbao1001 Date: Mon, 28 Oct 2024 10:38:29 +0800 Subject: [PATCH 5/6] fix: treeshaking jumped the async module --- crates/mako/src/generate/transform.rs | 6 +++-- crates/mako/src/module.rs | 8 ++++++- crates/mako/src/plugins/tree_shaking/shake.rs | 23 ++++++++----------- crates/mako/src/visitors/async_module.rs | 20 +++++----------- 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/crates/mako/src/generate/transform.rs b/crates/mako/src/generate/transform.rs index 262cd963a..0b99e95fb 100644 --- a/crates/mako/src/generate/transform.rs +++ b/crates/mako/src/generate/transform.rs @@ -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; @@ -55,7 +56,8 @@ impl Compiler { pub fn transform_modules(module_ids: Vec, context: &Arc) -> Result<()> { let t = Instant::now(); - mark_async(&module_ids, context); + let mut module_graph = context.module_graph.write().unwrap(); + mark_async(module_graph.deref_mut(), &module_ids, context); debug!(">> mark async in {}ms", t.elapsed().as_millis()); let t = Instant::now(); transform_modules_in_thread(&module_ids, context)?; @@ -70,8 +72,8 @@ pub fn transform_modules_in_thread( crate::mako_profile_function!(); let (rs, rr) = channel::>(); - let async_deps_by_module_id = context.async_deps_map.read().unwrap(); 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(); diff --git a/crates/mako/src/module.rs b/crates/mako/src/module.rs index 3122ea00f..ef5222f2b 100644 --- a/crates/mako/src/module.rs +++ b/crates/mako/src/module.rs @@ -491,7 +491,13 @@ impl Module { impl Debug for Module { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "id={}({:?})", self.id.id, self.get_module_type()) + write!( + f, + "id={}({:?}) is_async={:?}", + self.id.id, + self.get_module_type(), + self.info.as_ref().unwrap().is_async + ) } } diff --git a/crates/mako/src/plugins/tree_shaking/shake.rs b/crates/mako/src/plugins/tree_shaking/shake.rs index e90288ac2..4350ab9da 100644 --- a/crates/mako/src/plugins/tree_shaking/shake.rs +++ b/crates/mako/src/plugins/tree_shaking/shake.rs @@ -27,11 +27,17 @@ use crate::{mako_profile_function, mako_profile_scope}; type TreeShakingModuleMap = HashMap>; pub fn optimize_modules(module_graph: &mut ModuleGraph, context: &Arc) -> Result<()> { + let module_ids = { + let (mut module_ids, _) = module_graph.toposort(); + // start from the leaf nodes, so reverser 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, Vec) = topo_sorted_modules.into_iter().partition(|module_id| { let module = module_graph.get_module(module_id).unwrap(); @@ -39,8 +45,9 @@ pub fn optimize_modules(module_graph: &mut ModuleGraph, context: &Arc) 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; + if module_type != ModuleType::Script || module.is_external() || *is_async { + if module_type != ModuleType::Script && !module.is_external() || *is_async { // 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(); @@ -177,16 +184,6 @@ pub fn optimize_modules(module_graph: &mut ModuleGraph, context: &Arc) } } - // mark async should before concatenate && after skip module - - let module_ids = { - let (mut module_ids, _) = module_graph.toposort(); - // start from the leaf nodes, so reverser the sort - module_ids.reverse(); - module_ids - }; - mark_async(&module_ids, context); - if context .config .optimization diff --git a/crates/mako/src/visitors/async_module.rs b/crates/mako/src/visitors/async_module.rs index afddda979..525065e54 100644 --- a/crates/mako/src/visitors/async_module.rs +++ b/crates/mako/src/visitors/async_module.rs @@ -14,6 +14,7 @@ use crate::ast::utils::is_commonjs_require; 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_"; @@ -205,9 +206,7 @@ impl VisitMut for AsyncModule<'_> { } } -pub fn mark_async(module_ids: &[ModuleId], context: &Arc) { - let mut module_graph = context.module_graph.write().unwrap(); - +pub fn mark_async(module_graph: &mut ModuleGraph, module_ids: &[ModuleId], context: &Arc) { let mut to_visit_queue = module_graph .modules() .iter() @@ -252,23 +251,16 @@ pub fn mark_async(module_ids: &[ModuleId], context: &Arc) { 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(); let async_deps: Vec = 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(); - let mut async_deps_map = context.async_deps_map.write().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; - } - if !async_deps.is_empty() { - async_deps_map.insert(module_id.clone(), async_deps); - } + if !async_deps.is_empty() { + async_deps_map.insert(module_id.clone(), async_deps); } - }) + }); } #[cfg(test)] From 88bdaba44846acafc66f7893ec47dcbb58a64931 Mon Sep 17 00:00:00 2001 From: Jinbao1001 Date: Mon, 28 Oct 2024 10:41:33 +0800 Subject: [PATCH 6/6] chore: delete no use e2e --- e2e/fixtures/tla/mako.config.json | 8 -------- e2e/fixtures/tla/package.json | 6 ------ e2e/fixtures/tla/src/index.ts | 8 -------- e2e/fixtures/tla/src/proxy.ts | 2 -- 4 files changed, 24 deletions(-) delete mode 100644 e2e/fixtures/tla/mako.config.json delete mode 100644 e2e/fixtures/tla/package.json delete mode 100644 e2e/fixtures/tla/src/index.ts delete mode 100644 e2e/fixtures/tla/src/proxy.ts diff --git a/e2e/fixtures/tla/mako.config.json b/e2e/fixtures/tla/mako.config.json deleted file mode 100644 index 00e31dc36..000000000 --- a/e2e/fixtures/tla/mako.config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "minify": false, - "moduleIdStrategy": "named", - "optimization": { - "skipModules": true, - "concatenateModules": false - } -} \ No newline at end of file diff --git a/e2e/fixtures/tla/package.json b/e2e/fixtures/tla/package.json deleted file mode 100644 index 74470a546..000000000 --- a/e2e/fixtures/tla/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "repository": "git@github.com:umijs/mako.git", - "dependencies": { - "@alipay/huamei-components": "^3.6.2" - } -} diff --git a/e2e/fixtures/tla/src/index.ts b/e2e/fixtures/tla/src/index.ts deleted file mode 100644 index 50dc05d4b..000000000 --- a/e2e/fixtures/tla/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { useHuameiTemplatePicker } from './proxy' - - - - - - -console.log(19233456, useHuameiTemplatePicker) \ No newline at end of file diff --git a/e2e/fixtures/tla/src/proxy.ts b/e2e/fixtures/tla/src/proxy.ts deleted file mode 100644 index c50bd24ae..000000000 --- a/e2e/fixtures/tla/src/proxy.ts +++ /dev/null @@ -1,2 +0,0 @@ -// @ts-nocheck -export { useHuameiTemplatePicker } from '@alipay/huamei-components'