Skip to content
Merged
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
4 changes: 2 additions & 2 deletions crates/mako/src/build/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use swc_core::ecma::transforms::base::helpers::{Helpers, HELPERS};
use swc_core::ecma::transforms::base::{resolver, Assumptions};
use swc_core::ecma::transforms::compat::reserved_words;
use swc_core::ecma::transforms::optimization::simplifier;
use swc_core::ecma::transforms::optimization::simplify::{dce, Config as SimpilifyConfig};
use swc_core::ecma::transforms::optimization::simplify::{dce, Config as SimplifyConfig};
use swc_core::ecma::transforms::proposal::decorators;
use swc_core::ecma::visit::{Fold, VisitMut};

Expand Down Expand Up @@ -236,7 +236,7 @@ impl Transform {
// this must be kept for tree shaking to work
Box::new(simplifier(
unresolved_mark,
SimpilifyConfig {
SimplifyConfig {
dce: dce::Config {
top_level: false,
..Default::default()
Expand Down
61 changes: 14 additions & 47 deletions crates/mako/src/config/code_splitting.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use regex::Regex;
use serde::{Deserialize, Serialize};

use super::generic_usize::GenericUsizeDefault;
use crate::create_deserialize_fn;

#[derive(Deserialize, Serialize, Clone, Debug, Default)]
pub enum OptimizeAllowChunks {
#[derive(Deserialize, Serialize, Clone, Debug, Default, Eq, PartialEq)]
pub enum AllowChunks {
#[serde(rename = "all")]
All,
#[serde(rename = "entry")]
Expand Down Expand Up @@ -51,7 +50,7 @@ pub struct CodeSplittingGranularOptions {
pub struct CodeSplittingAdvancedOptions {
#[serde(default = "GenericUsizeDefault::<20000>::value")]
pub min_size: usize,
pub groups: Vec<OptimizeChunkGroup>,
pub groups: Vec<ChunkGroup>,
}

impl Default for CodeSplittingAdvancedOptions {
Expand All @@ -63,22 +62,22 @@ impl Default for CodeSplittingAdvancedOptions {
}
}

#[derive(Deserialize, Serialize, Clone, Debug)]
pub enum OptimizeChunkNameSuffixStrategy {
#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)]
pub enum ChunkNameSuffixStrategy {
#[serde(rename = "packageName")]
PackageName,
#[serde(rename = "dependentsHash")]
DependentsHash,
}

#[derive(Deserialize, Serialize, Clone, Debug)]
#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct OptimizeChunkGroup {
pub struct ChunkGroup {
pub name: String,
#[serde(default)]
pub name_suffix: Option<OptimizeChunkNameSuffixStrategy>,
pub name_suffix: Option<ChunkNameSuffixStrategy>,
#[serde(default)]
pub allow_chunks: OptimizeAllowChunks,
pub allow_chunks: AllowChunks,
#[serde(default = "GenericUsizeDefault::<1>::value")]
pub min_chunks: usize,
#[serde(default = "GenericUsizeDefault::<20000>::value")]
Expand All @@ -89,14 +88,15 @@ pub struct OptimizeChunkGroup {
pub min_module_size: Option<usize>,
#[serde(default)]
pub priority: i8,
#[serde(default, with = "optimize_test_format")]
pub test: Option<Regex>,
#[serde(default)]
// A string raw of regex
pub test: Option<String>,
Comment on lines +91 to +93
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

确认 test 字段类型更改未正确处理字符串到正则表达式的转换

在多个文件中,test 字段现在被赋值为 Option<String>,但未发现将字符串解析为正则表达式的实现逻辑。这可能导致潜在的运行时错误。

  • crates/mako/src/config/code_splitting.rs
  • crates/mako/src/generate/optimize_chunk.rs
  • crates/mako/src/plugins/ssu.rs
  • crates/mako/src/visitors/meta_url_replacer.rs
  • crates/mako/src/visitors/async_module.rs
  • crates/mako/src/generate/chunk_pot/util.rs
🔗 Analysis chain

注意 test 字段类型的更改

ChunkGroup 结构体中的 test 字段类型从 Option<Regex> 改为 Option<String>。请确保在代码中正确处理字符串到正则表达式的转换,以避免潜在的运行时错误。

请运行以下脚本以查找使用 test 字段的位置,验证是否已正确处理:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 描述:查找所有使用 `test` 字段的地方,确保有字符串到正则表达式的解析逻辑。

# 测试:搜索对 `test` 字段的访问。期望:找到解析字符串为正则表达式的代码。
rg --type rust 'test\s*:' -A 5

Length of output: 4277

}

impl Default for OptimizeChunkGroup {
impl Default for ChunkGroup {
fn default() -> Self {
Self {
allow_chunks: OptimizeAllowChunks::default(),
allow_chunks: AllowChunks::default(),
min_chunks: GenericUsizeDefault::<1>::value(),
min_size: GenericUsizeDefault::<20000>::value(),
max_size: GenericUsizeDefault::<5000000>::value(),
Expand All @@ -109,37 +109,4 @@ impl Default for OptimizeChunkGroup {
}
}

/**
* custom formatter for convert string to regex
* @see https://serde.rs/custom-date-format.html
*/
mod optimize_test_format {
use regex::Regex;
use serde::{self, Deserialize, Deserializer, Serializer};

pub fn serialize<S>(v: &Option<Regex>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if let Some(v) = v {
serializer.serialize_str(&v.to_string())
} else {
serializer.serialize_none()
}
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Regex>, D::Error>
where
D: Deserializer<'de>,
{
let v = String::deserialize(deserializer)?;

if v.is_empty() {
Ok(None)
} else {
Ok(Regex::new(v.as_str()).ok())
}
}
}

create_deserialize_fn!(deserialize_code_splitting, CodeSplitting);
78 changes: 37 additions & 41 deletions crates/mako/src/generate/optimize_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,22 @@ use std::string::String;

use hashlink::LinkedHashSet;
use indexmap::{IndexMap, IndexSet};
use regex::Regex;
use tracing::debug;

use crate::compiler::Compiler;
use crate::config::{
CodeSplitting, CodeSplittingAdvancedOptions, CodeSplittingGranularOptions,
CodeSplittingStrategy, CodeSplittingStrategyOptions, GenericUsizeDefault, OptimizeAllowChunks,
OptimizeChunkGroup, OptimizeChunkNameSuffixStrategy,
AllowChunks, ChunkGroup, ChunkNameSuffixStrategy, CodeSplitting, CodeSplittingAdvancedOptions,
CodeSplittingGranularOptions, CodeSplittingStrategy, CodeSplittingStrategyOptions,
GenericUsizeDefault,
};
use crate::generate::chunk::{Chunk, ChunkId, ChunkType};
use crate::generate::group_chunk::GroupUpdateResult;
use crate::module::{Module, ModuleId, ModuleInfo};
use crate::resolve::{ResolvedResource, ResolverResource};
use crate::utils::url_safe_base64_encode;
use crate::utils::{create_cached_regex, url_safe_base64_encode};

pub struct OptimizeChunksInfo {
pub group_options: OptimizeChunkGroup,
pub group_options: ChunkGroup,
pub module_to_chunks: IndexMap<ModuleId, Vec<ChunkId>>,
}

Expand Down Expand Up @@ -171,7 +170,7 @@ impl Compiler {

// check test regex
if let Some(test) = &optimize_info.group_options.test {
if !test.is_match(&module_id.id) {
if !create_cached_regex(test).is_match(&module_id.id) {
continue;
}
}
Expand Down Expand Up @@ -330,7 +329,7 @@ impl Compiler {
for info in &mut *optimize_chunks_infos {
if let Some(name_suffix) = &info.group_options.name_suffix {
match name_suffix {
OptimizeChunkNameSuffixStrategy::PackageName => {
ChunkNameSuffixStrategy::PackageName => {
let mut module_to_package_map: HashMap<String, Vec<ModuleId>> =
HashMap::new();
info.module_to_chunks.keys().for_each(|module_id| {
Expand Down Expand Up @@ -367,7 +366,7 @@ impl Compiler {
})
});
}
OptimizeChunkNameSuffixStrategy::DependentsHash => {
ChunkNameSuffixStrategy::DependentsHash => {
let mut module_to_dependents_md5_map: HashMap<String, Vec<ModuleId>> =
HashMap::new();
info.module_to_chunks
Expand Down Expand Up @@ -426,12 +425,11 @@ impl Compiler {
let info_chunk_id = ChunkId {
id: info.group_options.name.clone(),
};
let info_chunk_type =
if matches!(info.group_options.allow_chunks, OptimizeAllowChunks::Async) {
ChunkType::Sync
} else {
ChunkType::Entry(info_chunk_id.clone(), info.group_options.name.clone(), true)
};
let info_chunk_type = if matches!(info.group_options.allow_chunks, AllowChunks::Async) {
ChunkType::Sync
} else {
ChunkType::Entry(info_chunk_id.clone(), info.group_options.name.clone(), true)
};
let info_chunk = Chunk {
modules: info
.module_to_chunks
Expand Down Expand Up @@ -513,18 +511,14 @@ impl Compiler {

/* the following is util methods */

fn check_chunk_type_allow(
&self,
allow_chunks: &OptimizeAllowChunks,
chunk_type: &ChunkType,
) -> bool {
fn check_chunk_type_allow(&self, allow_chunks: &AllowChunks, chunk_type: &ChunkType) -> bool {
match allow_chunks {
OptimizeAllowChunks::All => matches!(
AllowChunks::All => matches!(
chunk_type,
&ChunkType::Entry(_, _, false) | &ChunkType::Async
),
OptimizeAllowChunks::Entry => matches!(chunk_type, &ChunkType::Entry(_, _, false)),
OptimizeAllowChunks::Async => chunk_type == &ChunkType::Async,
AllowChunks::Entry => matches!(chunk_type, &ChunkType::Entry(_, _, false)),
AllowChunks::Async => chunk_type == &ChunkType::Async,
}
}

Expand Down Expand Up @@ -594,13 +588,13 @@ impl Compiler {
fn code_splitting_strategy_auto() -> CodeSplittingAdvancedOptions {
CodeSplittingAdvancedOptions {
groups: vec![
OptimizeChunkGroup {
ChunkGroup {
name: "vendors".to_string(),
test: Regex::new(r"[/\\]node_modules[/\\]").ok(),
test: Some(r"[/\\]node_modules[/\\]".to_string()),
priority: -10,
..Default::default()
},
OptimizeChunkGroup {
ChunkGroup {
name: "common".to_string(),
min_chunks: 2,
// always split, to avoid multi-instance risk
Expand All @@ -619,34 +613,36 @@ fn code_splitting_strategy_granular(
) -> CodeSplittingAdvancedOptions {
CodeSplittingAdvancedOptions {
groups: vec![
OptimizeChunkGroup {
ChunkGroup {
name: "framework".to_string(),
allow_chunks: OptimizeAllowChunks::All,
allow_chunks: AllowChunks::All,
test: if framework_packages.is_empty() {
Regex::new("^$").ok()
Some("^$".to_string())
} else {
Regex::new(&format!(
r#"[/\\]node_modules[/\\].*({})[/\\]"#,
framework_packages.join("|")
))
.ok()
Some(
format!(
r#"[/\\]node_modules[/\\].*({})[/\\]"#,
framework_packages.join("|")
)
.to_string(),
)
},
priority: -10,
..Default::default()
},
OptimizeChunkGroup {
ChunkGroup {
name: "lib".to_string(),
name_suffix: Some(OptimizeChunkNameSuffixStrategy::PackageName),
allow_chunks: OptimizeAllowChunks::Async,
test: Regex::new(r"[/\\]node_modules[/\\]").ok(),
name_suffix: Some(ChunkNameSuffixStrategy::PackageName),
allow_chunks: AllowChunks::Async,
test: Some(r"[/\\]node_modules[/\\]".to_string()),
min_module_size: Some(lib_min_size),
priority: -20,
..Default::default()
},
OptimizeChunkGroup {
ChunkGroup {
name: "shared".to_string(),
name_suffix: Some(OptimizeChunkNameSuffixStrategy::DependentsHash),
allow_chunks: OptimizeAllowChunks::Async,
name_suffix: Some(ChunkNameSuffixStrategy::DependentsHash),
allow_chunks: AllowChunks::Async,
priority: -30,
min_chunks: 2,
..Default::default()
Expand Down
13 changes: 6 additions & 7 deletions crates/mako/src/plugins/ssu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ use std::sync::{Arc, Mutex};
use anyhow::Result;
use dashmap::DashSet;
use rayon::prelude::*;
use regex::Regex;
use serde::{Deserialize, Serialize};
use tracing::debug;

use crate::ast::file::{Content, File, JsContent};
use crate::compiler::{Args, Compiler, Context};
use crate::config::{
CodeSplitting, CodeSplittingAdvancedOptions, CodeSplittingStrategy,
CodeSplittingStrategyOptions, Config, OptimizeAllowChunks, OptimizeChunkGroup,
AllowChunks, ChunkGroup, CodeSplitting, CodeSplittingAdvancedOptions, CodeSplittingStrategy,
CodeSplittingStrategyOptions, Config,
};
use crate::generate::chunk::ChunkType;
use crate::generate::chunk_pot::util::{hash_hashmap, hash_vec};
Expand Down Expand Up @@ -164,18 +163,18 @@ impl Plugin for SUPlus {
CodeSplittingAdvancedOptions {
min_size: 0,
groups: vec![
OptimizeChunkGroup {
ChunkGroup {
name: "node_modules".to_string(),
name_suffix: None,
allow_chunks: OptimizeAllowChunks::All,
allow_chunks: AllowChunks::All,
min_chunks: 0,
min_size: 0,
max_size: usize::MAX,
min_module_size: None,
priority: 10,
test: Regex::new(r"[/\\]node_modules[/\\]").ok(),
test: Some(r"[/\\]node_modules[/\\]".to_string()),
},
OptimizeChunkGroup {
ChunkGroup {
name: "common".to_string(),
min_chunks: 0,
// always split, to avoid multi-instance risk
Expand Down
1 change: 1 addition & 0 deletions crates/mako/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub(crate) fn get_pkg_name(root: &Path) -> Option<String> {
pub fn create_cached_regex(re: &str) -> Regex {
Regex::new(re).unwrap()
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down