diff --git a/crates/mako/src/config/code_splitting.rs b/crates/mako/src/config/code_splitting.rs index e517ce539..d1175d72f 100644 --- a/crates/mako/src/config/code_splitting.rs +++ b/crates/mako/src/config/code_splitting.rs @@ -85,7 +85,7 @@ pub struct ChunkGroup { #[serde(default = "GenericUsizeDefault::<5000000>::value")] pub max_size: usize, #[serde(default)] - pub min_module_size: Option, + pub min_package_size: Option, #[serde(default)] pub priority: i8, #[serde(default)] @@ -102,7 +102,7 @@ impl Default for ChunkGroup { max_size: GenericUsizeDefault::<5000000>::value(), name: String::default(), name_suffix: None, - min_module_size: None, + min_package_size: None, test: None, priority: i8::default(), } diff --git a/crates/mako/src/generate/optimize_chunk.rs b/crates/mako/src/generate/optimize_chunk.rs index c5d0b2db9..f37897402 100644 --- a/crates/mako/src/generate/optimize_chunk.rs +++ b/crates/mako/src/generate/optimize_chunk.rs @@ -43,12 +43,12 @@ impl Compiler { // stage: modules self.module_to_optimize_infos(&mut optimize_chunks_infos, None); - // stage: size - self.optimize_chunk_size(&mut optimize_chunks_infos); - // stage: name_suffix self.optimize_name_suffix(&mut optimize_chunks_infos); + // stage: size + self.optimize_chunk_size(&mut optimize_chunks_infos); + // stage: apply self.apply_optimize_infos(&optimize_chunks_infos); @@ -264,13 +264,7 @@ impl Compiler { ); // split new chunks until chunk size is less than max_size and there has more than 1 package can be split - while package_size_map.len() > 1 - && (chunk_size > info.group_options.max_size - || (info.group_options.min_module_size.is_some() - && package_size_map - .iter() - .any(|p| p.1 .0 < info.group_options.min_module_size.unwrap()))) - { + while package_size_map.len() > 1 && chunk_size > info.group_options.max_size { let mut new_chunk_size = 0; let mut new_module_to_chunks = IndexMap::new(); @@ -283,8 +277,6 @@ impl Compiler { let package_size = package.1 .0; new_chunk_size == 0 || new_chunk_size + package_size < info.group_options.max_size - && (info.group_options.min_module_size.is_none() - || package_size < info.group_options.min_module_size.unwrap()) } else { false } @@ -344,6 +336,17 @@ impl Compiler { module_to_package_map .iter() .for_each(|(package_name, module_ids)| { + let total_package_size = + module_ids.iter().fold(0_usize, |total, cur| { + total + self.get_module_size(cur).unwrap_or_default() + }); + + if total_package_size + < info.group_options.min_package_size.unwrap_or_default() + { + return; + } + let mut new_chunk_group_options = info.group_options.clone(); new_chunk_group_options.name = format!("{}_{}", info.group_options.name, package_name); @@ -635,7 +638,7 @@ fn code_splitting_strategy_granular( name_suffix: Some(ChunkNameSuffixStrategy::PackageName), allow_chunks: AllowChunks::Async, test: Some(r"[/\\]node_modules[/\\]".to_string()), - min_module_size: Some(lib_min_size), + min_package_size: Some(lib_min_size), priority: -20, ..Default::default() }, diff --git a/crates/mako/src/plugins/ssu.rs b/crates/mako/src/plugins/ssu.rs index b78bebcd2..4db0208be 100644 --- a/crates/mako/src/plugins/ssu.rs +++ b/crates/mako/src/plugins/ssu.rs @@ -171,7 +171,7 @@ impl Plugin for SUPlus { min_chunks: 0, min_size: 0, max_size: usize::MAX, - min_module_size: None, + min_package_size: None, priority: 10, test: Some(r"[/\\]node_modules[/\\]".to_string()), }, @@ -182,7 +182,7 @@ impl Plugin for SUPlus { min_size: 1, max_size: usize::MAX, name_suffix: None, - min_module_size: None, + min_package_size: None, priority: 0, ..Default::default() }, diff --git a/e2e/fixtures/code-splitting.granular/expect.js b/e2e/fixtures/code-splitting.granular/expect.js index f924e824c..3120c1e93 100644 --- a/e2e/fixtures/code-splitting.granular/expect.js +++ b/e2e/fixtures/code-splitting.granular/expect.js @@ -10,14 +10,14 @@ assert( ); assert( - files["lib_0_lib1-async.js"].includes('console.log("lib1")') - && !files["lib_0_lib1-async.js"].includes("normal") - && files["lib_1_lib2-async.js"].includes('console.log("lib2")') - && !files["lib_1_lib2-async.js"].includes("normal") - && files["lib_0_shared1-async.js"].includes('console.log("shared1")') - && !files["lib_0_shared1-async.js"].includes("normal") - && files["lib_0_shared2-async.js"].includes('console.log("shared2")') - && !files["lib_0_shared2-async.js"].includes("normal"), + files["lib_lib1-async.js"].includes('console.log("lib1")') + && !files["lib_lib1-async.js"].includes("normal") + && files["lib_lib2-async.js"].includes('console.log("lib2")') + && !files["lib_lib2-async.js"].includes("normal") + && files["lib-async.js"].includes('console.log("shared1")') + && files["lib-async.js"].includes("normal") + && files["lib-async.js"].includes('console.log("shared2")') + && files["lib-async.js"].includes("normal"), "should split lib chunks" ); diff --git a/packages/bundler-mako/index.js b/packages/bundler-mako/index.js index 43ff235df..58741c56e 100644 --- a/packages/bundler-mako/index.js +++ b/packages/bundler-mako/index.js @@ -566,26 +566,52 @@ async function getMakoConfig(opts) { const normalizedDevtool = devtool === false ? false : 'source-map'; - if (process.env.GRANULAR_CHUNKS) { - codeSplitting = { - strategy: 'granular', - options: { - // copy from https://github.com/umijs/umi/blob/d8f3f1fa9586a8c7cab4d3b6a9e1637a6f47e1dc/packages/preset-umi/src/features/codeSplitting/codeSplitting.ts#L60 - frameworkPackages: [ - 'react-dom', - 'react', - // 'core-js', - // 'regenerator-runtime', - 'history', - 'react-router', - 'react-router-dom', - 'scheduler', - // TODO - // add renderer-react - ], - }, - }; - } + let makoCodeSplittingConfig = + codeSplitting === false + ? false + : codeSplitting?.jsStrategy === 'granularChunks' + ? { + strategy: 'granular', + options: { + // copy from https://github.com/umijs/umi/blob/d8f3f1fa9586a8c7cab4d3b6a9e1637a6f47e1dc/packages/preset-umi/src/features/codeSplitting/codeSplitting.ts#L60 + frameworkPackages: [ + 'react-dom', + 'react', + // 'core-js', + // 'regenerator-runtime', + 'history', + 'react-router', + 'react-router-dom', + 'scheduler', + // TODO + // add renderer-react + ], + }, + } + : codeSplitting?.jsStrategy === 'depPerChunk' + ? { + strategy: 'advanced', + options: { + groups: [ + { + name: 'npm', + allowChunks: 'async', + test: '[\\\\/]node_modules[\\\\/]', + nameSuffix: 'packageName', + priority: -10, + minSize: 1, + minPackageSize: 1, + }, + { + name: 'common', + allowChunks: 'async', + minChunks: 2, + priority: -20, + }, + ], + }, + } + : { strategy: 'auto' }; const makoConfig = { entry: opts.entry, @@ -600,13 +626,7 @@ async function getMakoConfig(opts) { }, manifest, mdx: !!mdx, - codeSplitting: - codeSplitting === false - ? false - : typeof codeSplitting === 'object' && - codeSplitting.strategy === 'granular' - ? codeSplitting - : { strategy: 'auto' }, + codeSplitting: makoCodeSplittingConfig, devtool: normalizedDevtool, cjs, dynamicImportToRequire,