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

perf: warn case sensitive plugin #7606

Merged
merged 1 commit into from
Aug 19, 2024
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
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions crates/rspack_plugin_warn_sensitive_module/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ license = "MIT"
name = "rspack_plugin_warn_sensitive_module"
repository = "https://github.com/web-infra-dev/rspack"
version = "0.1.0"

[dependencies]
rspack_core = { version = "0.1.0", path = "../rspack_core" }
rspack_error = { version = "0.1.0", path = "../rspack_error" }
rspack_hook = { version = "0.1.0", path = "../rspack_hook" }
tracing = { workspace = true }
rspack_collections = { path = "../rspack_collections" }
Copy link
Contributor

@hardfist hardfist Aug 19, 2024

Choose a reason for hiding this comment

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

this need version field, otherwise it can't be published

rspack_core = { version = "0.1.0", path = "../rspack_core" }
rspack_error = { version = "0.1.0", path = "../rspack_error" }
rspack_hook = { version = "0.1.0", path = "../rspack_hook" }
rustc-hash = { workspace = true }
tracing = { workspace = true }

[package.metadata.cargo-shear]
ignored = ["tracing"]
53 changes: 32 additions & 21 deletions crates/rspack_plugin_warn_sensitive_module/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// https://github.com/webpack/webpack/blob/main/lib/WarnCaseSensitiveModulesPlugin.js

use std::collections::HashMap;
use std::{collections::HashMap, hash::BuildHasherDefault};

use rspack_collections::{Identifier, IdentifierSet};
use rspack_core::{
ApplyContext, Compilation, CompilationSeal, CompilerOptions, Logger, Module, ModuleGraph, Plugin,
ApplyContext, Compilation, CompilationSeal, CompilerOptions, Logger, ModuleGraph, Plugin,
PluginContext,
};
use rspack_error::{Diagnostic, Result};
use rspack_hook::{plugin, plugin_hook};
use rustc_hash::{FxHashMap, FxHasher};

#[plugin]
#[derive(Debug, Default)]
Expand All @@ -16,15 +18,15 @@ pub struct WarnCaseSensitiveModulesPlugin;
impl WarnCaseSensitiveModulesPlugin {
pub fn create_sensitive_modules_warning(
&self,
modules: &Vec<&dyn Module>,
modules: Vec<Identifier>,
graph: &ModuleGraph,
) -> String {
let mut message =
String::from("There are multiple modules with names that only differ in casing.\n");

for m in modules {
if let Some(boxed_m) = graph.module_by_identifier(&m.identifier()) {
let mut module_msg = format!(" - {}\n", m.identifier());
if let Some(boxed_m) = graph.module_by_identifier(&m) {
let mut module_msg = format!(" - {}\n", m);
graph
.get_incoming_connections(&boxed_m.identifier())
.iter()
Expand All @@ -48,8 +50,11 @@ async fn seal(&self, compilation: &mut Compilation) -> Result<()> {
let start = logger.time("check case sensitive modules");
let mut diagnostics: Vec<Diagnostic> = vec![];
let module_graph = compilation.get_module_graph();
let mut module_without_case_map: HashMap<String, HashMap<String, &Box<dyn Module>>> =
HashMap::new();
let mut not_conflect: FxHashMap<String, Identifier> = HashMap::with_capacity_and_hasher(
module_graph.modules().len(),
BuildHasherDefault::<FxHasher>::default(),
);
let mut conflict: FxHashMap<String, IdentifierSet> = FxHashMap::default();

for module in module_graph.modules().values() {
// Ignore `data:` URLs, because it's not a real path
Expand All @@ -63,25 +68,31 @@ async fn seal(&self, compilation: &mut Compilation) -> Result<()> {
}
}

let identifier = module.identifier().to_string();
let identifier = module.identifier();
let lower_identifier = identifier.to_lowercase();
let lower_map = module_without_case_map.entry(lower_identifier).or_default();
lower_map.insert(identifier, module);
if let Some(prev_identifier) = not_conflect.remove(&lower_identifier) {
conflict.insert(
lower_identifier,
IdentifierSet::from_iter([prev_identifier, identifier]),
);
} else if let Some(set) = conflict.get_mut(&lower_identifier) {
set.insert(identifier);
} else {
not_conflect.insert(lower_identifier, identifier);
}
}

// sort by module identifier, guarantee the warning order
let mut case_map_vec = module_without_case_map.into_iter().collect::<Vec<_>>();
case_map_vec.sort_by(|a, b| a.0.cmp(&b.0));
let mut case_map_vec = conflict.into_iter().collect::<Vec<_>>();
case_map_vec.sort_unstable_by(|a, b| a.0.cmp(&b.0));

for (_, lower_map) in case_map_vec {
if lower_map.values().len() > 1 {
let mut case_modules = lower_map.values().map(|m| m.as_ref()).collect::<Vec<_>>();
case_modules.sort_by_key(|m| m.identifier());
diagnostics.push(Diagnostic::warn(
"Sensitive Modules Warn".to_string(),
self.create_sensitive_modules_warning(&case_modules, &compilation.get_module_graph()),
));
}
for (_, set) in case_map_vec {
let mut case_modules = set.iter().copied().collect::<Vec<_>>();
case_modules.sort_unstable();
diagnostics.push(Diagnostic::warn(
"Sensitive Modules Warn".to_string(),
self.create_sensitive_modules_warning(case_modules, &compilation.get_module_graph()),
));
}

compilation.extend_diagnostics(diagnostics);
Expand Down
Loading