From a5e321288eb8fc95dc0606375ba11fe39678f2a5 Mon Sep 17 00:00:00 2001 From: Gengkun Date: Thu, 15 Aug 2024 15:39:25 +0800 Subject: [PATCH] refactor: module hash (#7569) --- Cargo.lock | 3 +- .../src/chunk_graph/chunk_graph_module.rs | 179 +++++++-------- .../src/code_generation_results.rs | 8 + .../rspack_core/src/compiler/compilation.rs | 217 ++++++++++-------- .../make/cutout/has_module_graph_change.rs | 18 ++ .../src/compiler/module_executor/execute.rs | 6 +- crates/rspack_core/src/concatenated_module.rs | 202 ++++++++-------- crates/rspack_core/src/context_module.rs | 49 ++-- crates/rspack_core/src/dependencies_block.rs | 69 ++++-- .../src/dependency/cached_const_dependency.rs | 18 +- .../src/dependency/const_dependency.rs | 17 +- .../src/dependency/dependency_template.rs | 7 + .../runtime_requirements_dependency.rs | 14 +- crates/rspack_core/src/exports_info.rs | 180 ++++++--------- crates/rspack_core/src/external_module.rs | 38 ++- crates/rspack_core/src/lib.rs | 1 - crates/rspack_core/src/module.rs | 146 ++++-------- crates/rspack_core/src/normal_module.rs | 104 +++++---- .../src/old_cache/occasion/code_generate.rs | 67 ++---- crates/rspack_core/src/options/module.rs | 4 +- .../rspack_core/src/parser_and_generator.rs | 16 +- crates/rspack_core/src/raw_module.rs | 35 ++- crates/rspack_core/src/runtime.rs | 9 + crates/rspack_core/src/runtime_module.rs | 2 +- crates/rspack_core/src/self_module.rs | 33 +-- crates/rspack_core/src/update_hash.rs | 13 -- crates/rspack_hash/src/lib.rs | 4 +- crates/rspack_macros/src/runtime_module.rs | 27 ++- .../tests/runtime_module.rs | 15 +- crates/rspack_plugin_asset/src/lib.rs | 147 +++++++++--- .../src/dependency/export.rs | 15 +- .../src/dependency/import.rs | 13 +- .../src/dependency/local_ident.rs | 16 +- .../rspack_plugin_css/src/dependency/url.rs | 11 +- .../src/parser_and_generator/mod.rs | 21 +- crates/rspack_plugin_css/src/plugin/mod.rs | 10 +- .../src/css_module.rs | 41 ++-- .../rspack_plugin_extract_css/src/plugin.rs | 15 +- crates/rspack_plugin_hmr/Cargo.toml | 2 +- crates/rspack_plugin_hmr/src/lib.rs | 23 +- .../common_js_export_require_dependency.rs | 10 +- .../commonjs/common_js_exports_dependency.rs | 18 +- .../common_js_full_require_dependency.rs | 12 +- .../commonjs/common_js_require_dependency.rs | 10 +- .../common_js_self_reference_dependency.rs | 10 +- .../commonjs/module_decorator_dependency.rs | 18 +- .../commonjs/require_header_dependency.rs | 10 +- .../commonjs/require_resolve_dependency.rs | 14 +- .../common_js_require_context_dependency.rs | 10 +- .../context/import_context_dependency.rs | 10 +- .../context/import_meta_context_dependency.rs | 10 +- .../context/require_context_dependency.rs | 10 +- .../esm/external_module_dependency.rs | 16 +- .../esm/harmony_compatibility_dependency.rs | 13 +- .../harmony_export_expression_dependency.rs | 8 + .../esm/harmony_export_header_dependency.rs | 12 +- ...ny_export_imported_specifier_dependency.rs | 18 +- .../harmony_export_specifier_dependency.rs | 16 +- .../esm/harmony_import_dependency.rs | 9 + .../harmony_import_specifier_dependency.rs | 14 +- .../src/dependency/esm/import_dependency.rs | 13 +- .../dependency/esm/import_eager_dependency.rs | 14 +- .../src/dependency/esm/provide_dependency.rs | 13 +- .../src/dependency/export_info_dependency.rs | 12 +- .../hmr/harmony_accept_dependency.rs | 13 +- .../dependency/hmr/import_meta_hot_accept.rs | 13 +- .../dependency/hmr/import_meta_hot_decline.rs | 13 +- .../src/dependency/hmr/module_hot_accept.rs | 13 +- .../src/dependency/hmr/module_hot_decline.rs | 13 +- .../src/dependency/is_included_dependency.rs | 10 +- .../dependency/module_argument_dependency.rs | 15 +- .../dependency/pure_expression_dependency.rs | 85 ++++--- .../src/dependency/url/mod.rs | 16 +- .../src/dependency/worker/mod.rs | 17 +- .../common_js_exports_parse_plugin.rs | 6 +- crates/rspack_plugin_json/Cargo.toml | 1 + .../src/json_exports_dependency.rs | 17 +- .../src/module.rs | 45 ++-- crates/rspack_plugin_mf/Cargo.toml | 1 - .../src/container/container_entry_module.rs | 37 ++- .../src/container/fallback_module.rs | 35 +-- .../src/container/remote_module.rs | 35 +-- .../src/sharing/consume_shared_module.rs | 43 ++-- .../src/sharing/consume_shared_plugin.rs | 2 +- .../src/sharing/provide_shared_module.rs | 46 ++-- .../src/plugin/max_size.rs | 6 +- ...js.$4b5109fbbb7c7970bd73f145985a8713$.css} | 0 ...js.$765cfc26ddecf262088215f69c92da3e$.css} | 0 ...in.$c414a55a331514d313ce34913a677700$.css} | 0 ...yA.$5038057b5dc54d459c2090d9455373d6$.css} | 0 ...yB.$8ddf1fb367ac73deeba175a1de156238$.css} | 0 ...in.$7a92eedfa1f9813bd6a40e1910d3ecc0$.css} | 0 ...in.$4f43297fc0af2c899c5e56fd341c7258$.css} | 0 .../cases/issue-6649/expected/main.js | 4 +- ....$33888ee88d16a14ff101cdf362266f8f$.1.css} | 0 ....$cdffad3f0b38fa11c50b5a3ca2766a33$.2.css} | 0 96 files changed, 1477 insertions(+), 1124 deletions(-) delete mode 100644 crates/rspack_core/src/update_hash.rs rename tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/{one_js.$2faf8431c36246aaa99efe65186ef7b1$.css => one_js.$4b5109fbbb7c7970bd73f145985a8713$.css} (100%) rename tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/{two_js.$108a632b35566ba6e10f21437dc1e449$.css => two_js.$765cfc26ddecf262088215f69c92da3e$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash-1/expected/{main.$2948667d05523e0bdd4b433a8b432330$.css => main.$c414a55a331514d313ce34913a677700$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/{entryA.$63eb4b2b7412624c84340d8ef2383cb3$.css => entryA.$5038057b5dc54d459c2090d9455373d6$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/{entryB.$7dc4057bc127528eb3d6e30affb70fc5$.css => entryB.$8ddf1fb367ac73deeba175a1de156238$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash/expected/{1.main.$fcf981e297c26c27907740d422c8fbb8$.css => 1.main.$7a92eedfa1f9813bd6a40e1910d3ecc0$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash/expected/{2.main.$a033229f200a2cfbacbc9213dd60155a$.css => 2.main.$4f43297fc0af2c899c5e56fd341c7258$.css} (100%) rename tests/plugin-test/css-extract/cases/js-hash/expected/{style.$fc35cd7d3442366ea0e20c936c0d399c$.1.css => style.$33888ee88d16a14ff101cdf362266f8f$.1.css} (100%) rename tests/plugin-test/css-extract/cases/js-hash/expected/{style.$2ebc9424ae217f7031ea75743effd066$.2.css => style.$cdffad3f0b38fa11c50b5a3ca2766a33$.2.css} (100%) diff --git a/Cargo.lock b/Cargo.lock index e62f5f6830f..ea3a72cbbf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3596,7 +3596,6 @@ dependencies = [ "rspack_collections", "rspack_core", "rspack_error", - "rspack_hash", "rspack_hook", "rspack_util", "rustc-hash 1.1.0", @@ -3689,6 +3688,7 @@ dependencies = [ "ropey", "rspack_core", "rspack_error", + "rspack_util", ] [[package]] @@ -3776,7 +3776,6 @@ dependencies = [ "rspack_collections", "rspack_core", "rspack_error", - "rspack_hash", "rspack_hook", "rspack_loader_runner", "rspack_plugin_runtime", diff --git a/crates/rspack_core/src/chunk_graph/chunk_graph_module.rs b/crates/rspack_core/src/chunk_graph/chunk_graph_module.rs index b91bec66917..9ae1410ef8e 100644 --- a/crates/rspack_core/src/chunk_graph/chunk_graph_module.rs +++ b/crates/rspack_core/src/chunk_graph/chunk_graph_module.rs @@ -1,18 +1,19 @@ //! There are methods whose verb is `ChunkGraphModule` -use std::hash::Hasher; +use std::hash::{Hash, Hasher}; -use rspack_collections::{IdentifierMap, UkeySet}; +use rspack_collections::{IdentifierSet, UkeySet}; +use rspack_hash::RspackHashDigest; use rspack_util::ext::DynHash; use rustc_hash::FxHasher; +use tracing::instrument; -use crate::update_hash::{UpdateHashContext, UpdateRspackHash}; -use crate::ChunkGraph; use crate::{ - get_chunk_group_from_ukey, AsyncDependenciesBlockIdentifier, BoxModule, ChunkByUkey, ChunkGroup, - ChunkGroupByUkey, ChunkGroupUkey, ChunkUkey, Compilation, ExportsHash, ModuleIdentifier, - RuntimeGlobals, RuntimeSpec, RuntimeSpecMap, RuntimeSpecSet, + get_chunk_group_from_ukey, AsyncDependenciesBlockIdentifier, ChunkByUkey, ChunkGroup, + ChunkGroupByUkey, ChunkGroupUkey, ChunkUkey, Compilation, ModuleIdentifier, RuntimeGlobals, + RuntimeSpec, RuntimeSpecMap, RuntimeSpecSet, }; +use crate::{ChunkGraph, Module}; #[derive(Debug, Clone, Default)] pub struct ChunkGraphModule { @@ -21,7 +22,7 @@ pub struct ChunkGraphModule { pub chunks: UkeySet, pub(crate) runtime_requirements: Option>, pub(crate) runtime_in_chunks: UkeySet, - // pub(crate) hashes: Option>, + pub(crate) hashes: Option>, } impl ChunkGraphModule { @@ -32,7 +33,7 @@ impl ChunkGraphModule { chunks: Default::default(), runtime_requirements: None, runtime_in_chunks: Default::default(), - // hashes: None, + hashes: None, } } } @@ -165,106 +166,84 @@ impl ChunkGraph { self.block_to_chunk_group_ukey.insert(block, chunk_group); } + pub fn get_module_hash( + &self, + module_identifier: ModuleIdentifier, + runtime: &RuntimeSpec, + ) -> Option<&RspackHashDigest> { + let cgm = self.get_chunk_graph_module(module_identifier); + if let Some(hashes) = &cgm.hashes { + if let Some(hash) = hashes.get(runtime) { + return Some(hash); + } + } + None + } + + pub fn set_module_hashes( + &mut self, + module_identifier: ModuleIdentifier, + hashes: RuntimeSpecMap, + ) { + let cgm = self.get_chunk_graph_module_mut(module_identifier); + cgm.hashes = Some(hashes); + } + + #[instrument(name = "chunk_graph:get_module_graph_hash", skip_all)] pub fn get_module_graph_hash( &self, - module: &BoxModule, + module: &dyn Module, compilation: &Compilation, runtime: Option<&RuntimeSpec>, - with_connections: bool, - ) -> String { + ) -> u64 { let mut hasher = FxHasher::default(); - let mut connection_hash_cache: IdentifierMap = IdentifierMap::default(); - let module_graph = &compilation.get_module_graph(); - - let process_module_graph_module = |module: &BoxModule, strict: Option| -> u64 { - let mut hasher = FxHasher::default(); - module.identifier().dyn_hash(&mut hasher); - module.source_types().dyn_hash(&mut hasher); - module_graph - .is_async(&module.identifier()) - .dyn_hash(&mut hasher); - - module_graph - .get_exports_info(&module.identifier()) - .export_info_hash(&mut hasher, module_graph, &mut UkeySet::default()); - - module - .get_blocks() - .iter() - .filter_map(|id| module_graph.block_by_id(id)) - .for_each(|block| { - block.update_hash( - &mut hasher, - &UpdateHashContext { - compilation, - runtime, - }, - ) - }); - - // NOTE: - // Webpack use module.getExportsType() to generate hash - // but the module graph may be modified in it - // and exports type is calculated from build meta and exports info - // so use them to generate hash directly to avoid mutable access to module graph - if let Some(strict) = strict { - if let Some(build_meta) = module.build_meta() { - strict.dyn_hash(&mut hasher); - build_meta.default_object.dyn_hash(&mut hasher); - build_meta.exports_type.dyn_hash(&mut hasher); - } - } - - hasher.finish() - }; - - // hash module build_info - module_graph - .get_module_hash(&module.identifier()) - .dyn_hash(&mut hasher); - // hash module graph module - process_module_graph_module(module, None).dyn_hash(&mut hasher); - - let strict: bool = module_graph - .module_by_identifier(&module.identifier()) - .unwrap_or_else(|| { - panic!( - "Module({}) should be added before using", - module.identifier() - ) - }) - .get_strict_harmony_module(); - - if with_connections { - let mut connections = module_graph - .get_outgoing_connections(&module.identifier()) - .into_iter() - .collect::>(); - - connections.sort_by(|a, b| a.module_identifier().cmp(b.module_identifier())); - - // hash connection module graph modules + self + .get_module_graph_hash_without_connections(module, compilation, runtime) + .hash(&mut hasher); + let strict = module.get_strict_harmony_module(); + let mg = compilation.get_module_graph(); + let connections = mg + .get_outgoing_connections(&module.identifier()) + .into_iter() + .collect::>(); + if !connections.is_empty() { + let mut visited_modules = IdentifierSet::default(); + visited_modules.insert(module.identifier()); for connection in connections { - if let Some(connection_hash) = connection_hash_cache.get(connection.module_identifier()) { - connection_hash.dyn_hash(&mut hasher) - } else { - let connection_hash = process_module_graph_module( - module_graph - .module_by_identifier(connection.module_identifier()) - .unwrap_or_else(|| { - panic!( - "Module({}) should be added before using", - connection.module_identifier() - ) - }), - Some(strict), - ); - connection_hash.dyn_hash(&mut hasher); - connection_hash_cache.insert(*connection.module_identifier(), connection_hash); + let module_identifier = connection.module_identifier(); + if visited_modules.contains(module_identifier) { + continue; + } + if connection.get_active_state(&mg, runtime).is_false() { + continue; } + visited_modules.insert(*module_identifier); + let module = mg + .module_by_identifier(module_identifier) + .expect("should have module") + .as_ref(); + module.get_exports_type(&mg, strict).hash(&mut hasher); + self.get_module_graph_hash_without_connections(module, compilation, runtime); } } + hasher.finish() + } - format!("{:016x}", hasher.finish()) + fn get_module_graph_hash_without_connections( + &self, + module: &dyn Module, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> u64 { + let mut hasher = FxHasher::default(); + let mg = compilation.get_module_graph(); + let module_identifier = module.identifier(); + let cgm = self.get_chunk_graph_module(module_identifier); + cgm.id.as_ref().dyn_hash(&mut hasher); + module.source_types().dyn_hash(&mut hasher); + mg.is_async(&module_identifier).dyn_hash(&mut hasher); + mg.get_exports_info(&module_identifier) + .update_hash(&mg, &mut hasher, compilation, runtime); + hasher.finish() } } diff --git a/crates/rspack_core/src/code_generation_results.rs b/crates/rspack_core/src/code_generation_results.rs index 1e2f39c5ffd..6344671ce52 100644 --- a/crates/rspack_core/src/code_generation_results.rs +++ b/crates/rspack_core/src/code_generation_results.rs @@ -303,3 +303,11 @@ impl CodeGenerationResults { code_generation_result.hash.as_ref() } } + +#[derive(Debug)] +pub struct CodeGenerationJob { + pub module: ModuleIdentifier, + pub hash: RspackHashDigest, + pub runtime: RuntimeSpec, + pub runtimes: Vec, +} diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index fa1a397b555..edc862a2dda 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -32,11 +32,11 @@ use crate::{ old_cache::{use_code_splitting_cache, Cache as OldCache, CodeSplittingCache}, to_identifier, BoxDependency, BoxModule, CacheCount, CacheOptions, Chunk, ChunkByUkey, ChunkContentHash, ChunkGraph, ChunkGroupByUkey, ChunkGroupUkey, ChunkKind, ChunkUkey, - CodeGenerationResults, CompilationLogger, CompilationLogging, CompilerOptions, DependencyId, - DependencyType, Entry, EntryData, EntryOptions, EntryRuntime, Entrypoint, ExecuteModuleId, - Filename, ImportVarMap, LocalFilenameFn, Logger, Module, ModuleFactory, ModuleGraph, - ModuleGraphPartial, ModuleIdentifier, PathData, ResolverFactory, RuntimeGlobals, RuntimeModule, - RuntimeSpec, SharedPluginDriver, SourceType, Stats, + CodeGenerationJob, CodeGenerationResults, CompilationLogger, CompilationLogging, CompilerOptions, + DependencyId, DependencyType, Entry, EntryData, EntryOptions, EntryRuntime, Entrypoint, + ExecuteModuleId, Filename, ImportVarMap, LocalFilenameFn, Logger, Module, ModuleFactory, + ModuleGraph, ModuleGraphPartial, ModuleIdentifier, PathData, ResolverFactory, RuntimeGlobals, + RuntimeModule, RuntimeSpec, RuntimeSpecMap, SharedPluginDriver, SourceType, Stats, }; pub type BuildDependency = ( @@ -754,23 +754,18 @@ impl Compilation { fn run_iteration( compilation: &mut Compilation, - codegen_cache_counter: &mut Option, + cache_counter: &mut Option, filter_op: impl Fn(&(ModuleIdentifier, &Box)) -> bool + Sync + Send, ) -> Result<()> { - // If the runtime optimization is not opt out, a module codegen should be executed for each runtime. - // Else, share same codegen result for all runtimes. - let used_exports_optimization = compilation.options.optimization.used_exports.is_true(); let results = compilation.code_generation_modules( - codegen_cache_counter, - used_exports_optimization, + cache_counter, compilation .get_module_graph() .modules() .into_iter() .filter(filter_op) .map(|(id, _)| id) - .collect::>() - .into_par_iter(), + .collect(), )?; results.iter().for_each(|module_identifier| { @@ -799,76 +794,94 @@ impl Compilation { pub(crate) fn code_generation_modules( &mut self, - codegen_cache_counter: &mut Option, - used_exports_optimization: bool, - modules: impl ParallelIterator, + cache_counter: &mut Option, + modules: IdentifierSet, ) -> Result> { let chunk_graph = &self.chunk_graph; let module_graph = self.get_module_graph(); - #[allow(clippy::type_complexity)] - let results = modules - .filter_map(|module_identifier| { - let runtimes = chunk_graph.get_module_runtimes(module_identifier, &self.chunk_by_ukey); - if runtimes.is_empty() { - return None; + let mut jobs = Vec::new(); + for module in modules { + let runtimes = chunk_graph.get_module_runtimes(module, &self.chunk_by_ukey); + if runtimes.is_empty() { + continue; + } + if runtimes.len() == 1 { + let runtime = runtimes + .into_values() + .next() + .expect("should have first value"); + let hash = chunk_graph + .get_module_hash(module, &runtime) + .expect("should have cgm.hash in code generation") + .clone(); + jobs.push(CodeGenerationJob { + module, + hash, + runtime: runtime.clone(), + runtimes: vec![runtime], + }) + } else { + let mut map: HashMap = HashMap::default(); + for runtime in runtimes.into_values() { + let hash = chunk_graph + .get_module_hash(module, &runtime) + .expect("should have cgm.hash in code generation") + .clone(); + if let Some(job) = map.get_mut(&hash) { + job.runtimes.push(runtime); + } else { + map.insert( + hash.clone(), + CodeGenerationJob { + module, + hash, + runtime: runtime.clone(), + runtimes: vec![runtime], + }, + ); + } } - - let module = module_graph - .module_by_identifier(&module_identifier) - .expect("module should exist"); - let res = self + jobs.extend(map.into_values()); + } + } + let results = jobs + .into_par_iter() + .map(|job| { + let module = job.module; + self .old_cache .code_generate_occasion - .use_cache(module, runtimes, self, |module, runtimes| { - let take_length = if used_exports_optimization { - runtimes.len() - } else { - // Only codegen once - 1 - }; - let mut codegen_list = vec![]; - for runtime in runtimes.into_values().take(take_length) { - codegen_list.push((module.code_generation(self, Some(&runtime), None)?, runtime)); - } - Ok(codegen_list) + .use_cache(job, |module, runtime| { + let module = module_graph + .module_by_identifier(&module) + .expect("should have module"); + module.code_generation(self, Some(runtime), None) }) - .map(|(result, from_cache)| (module_identifier, result, from_cache)); - Some(res) + .map(|(res, runtimes, from_cache)| (module, res, runtimes, from_cache)) }) .collect::>>()?; let results = results .into_iter() - .map(|(module_identifier, item, from_cache)| { - item.into_iter().for_each(|(result, runtime)| { - if let Some(counter) = codegen_cache_counter { - if from_cache { - counter.hit(); - } else { - counter.miss(); - } + .map(|(module, codegen_res, runtimes, from_cache)| { + if let Some(counter) = cache_counter { + if from_cache { + counter.hit(); + } else { + counter.miss(); } + } - let runtimes = self - .chunk_graph - .get_module_runtimes(module_identifier, &self.chunk_by_ukey); - let result_id = result.id; + let codegen_res_id = codegen_res.id; + self + .code_generation_results + .module_generation_result_map + .insert(codegen_res_id, codegen_res); + for runtime in runtimes { self .code_generation_results - .module_generation_result_map - .insert(result_id, result); - if used_exports_optimization { - self - .code_generation_results - .add(module_identifier, runtime, result_id); - } else { - for runtime in runtimes.into_values() { - self - .code_generation_results - .add(module_identifier, runtime, result_id); - } - } - }); - module_identifier + .add(module, runtime, codegen_res_id); + } + module }); Ok(results.collect()) @@ -1149,6 +1162,16 @@ impl Compilation { self.assign_runtime_ids(); + self.create_module_hashes( + self + .get_module_graph() + .modules() + .keys() + .copied() + .collect::>() + .into_par_iter(), + )?; + let start = logger.time("optimize code generation"); plugin_driver .compilation_hooks @@ -1569,31 +1592,39 @@ impl Compilation { Ok((chunk_hash, content_hashes)) } - // #[instrument(name = "compilation:create_module_hash", skip_all)] - // pub fn create_module_hash(&mut self) { - // let module_hash_map: HashMap = self - // .get_module_graph() - // .module_identifier_to_module - // .par_iter() - // .map(|(identifier, module)| { - // let mut hasher = RspackHash::new(); - // module.hash(&mut hasher); - // (*identifier, hasher.finish()) - // }) - // .collect(); - - // for (identifier, hash) in module_hash_map { - // for runtime in self - // .chunk_graph - // .get_module_runtimes(identifier, &self.chunk_by_ukey) - // .values() - // { - // self - // .chunk_graph - // .set_module_hashes(identifier, runtime, hash); - // } - // } - // } + #[instrument(name = "compilation:create_module_hashes", skip_all)] + pub fn create_module_hashes( + &mut self, + modules: impl ParallelIterator, + ) -> Result<()> { + let results: Vec<(ModuleIdentifier, RuntimeSpecMap)> = modules + .map(|module| { + ( + module, + self + .chunk_graph + .get_module_runtimes(module, &self.chunk_by_ukey), + ) + }) + .map(|(module_identifier, runtimes)| { + let mut hashes = RuntimeSpecMap::new(); + for runtime in runtimes.into_values() { + let mut hasher = RspackHash::from(&self.options.output); + let mg = self.get_module_graph(); + let module = mg + .module_by_identifier(&module_identifier) + .expect("should have module"); + module.update_hash(&mut hasher, self, Some(&runtime))?; + hashes.set(runtime, hasher.digest(&self.options.output.hash_digest)); + } + Ok((module_identifier, hashes)) + }) + .collect::>()?; + for (module, hashes) in results { + self.chunk_graph.set_module_hashes(module, hashes); + } + Ok(()) + } #[instrument(name = "compilation:create_runtime_module_hash", skip_all)] pub fn create_runtime_module_hash(&mut self) -> Result<()> { diff --git a/crates/rspack_core/src/compiler/make/cutout/has_module_graph_change.rs b/crates/rspack_core/src/compiler/make/cutout/has_module_graph_change.rs index 3ee4c4ac9c4..b700f751f1e 100644 --- a/crates/rspack_core/src/compiler/make/cutout/has_module_graph_change.rs +++ b/crates/rspack_core/src/compiler/make/cutout/has_module_graph_change.rs @@ -180,6 +180,15 @@ mod t { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + todo!() + } } impl ModuleDependency for TestDep { @@ -288,6 +297,15 @@ mod t { ) -> Result { todo!() } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + todo!() + } } #[test] diff --git a/crates/rspack_core/src/compiler/module_executor/execute.rs b/crates/rspack_core/src/compiler/module_executor/execute.rs index 87ca3bb986e..4c8bf00ee78 100644 --- a/crates/rspack_core/src/compiler/module_executor/execute.rs +++ b/crates/rspack_core/src/compiler/module_executor/execute.rs @@ -78,7 +78,7 @@ impl Task for ExecuteTask { .expect("should have module") .identifier(); let mut queue = vec![entry_module_identifier]; - let mut modules = HashSet::default(); + let mut modules = IdentifierSet::default(); while let Some(m) = queue.pop() { modules.insert(m); @@ -159,8 +159,10 @@ impl Task for ExecuteTask { // replace code_generation_results is the same reason compilation.chunk_graph = chunk_graph; + compilation.create_module_hashes(modules.par_iter().copied())?; + let code_generation_results = - compilation.code_generation_modules(&mut None, false, modules.par_iter().copied())?; + compilation.code_generation_modules(&mut None, modules.clone())?; code_generation_results .iter() diff --git a/crates/rspack_core/src/concatenated_module.rs b/crates/rspack_core/src/concatenated_module.rs index dcc6cbe2eb3..e3a0b3bb32a 100644 --- a/crates/rspack_core/src/concatenated_module.rs +++ b/crates/rspack_core/src/concatenated_module.rs @@ -1,14 +1,13 @@ use std::{ borrow::Cow, - collections::hash_map::{DefaultHasher, Entry}, + collections::hash_map::Entry, fmt::Debug, - hash::{BuildHasherDefault, Hash, Hasher}, + hash::{BuildHasherDefault, Hasher}, sync::{Arc, LazyLock, Mutex}, }; use dashmap::DashMap; use indexmap::{IndexMap, IndexSet}; -use once_cell::sync::OnceCell; use rayon::prelude::*; use regex::Regex; use rspack_ast::javascript::Ast; @@ -19,7 +18,7 @@ use rspack_error::{Diagnosable, Diagnostic, DiagnosticKind, Result, TraceableErr use rspack_hash::{HashDigest, HashFunction, RspackHash}; use rspack_hook::define_hook; use rspack_sources::{CachedSource, ConcatSource, RawSource, ReplaceSource, Source, SourceExt}; -use rspack_util::{source_map::SourceMapKind, swc::join_atom}; +use rspack_util::{ext::DynHash, source_map::SourceMapKind, swc::join_atom}; use rustc_hash::FxHasher; use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; use swc_core::{ @@ -35,7 +34,7 @@ use swc_node_comments::SwcComments; use crate::{ define_es_module_flag_statement, filter_runtime, impl_source_map_config, merge_runtime_condition, - merge_runtime_condition_non_false, property_access, property_name, + merge_runtime_condition_non_false, module_update_hash, property_access, property_name, reserved_names::RESERVED_NAMES, returning_function, runtime_condition_expression, subtract_runtime_condition, to_identifier, AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildMetaDefaultObject, BuildMetaExportsType, BuildResult, @@ -114,45 +113,46 @@ pub struct ConcatenatedInnerModule { pub shorten_id: String, } -#[derive(Debug)] -pub enum ConcatenationEntryType { - Concatenated, - External, -} +static REGEX: LazyLock = LazyLock::new(|| { + let pattern = r"\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules"; + Regex::new(pattern).expect("should construct the regex") +}); #[derive(Debug)] -pub enum ConnectionOrModuleIdent { - Module(ModuleIdentifier), - Connection(ConnectionId), +enum ConcatenationEntry { + Concatenated(ConcatenationEntryConcatenated), + External(ConcatenationEntryExternal), } -impl ConnectionOrModuleIdent { - fn get_module_id(&self, mg: &ModuleGraph) -> ModuleIdentifier { +impl ConcatenationEntry { + pub fn module(&self, mg: &ModuleGraph) -> ModuleIdentifier { match self { - ConnectionOrModuleIdent::Module(m) => *m, - ConnectionOrModuleIdent::Connection(c) => { - let con = mg - .connection_by_connection_id(c) - .expect("should have connection"); - *con.module_identifier() - } + ConcatenationEntry::Concatenated(c) => c.module, + ConcatenationEntry::External(e) => e.module(mg), } } } -pub static REGEX: LazyLock = LazyLock::new(|| { - let pattern = r"\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules"; - Regex::new(pattern).expect("should construct the regex") -}); #[derive(Debug)] -pub struct ConcatenationEntry { - ty: ConcatenationEntryType, - /// I do want to align with webpack, but https://github.com/webpack/webpack/blob/1f99ad6367f2b8a6ef17cce0e058f7a67fb7db18/lib/optimize/ConcatenatedModule.js#L1018-L1027 - /// you know .. - connection_or_module_id: ConnectionOrModuleIdent, +struct ConcatenationEntryConcatenated { + module: ModuleIdentifier, +} + +#[derive(Debug)] +struct ConcatenationEntryExternal { + connection: ConnectionId, runtime_condition: RuntimeCondition, } +impl ConcatenationEntryExternal { + pub fn module(&self, mg: &ModuleGraph) -> ModuleIdentifier { + let con = mg + .connection_by_connection_id(&self.connection) + .expect("should have connection"); + *con.module_identifier() + } +} + #[derive(Debug)] pub struct ConcatenatedModuleImportInfo { connection: ModuleGraphConnection, @@ -361,7 +361,6 @@ pub struct ConcatenatedModule { cached_source_sizes: DashMap>, diagnostics: Mutex>, - cached_hash: OnceCell, build_info: Option, } @@ -384,7 +383,6 @@ impl ConcatenatedModule { blocks: vec![], cached_source_sizes: DashMap::default(), diagnostics: Mutex::new(vec![]), - cached_hash: OnceCell::default(), build_info: None, source_map_kind: SourceMapKind::empty(), } @@ -527,7 +525,7 @@ impl Module for ConcatenatedModule { /// the compilation is asserted to be `Some(Compilation)`, https://github.com/webpack/webpack/blob/1f99ad6367f2b8a6ef17cce0e058f7a67fb7db18/lib/optimize/ModuleConcatenationPlugin.js#L394-L418 async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, compilation: Option<&Compilation>, ) -> Result { let compilation = compilation.expect("should pass compilation"); @@ -550,12 +548,6 @@ impl Module for ConcatenatedModule { }; self.clear_diagnostics(); - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - self.build_meta().hash(&mut hasher); - - build_info.hash = Some(hasher.digest(&build_context.compiler_options.output.hash_digest)); - let module_graph = compilation.get_module_graph(); let modules = self .modules @@ -611,6 +603,7 @@ impl Module for ConcatenatedModule { Ok(BuildResult::default()) } + #[tracing::instrument(name = "ConcatenatedModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -1288,6 +1281,49 @@ impl Module for ConcatenatedModule { Ok(code_generation_result) } + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + generation_runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + let runtime = if let Some(self_runtime) = &self.runtime + && let Some(generation_runtime) = generation_runtime + { + Some(Cow::Owned( + generation_runtime + .intersection(self_runtime) + .cloned() + .collect::(), + )) + } else { + generation_runtime.map(Cow::Borrowed) + }; + let runtime = runtime.as_deref(); + for info in self.create_concatenation_list( + self.root_module_ctxt.id, + IndexSet::from_iter(self.modules.iter().map(|item| item.id)), + runtime, + &compilation.get_module_graph(), + ) { + match info { + ConcatenationEntry::Concatenated(e) => compilation + .get_module_graph() + .module_by_identifier(&e.module) + .expect("should have module") + .update_hash(hasher, compilation, generation_runtime)?, + ConcatenationEntry::External(e) => { + compilation + .chunk_graph + .get_module_id(e.module(&compilation.get_module_graph())) + .dyn_hash(hasher); + } + }; + } + module_update_hash(self, hasher, compilation, generation_runtime); + Ok(()) + } + fn name_for_condition(&self) -> Option> { self.root_module_ctxt.name_for_condition.clone() } @@ -1365,14 +1401,6 @@ impl Diagnosable for ConcatenatedModule { } } -impl PartialEq for ConcatenatedModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() - } -} - -impl Eq for ConcatenatedModule {} - impl ConcatenatedModule { fn clear_diagnostics(&mut self) { self @@ -1397,16 +1425,14 @@ impl ConcatenatedModule { let mut list = vec![]; let mut map = IdentifierIndexMap::default(); for (i, concatenation_entry) in ordered_concatenation_list.into_iter().enumerate() { - let module_id = concatenation_entry - .connection_or_module_id - .get_module_id(mg); + let module_id = concatenation_entry.module(mg); match map.entry(module_id) { indexmap::map::Entry::Occupied(_) => { list.push(module_id); } indexmap::map::Entry::Vacant(vac) => { - match concatenation_entry.ty { - ConcatenationEntryType::Concatenated => { + match concatenation_entry { + ConcatenationEntry::Concatenated(_) => { let info = ConcatenatedModuleInfo { index: i, module: module_id, @@ -1415,11 +1441,11 @@ impl ConcatenatedModule { vac.insert(ModuleInfo::Concatenated(info)); list.push(module_id); } - ConcatenationEntryType::External => { + ConcatenationEntry::External(e) => { let info = ExternalModuleInfo { index: i, module: module_id, - runtime_condition: concatenation_entry.runtime_condition, + runtime_condition: e.runtime_condition, interop_namespace_object_used: false, interop_namespace_object_name: None, interop_namespace_object2_used: false, @@ -1462,11 +1488,11 @@ impl ConcatenatedModule { &mut list, ); } - list.push(ConcatenationEntry { - ty: ConcatenationEntryType::Concatenated, - connection_or_module_id: ConnectionOrModuleIdent::Module(root_module), - runtime_condition: RuntimeCondition::Boolean(true), - }); + list.push(ConcatenationEntry::Concatenated( + ConcatenationEntryConcatenated { + module: root_module, + }, + )); list } @@ -1509,11 +1535,11 @@ impl ConcatenatedModule { list, ); } - list.push(ConcatenationEntry { - ty: ConcatenationEntryType::Concatenated, - runtime_condition, - connection_or_module_id: ConnectionOrModuleIdent::Module(*con.module_identifier()), - }); + list.push(ConcatenationEntry::Concatenated( + ConcatenationEntryConcatenated { + module: *con.module_identifier(), + }, + )); } else { if let Some(cond) = exist_entry { let reduced_runtime_condition = @@ -1525,23 +1551,20 @@ impl ConcatenatedModule { } else { exists_entry.insert(*con.module_identifier(), runtime_condition.clone()); } - if let Some(last) = list.last_mut() { - if matches!(last.ty, ConcatenationEntryType::External) - && last.connection_or_module_id.get_module_id(mg) == *con.module_identifier() - { - last.runtime_condition = - merge_runtime_condition(&last.runtime_condition, &runtime_condition, runtime); - return; - } + if let Some(ConcatenationEntry::External(last)) = list.last_mut() + && last.module(mg) == *con.module_identifier() + { + last.runtime_condition = + merge_runtime_condition(&last.runtime_condition, &runtime_condition, runtime); + return; } let con_id = mg .connection_id_by_dependency_id(&con.dependency_id) .expect("should have dep id"); - list.push(ConcatenationEntry { - ty: ConcatenationEntryType::External, + list.push(ConcatenationEntry::External(ConcatenationEntryExternal { + connection: *con_id, runtime_condition, - connection_or_module_id: ConnectionOrModuleIdent::Connection(*con_id), - }) + })); } } @@ -2176,31 +2199,6 @@ impl ConcatenatedModule { } } -impl Hash for ConcatenatedModule { - fn hash(&self, state: &mut H) { - if let Some(h) = self.cached_hash.get() { - h.hash(state); - return; - } - - let mut temp_state = DefaultHasher::default(); - - "__rspack_internal__ConcatenatedModule".hash(&mut temp_state); - // the module has been sorted, so the has should be consistent - for module in self.modules.iter() { - if let Some(ref original_source_hash) = module.original_source_hash { - temp_state.write_u64(*original_source_hash); - } - } - let res = temp_state.finish(); - res.hash(state); - self - .cached_hash - .set(res) - .expect("should set hash of ConcatenatedModule") - } -} - pub fn is_harmony_dep_like(dep: &BoxDependency) -> bool { matches!( dep.dependency_type(), diff --git a/crates/rspack_core/src/context_module.rs b/crates/rspack_core/src/context_module.rs index 7b989c09867..8c7b6a86f98 100644 --- a/crates/rspack_core/src/context_module.rs +++ b/crates/rspack_core/src/context_module.rs @@ -12,7 +12,6 @@ use itertools::Itertools; use regex::{Captures, Regex}; use rspack_collections::{Identifiable, Identifier}; use rspack_error::{impl_empty_diagnosable_trait, miette::IntoDiagnostic, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_macros::impl_source_map_config; use rspack_regex::RspackRegex; use rspack_sources::{BoxSource, ConcatSource, RawSource, SourceExt}; @@ -23,14 +22,14 @@ use swc_core::atoms::Atom; use crate::{ block_promise, contextify, get_exports_type_with_strict, impl_module_meta_info, - returning_function, to_path, AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, - BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildMetaDefaultObject, BuildMetaExportsType, - BuildResult, ChunkGraph, ChunkGroupOptions, CodeGenerationResult, Compilation, - ConcatenationScope, ContextElementDependency, DependenciesBlock, Dependency, DependencyCategory, - DependencyId, DependencyType, DynamicImportMode, ExportsType, FactoryMeta, - FakeNamespaceObjectMode, GroupOptions, ImportAttributes, LibIdentOptions, Module, ModuleLayer, - ModuleType, Resolve, ResolveInnerOptions, ResolveOptionsWithDependencyType, ResolverFactory, - RuntimeGlobals, RuntimeSpec, SourceType, + module_update_hash, returning_function, to_path, AsyncDependenciesBlock, + AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, + BuildMetaDefaultObject, BuildMetaExportsType, BuildResult, ChunkGraph, ChunkGroupOptions, + CodeGenerationResult, Compilation, ConcatenationScope, ContextElementDependency, + DependenciesBlock, Dependency, DependencyCategory, DependencyId, DependencyType, + DynamicImportMode, ExportsType, FactoryMeta, FakeNamespaceObjectMode, GroupOptions, + ImportAttributes, LibIdentOptions, Module, ModuleLayer, ModuleType, Resolve, ResolveInnerOptions, + ResolveOptionsWithDependencyType, ResolverFactory, RuntimeGlobals, RuntimeSpec, SourceType, }; #[derive(Debug, Clone)] @@ -172,14 +171,6 @@ pub struct ContextModule { build_meta: Option, } -impl PartialEq for ContextModule { - fn eq(&self, other: &Self) -> bool { - self.identifier == other.identifier - } -} - -impl Eq for ContextModule {} - impl ContextModule { pub fn new(options: ContextModuleOptions, resolve_factory: Arc) -> Self { Self { @@ -880,19 +871,15 @@ impl Module for ContextModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { let (dependencies, blocks) = self.resolve_dependencies()?; - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let mut context_dependencies: HashSet = Default::default(); context_dependencies.insert(PathBuf::from(&self.options.resource)); let build_info = BuildInfo { - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), context_dependencies, ..Default::default() }; @@ -910,6 +897,7 @@ impl Module for ContextModule { }) } + #[tracing::instrument(name = "ContextModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -972,6 +960,16 @@ impl Module for ContextModule { ); Ok(code_generation_result) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + Ok(()) + } } impl_empty_diagnosable_trait!(ContextModule); @@ -982,13 +980,6 @@ impl Identifiable for ContextModule { } } -impl Hash for ContextModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__ContextModule".hash(state); - self.identifier.hash(state); - } -} - static WEBPACK_CHUNK_NAME_PLACEHOLDER: LazyLock = LazyLock::new(|| Regex::new(r"\[index|request\]").expect("regexp init failed")); static WEBPACK_CHUNK_NAME_INDEX_PLACEHOLDER: LazyLock = diff --git a/crates/rspack_core/src/dependencies_block.rs b/crates/rspack_core/src/dependencies_block.rs index 02881c7ba07..f3e1f6a9e50 100644 --- a/crates/rspack_core/src/dependencies_block.rs +++ b/crates/rspack_core/src/dependencies_block.rs @@ -1,9 +1,4 @@ -use std::{ - borrow::Cow, - fmt::Display, - hash::{Hash, Hasher}, - sync::Arc, -}; +use std::{borrow::Cow, fmt::Display, hash::Hash, sync::Arc}; use derivative::Derivative; use rspack_collections::Identifier; @@ -11,11 +6,11 @@ use rspack_error::{ miette::{self, Diagnostic}, thiserror::{self, Error}, }; +use rspack_util::ext::DynHash; use swc_core::common::{BytePos, SourceMap}; use crate::{ - update_hash::{UpdateHashContext, UpdateRspackHash}, - BoxDependency, DependencyId, GroupOptions, ModuleIdentifier, + BoxDependency, Compilation, DependencyId, GroupOptions, ModuleIdentifier, RuntimeSpec, }; pub trait DependenciesBlock { @@ -28,6 +23,26 @@ pub trait DependenciesBlock { fn get_dependencies(&self) -> &[DependencyId]; } +pub fn dependencies_block_update_hash( + deps: &[DependencyId], + blocks: &[AsyncDependenciesBlockIdentifier], + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, +) { + let mg = compilation.get_module_graph(); + for dep_id in deps { + let dep = mg.dependency_by_id(dep_id).expect("should have dependency"); + if let Some(dep) = dep.as_dependency_template() { + dep.update_hash(hasher, compilation, runtime); + } + } + for block_id in blocks { + let block = mg.block_by_id_expect(block_id); + block.update_hash(hasher, compilation, runtime); + } +} + #[derive(Derivative)] #[derivative(Debug, Clone)] pub struct DependencyLocation { @@ -178,6 +193,28 @@ impl AsyncDependenciesBlock { pub fn request(&self) -> &Option { &self.request } + + pub fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) { + self.group_options.dyn_hash(hasher); + if let Some(chunk_group) = compilation + .chunk_graph + .get_block_chunk_group(&self.id, &compilation.chunk_group_by_ukey) + { + chunk_group.id(compilation).dyn_hash(hasher); + } + dependencies_block_update_hash( + self.get_dependencies(), + self.get_blocks(), + hasher, + compilation, + runtime, + ); + } } impl DependenciesBlock for AsyncDependenciesBlock { @@ -199,22 +236,6 @@ impl DependenciesBlock for AsyncDependenciesBlock { } } -impl UpdateRspackHash for AsyncDependenciesBlock { - fn update_hash(&self, state: &mut H, context: &UpdateHashContext) { - self.group_options.hash(state); - if let Some(chunk_group) = context - .compilation - .chunk_graph - .get_block_chunk_group(&self.id, &context.compilation.chunk_group_by_ukey) - { - chunk_group.id(context.compilation).hash(state); - } - for block in &self.blocks { - block.update_hash(state, context); - } - } -} - #[derive(Debug, Error, Diagnostic)] #[diagnostic(code(AsyncDependencyToInitialChunkError))] #[error("It's not allowed to load an initial chunk on demand. The chunk name \"{0}\" is already used by an entrypoint.")] diff --git a/crates/rspack_core/src/dependency/cached_const_dependency.rs b/crates/rspack_core/src/dependency/cached_const_dependency.rs index 4e9b274ea9e..8feddacc74b 100644 --- a/crates/rspack_core/src/dependency/cached_const_dependency.rs +++ b/crates/rspack_core/src/dependency/cached_const_dependency.rs @@ -1,6 +1,8 @@ +use rspack_util::ext::DynHash; + use crate::{ - AsDependency, DependencyTemplate, InitFragmentExt, InitFragmentKey, InitFragmentStage, - NormalInitFragment, TemplateContext, TemplateReplaceSource, + AsDependency, Compilation, DependencyTemplate, InitFragmentExt, InitFragmentKey, + InitFragmentStage, NormalInitFragment, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; #[derive(Debug, Clone)] @@ -44,6 +46,18 @@ impl DependencyTemplate for CachedConstDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.identifier.dyn_hash(hasher); + self.start.dyn_hash(hasher); + self.end.dyn_hash(hasher); + self.content.dyn_hash(hasher); + } } impl AsDependency for CachedConstDependency {} diff --git a/crates/rspack_core/src/dependency/const_dependency.rs b/crates/rspack_core/src/dependency/const_dependency.rs index abbd2b01437..2141daf88a2 100644 --- a/crates/rspack_core/src/dependency/const_dependency.rs +++ b/crates/rspack_core/src/dependency/const_dependency.rs @@ -1,5 +1,8 @@ +use rspack_util::ext::DynHash; + use crate::{ - AsDependency, DependencyTemplate, RuntimeGlobals, TemplateContext, TemplateReplaceSource, + AsDependency, Compilation, DependencyTemplate, RuntimeGlobals, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; #[derive(Debug, Clone)] @@ -43,6 +46,18 @@ impl DependencyTemplate for ConstDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.start.dyn_hash(hasher); + self.end.dyn_hash(hasher); + self.content.dyn_hash(hasher); + self.runtime_requirements.dyn_hash(hasher); + } } impl AsDependency for ConstDependency {} diff --git a/crates/rspack_core/src/dependency/dependency_template.rs b/crates/rspack_core/src/dependency/dependency_template.rs index 841f9166158..ec638bedbb0 100644 --- a/crates/rspack_core/src/dependency/dependency_template.rs +++ b/crates/rspack_core/src/dependency/dependency_template.rs @@ -50,6 +50,13 @@ pub trait DependencyTemplate: Debug + DynClone + Sync + Send + AsDependency + As ); fn dependency_id(&self) -> Option; + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ); } pub type BoxDependencyTemplate = Box; diff --git a/crates/rspack_core/src/dependency/runtime_requirements_dependency.rs b/crates/rspack_core/src/dependency/runtime_requirements_dependency.rs index 882db057562..70864325aef 100644 --- a/crates/rspack_core/src/dependency/runtime_requirements_dependency.rs +++ b/crates/rspack_core/src/dependency/runtime_requirements_dependency.rs @@ -1,5 +1,8 @@ +use rspack_util::ext::DynHash; + use crate::{ - AsDependency, DependencyTemplate, RuntimeGlobals, TemplateContext, TemplateReplaceSource, + AsDependency, Compilation, DependencyTemplate, RuntimeGlobals, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; #[derive(Debug, Eq, PartialEq, Clone, Hash)] @@ -21,6 +24,15 @@ impl DependencyTemplate for RuntimeRequirementsDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.runtime_requirements.dyn_hash(hasher); + } } impl AsDependency for RuntimeRequirementsDependency {} diff --git a/crates/rspack_core/src/exports_info.rs b/crates/rspack_core/src/exports_info.rs index ba2d4e18e8e..26cfd1cbc8d 100644 --- a/crates/rspack_core/src/exports_info.rs +++ b/crates/rspack_core/src/exports_info.rs @@ -1,42 +1,27 @@ use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::BTreeMap; -use std::hash::Hasher; use std::sync::atomic::AtomicU32; use std::sync::atomic::Ordering::Relaxed; use std::sync::Arc; -use std::sync::LazyLock; use either::Either; use itertools::Itertools; use rspack_collections::impl_item_ukey; use rspack_collections::Ukey; -use rspack_collections::UkeyDashMap; use rspack_collections::UkeySet; use rspack_util::atom::Atom; use rspack_util::ext::DynHash; use rustc_hash::FxHashMap as HashMap; use rustc_hash::FxHashSet as HashSet; -use rustc_hash::FxHasher; use serde::Serialize; +use crate::Compilation; use crate::{ property_access, ConnectionState, DependencyCondition, DependencyId, ModuleGraph, ModuleIdentifier, Nullable, RuntimeSpec, }; -pub trait ExportsHash { - fn export_info_hash( - &self, - hasher: &mut dyn Hasher, - module_graph: &ModuleGraph, - already_visited: &mut UkeySet, - ); -} - -static EXPORTS_INFO_HASH: LazyLock> = - LazyLock::new(UkeyDashMap::default); - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize)] pub struct ExportsInfo(Ukey); @@ -44,19 +29,6 @@ static NEXT_EXPORTS_INFO_UKEY: AtomicU32 = AtomicU32::new(0); impl_item_ukey!(ExportsInfo); -impl ExportsHash for ExportsInfo { - fn export_info_hash( - &self, - hasher: &mut dyn Hasher, - module_graph: &ModuleGraph, - already_visited: &mut UkeySet, - ) { - if let Some(exports_info) = module_graph.try_get_exports_info_by_id(self) { - exports_info.export_info_hash(hasher, module_graph, already_visited); - } - } -} - impl ExportsInfo { #[allow(clippy::new_without_default)] pub fn new() -> Self { @@ -720,6 +692,42 @@ impl ExportsInfo { } false } + + pub fn update_hash( + &self, + mg: &ModuleGraph, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) { + self.update_hash_with_visited(mg, hasher, compilation, runtime, &mut UkeySet::default()); + } + + fn update_hash_with_visited( + &self, + mg: &ModuleGraph, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + visited: &mut UkeySet, + ) { + visited.insert(*self); + let data = self.as_exports_info(mg); + for export_info in self.ordered_exports(mg) { + if export_info.has_info(mg, data.other_exports_info, runtime) { + export_info.update_hash_with_visited(mg, hasher, compilation, runtime, visited); + } + } + data + .side_effects_only_info + .update_hash_with_visited(mg, hasher, compilation, runtime, visited); + data + .other_exports_info + .update_hash_with_visited(mg, hasher, compilation, runtime, visited); + if let Some(redirect_to) = data.redirect_to { + redirect_to.update_hash_with_visited(mg, hasher, compilation, runtime, visited); + } + } } #[derive(Debug, Clone)] @@ -731,38 +739,6 @@ pub struct ExportsInfoData { id: ExportsInfo, } -impl ExportsHash for ExportsInfoData { - fn export_info_hash( - &self, - hasher: &mut dyn Hasher, - module_graph: &ModuleGraph, - already_visited: &mut UkeySet, - ) { - if let Some(hash) = EXPORTS_INFO_HASH.get(&self.id) { - hash.dyn_hash(hasher); - return; - }; - let mut default_hash = FxHasher::default(); - for (name, export_info_id) in &self.exports { - name.dyn_hash(&mut default_hash); - export_info_id.export_info_hash(&mut default_hash, module_graph, already_visited); - } - self - .other_exports_info - .export_info_hash(&mut default_hash, module_graph, already_visited); - self - .side_effects_only_info - .export_info_hash(&mut default_hash, module_graph, already_visited); - - if let Some(redirect_to) = self.redirect_to { - redirect_to.export_info_hash(&mut default_hash, module_graph, already_visited); - } - let hash = default_hash.finish(); - EXPORTS_INFO_HASH.insert(self.id, hash); - hash.dyn_hash(hasher); - } -} - pub enum ProvidedExports { Null, True, @@ -830,24 +806,6 @@ static NEXT_EXPORT_INFO_UKEY: AtomicU32 = AtomicU32::new(0); impl_item_ukey!(ExportInfo); -impl ExportsHash for ExportInfo { - fn export_info_hash( - &self, - hasher: &mut dyn Hasher, - module_graph: &ModuleGraph, - already_visited: &mut UkeySet, - ) { - if already_visited.contains(self) { - return; - } - already_visited.insert(*self); - - if let Some(export_info) = module_graph.try_get_export_info_by_id(self) { - export_info.export_info_hash(hasher, module_graph, already_visited); - } - } -} - impl ExportInfo { fn new() -> Self { Self(NEXT_EXPORT_INFO_UKEY.fetch_add(1, Relaxed).into()) @@ -1545,13 +1503,49 @@ impl ExportInfo { } } } + + pub fn has_info( + &self, + mg: &ModuleGraph, + base_info: ExportInfo, + runtime: Option<&RuntimeSpec>, + ) -> bool { + let data = self.as_export_info(mg); + data.used_name.is_some() + || data.provided.is_some() + || data.terminal_binding + || (self.get_used(mg, runtime) != base_info.get_used(mg, runtime)) + } + + fn update_hash_with_visited( + &self, + mg: &ModuleGraph, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + visited: &mut UkeySet, + ) { + let data = self.as_export_info(mg); + if let Some(used_name) = &data.used_name { + used_name.dyn_hash(hasher); + } else { + data.name.dyn_hash(hasher); + } + self.get_used(mg, runtime).dyn_hash(hasher); + data.provided.dyn_hash(hasher); + data.terminal_binding.dyn_hash(hasher); + if let Some(exports_info) = data.exports_info + && !visited.contains(&exports_info) + { + exports_info.update_hash_with_visited(mg, hasher, compilation, runtime, visited); + } + } } #[derive(Debug, Clone)] pub struct ExportInfoData { // the name could be `null` you could refer https://github.com/webpack/webpack/blob/ac7e531436b0d47cd88451f497cdfd0dad4153d/lib/ExportsInfo.js#L78 name: Option, - usage_state: UsageState, /// this is mangled name, https://github.com/webpack/webpack/blob/1f99ad6367f2b8a6ef17cce0e058f7a67fb7db18/lib/ExportsInfo.js#L1181-L1188 used_name: Option, target: HashMap, ExportInfoTargetValue>, @@ -1569,31 +1563,6 @@ pub struct ExportInfoData { used_in_runtime: Option, UsageState>>, } -impl ExportsHash for ExportInfoData { - fn export_info_hash( - &self, - hasher: &mut dyn Hasher, - module_graph: &ModuleGraph, - already_visited: &mut UkeySet, - ) { - self.name.dyn_hash(hasher); - self.usage_state.dyn_hash(hasher); - self.used_name.dyn_hash(hasher); - for (name, value) in &self.target { - name.dyn_hash(hasher); - value.dyn_hash(hasher); - } - self.provided.dyn_hash(hasher); - self.can_mangle_provide.dyn_hash(hasher); - self.terminal_binding.dyn_hash(hasher); - self.target_is_set.dyn_hash(hasher); - if let Some(exports_info_id) = self.exports_info { - exports_info_id.export_info_hash(hasher, module_graph, already_visited); - } - self.exports_info_owned.dyn_hash(hasher); - } -} - #[derive(Debug, Hash, Clone, Copy)] pub enum ExportInfoProvided { True, @@ -1711,7 +1680,6 @@ impl ExportInfoData { .unwrap_or_default(); Self { name, - usage_state: UsageState::Unknown, used_name, used_in_runtime, target, diff --git a/crates/rspack_core/src/external_module.rs b/crates/rspack_core/src/external_module.rs index e259e7638e3..0376a6fcfdf 100644 --- a/crates/rspack_core/src/external_module.rs +++ b/crates/rspack_core/src/external_module.rs @@ -1,17 +1,15 @@ use std::borrow::Cow; -use std::hash::Hash; use std::iter; use rspack_collections::{Identifiable, Identifier}; use rspack_error::{error, impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_macros::impl_source_map_config; -use rspack_util::{json_stringify, source_map::SourceMapKind}; +use rspack_util::{ext::DynHash, json_stringify, source_map::SourceMapKind}; use rustc_hash::{FxHashMap as HashMap, FxHashSet}; use serde::Serialize; use crate::{ - extract_url_and_global, impl_module_meta_info, property_access, + extract_url_and_global, impl_module_meta_info, module_update_hash, property_access, rspack_sources::{BoxSource, RawSource, Source, SourceExt}, to_identifier, AsyncDependenciesBlockIdentifier, BuildContext, BuildInfo, BuildMeta, BuildMetaExportsType, BuildResult, ChunkInitFragments, ChunkUkey, CodeGenerationDataUrl, @@ -452,15 +450,12 @@ impl Module for ExternalModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); let (_, external_type) = self.get_request_and_external_type(); let build_info = BuildInfo { - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), top_level_declarations: Some(FxHashSet::default()), strict: true, ..Default::default() @@ -500,6 +495,7 @@ impl Module for ExternalModule { Ok(build_result) } + #[tracing::instrument(name = "ExternalModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -559,21 +555,19 @@ impl Module for ExternalModule { fn lib_ident(&self, _options: LibIdentOptions) -> Option> { Some(Cow::Borrowed(self.user_request.as_str())) } -} - -impl_empty_diagnosable_trait!(ExternalModule); -impl Hash for ExternalModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__ExternalModule".hash(state); - self.identifier().hash(state); - } -} - -impl PartialEq for ExternalModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + self.id.dyn_hash(hasher); + let is_optional = compilation.get_module_graph().is_optional(&self.id); + is_optional.dyn_hash(hasher); + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for ExternalModule {} +impl_empty_diagnosable_trait!(ExternalModule); diff --git a/crates/rspack_core/src/lib.rs b/crates/rspack_core/src/lib.rs index ddb6dfce3d0..d8a6fcbd4b7 100644 --- a/crates/rspack_core/src/lib.rs +++ b/crates/rspack_core/src/lib.rs @@ -9,7 +9,6 @@ use std::{fmt, sync::Arc}; mod dependencies_block; pub mod diagnostics; -mod update_hash; pub use dependencies_block::{ AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, DependenciesBlock, DependencyLocation, }; diff --git a/crates/rspack_core/src/module.rs b/crates/rspack_core/src/module.rs index 98c9e0a5860..f40f157c595 100644 --- a/crates/rspack_core/src/module.rs +++ b/crates/rspack_core/src/module.rs @@ -7,14 +7,15 @@ use async_trait::async_trait; use json::JsonValue; use rspack_collections::{Identifiable, Identifier, IdentifierSet}; use rspack_error::{Diagnosable, Diagnostic, Result}; -use rspack_hash::{RspackHash, RspackHashDigest}; +use rspack_hash::RspackHashDigest; use rspack_sources::Source; use rspack_util::atom::Atom; -use rspack_util::ext::{AsAny, DynEq, DynHash}; +use rspack_util::ext::{AsAny, DynHash}; use rspack_util::source_map::ModuleSourceMapConfig; use rustc_hash::FxHashSet as HashSet; use crate::concatenated_module::ConcatenatedModule; +use crate::dependencies_block::dependencies_block_update_hash; use crate::{ AsyncDependenciesBlock, BoxDependency, ChunkGraph, ChunkUkey, CodeGenerationResult, Compilation, CompilerOptions, ConcatenationScope, ConnectionState, Context, ContextModule, DependenciesBlock, @@ -22,6 +23,7 @@ use crate::{ ModuleGraph, ModuleLayer, ModuleType, NormalModule, RawModule, Resolve, RunnerContext, RuntimeSpec, SelfModule, SharedPluginDriver, SourceType, }; + pub struct BuildContext<'a> { pub runner_context: RunnerContext, pub plugin_driver: SharedPluginDriver, @@ -174,8 +176,6 @@ pub trait Module: + Sync + Any + AsAny - + DynHash - + DynEq + Identifiable + DependenciesBlock + Diagnosable @@ -201,19 +201,11 @@ pub trait Module: /// Build can also returns the dependencies of the module, which will be used by the `Compilation` to build the dependency graph. async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _compilation: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - - let build_info = BuildInfo { - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), - ..Default::default() - }; - Ok(BuildResult { - build_info, + build_info: Default::default(), build_meta: Default::default(), dependencies: Vec::new(), blocks: Vec::new(), @@ -280,10 +272,16 @@ pub trait Module: None } - /// Apply module hash to the provided hasher. - fn update_hash(&self, state: &mut dyn std::hash::Hasher) { - self.dyn_hash(state); - } + /// Update hash for cgm.hash (chunk graph module hash) + /// Different cgm code generation result should have different cgm.hash, + /// so this also accept compilation (mainly chunk graph) and runtime as args. + /// (Difference with `impl Hash for Module`: this is just a part for calculating cgm.hash, not for Module itself) + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()>; fn lib_ident(&self, _options: LibIdentOptions) -> Option> { // Align with https://github.com/webpack/webpack/blob/4b4ca3bb53f36a5b8fc6bc1bd976ed7af161bd80/lib/Module.js#L845 @@ -469,6 +467,30 @@ fn get_exports_type_impl( } } +pub fn module_update_hash( + module: &dyn Module, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, +) { + let chunk_graph = &compilation.chunk_graph; + chunk_graph + .get_module_graph_hash(module, compilation, runtime) + .dyn_hash(hasher); + if let Some(deps) = module.get_presentational_dependencies() { + for dep in deps { + dep.update_hash(hasher, compilation, runtime); + } + } + dependencies_block_update_hash( + module.get_dependencies(), + module.get_blocks(), + hasher, + compilation, + runtime, + ); +} + pub trait ModuleExt { fn boxed(self) -> Box; } @@ -489,20 +511,6 @@ impl Identifiable for Box { } } -impl PartialEq for dyn Module { - fn eq(&self, other: &Self) -> bool { - self.dyn_eq(other.as_any()) - } -} - -impl Eq for dyn Module {} - -impl Hash for dyn Module { - fn hash(&self, state: &mut H) { - self.dyn_hash(state) - } -} - impl dyn Module { pub fn downcast_ref(&self) -> Option<&T> { self.as_any().downcast_ref::() @@ -590,7 +598,6 @@ pub struct LibIdentOptions<'me> { #[cfg(test)] mod test { use std::borrow::Cow; - use std::hash::Hash; use rspack_collections::{Identifiable, Identifier}; use rspack_error::{Diagnosable, Diagnostic, Result}; @@ -604,36 +611,12 @@ mod test { RuntimeSpec, SourceType, }; - #[derive(Debug, Eq)] + #[derive(Debug)] struct RawModule(&'static str); - impl PartialEq for RawModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() - } - } - - #[derive(Debug, Eq)] + #[derive(Debug)] struct ExternalModule(&'static str); - impl PartialEq for ExternalModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() - } - } - - impl Hash for RawModule { - fn hash(&self, state: &mut H) { - self.identifier().hash(state); - } - } - - impl Hash for ExternalModule { - fn hash(&self, state: &mut H) { - self.identifier().hash(state); - } - } - macro_rules! impl_noop_trait_module_type { ($ident: ident) => { impl Identifiable for $ident { @@ -696,6 +679,15 @@ mod test { vec![] } + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + unreachable!() + } + fn code_generation( &self, _compilation: &Compilation, @@ -757,40 +749,4 @@ mod test { assert!(a.downcast_ref::().is_some()); assert!(b.downcast_ref::().is_some()); } - - #[test] - fn hash_should_work() { - let e1: Box = ExternalModule("e").boxed(); - let e2: Box = ExternalModule("e").boxed(); - - let mut state1 = rspack_hash::RspackHash::new(&rspack_hash::HashFunction::Xxhash64); - let mut state2 = rspack_hash::RspackHash::new(&rspack_hash::HashFunction::Xxhash64); - e1.hash(&mut state1); - e2.hash(&mut state2); - - let hash1 = state1.digest(&rspack_hash::HashDigest::Hex); - let hash2 = state2.digest(&rspack_hash::HashDigest::Hex); - assert_eq!(hash1, hash2); - - let e3: Box = ExternalModule("e3").boxed(); - let mut state3 = rspack_hash::RspackHash::new(&rspack_hash::HashFunction::Xxhash64); - e3.hash(&mut state3); - - let hash3 = state3.digest(&rspack_hash::HashDigest::Hex); - assert_ne!(hash1, hash3); - } - - #[test] - fn eq_should_work() { - let e1 = ExternalModule("e"); - let e2 = ExternalModule("e"); - - assert_eq!(e1, e2); - assert_eq!(&e1.boxed(), &e2.boxed()); - - let r1 = RawModule("r1"); - let r2 = RawModule("r2"); - assert_ne!(r1, r2); - assert_ne!(&r1.boxed(), &r2.boxed()); - } } diff --git a/crates/rspack_core/src/normal_module.rs b/crates/rspack_core/src/normal_module.rs index 6e88213ac63..b292f1196ce 100644 --- a/crates/rspack_core/src/normal_module.rs +++ b/crates/rspack_core/src/normal_module.rs @@ -13,7 +13,7 @@ use dashmap::DashMap; use derivative::Derivative; use rspack_collections::{Identifiable, IdentifierSet}; use rspack_error::{error, Diagnosable, Diagnostic, DiagnosticExt, NodeError, Result, Severity}; -use rspack_hash::RspackHash; +use rspack_hash::{RspackHash, RspackHashDigest}; use rspack_hook::define_hook; use rspack_loader_runner::{run_loaders, AdditionalData, Content, LoaderContext, ResourceData}; use rspack_macros::impl_source_map_config; @@ -21,19 +21,22 @@ use rspack_sources::{ BoxSource, CachedSource, OriginalSource, RawSource, Source, SourceExt, SourceMap, SourceMapSource, WithoutOriginalOptions, }; -use rspack_util::source_map::{ModuleSourceMapConfig, SourceMapKind}; +use rspack_util::{ + ext::DynHash, + source_map::{ModuleSourceMapConfig, SourceMapKind}, +}; use rustc_hash::FxHasher; use serde_json::json; use crate::{ add_connection_states, contextify, diagnostics::ModuleBuildError, get_context, - impl_module_meta_info, AsyncDependenciesBlockIdentifier, BoxLoader, BoxModule, BuildContext, - BuildInfo, BuildMeta, BuildResult, ChunkGraph, CodeGenerationResult, Compilation, - ConcatenationScope, ConnectionState, Context, DependenciesBlock, DependencyId, + impl_module_meta_info, module_update_hash, AsyncDependenciesBlockIdentifier, BoxLoader, + BoxModule, BuildContext, BuildInfo, BuildMeta, BuildResult, ChunkGraph, CodeGenerationResult, + Compilation, ConcatenationScope, ConnectionState, Context, DependenciesBlock, DependencyId, DependencyTemplate, FactoryMeta, GenerateContext, GeneratorOptions, LibIdentOptions, Module, - ModuleDependency, ModuleGraph, ModuleIdentifier, ModuleLayer, ModuleType, ParseContext, - ParseResult, ParserAndGenerator, ParserOptions, Resolve, RspackLoaderRunnerPlugin, RunnerContext, - RuntimeGlobals, RuntimeSpec, SourceType, + ModuleDependency, ModuleGraph, ModuleIdentifier, ModuleLayer, ModuleType, OutputOptions, + ParseContext, ParseResult, ParserAndGenerator, ParserOptions, Resolve, RspackLoaderRunnerPlugin, + RunnerContext, RuntimeGlobals, RuntimeSpec, SourceType, }; bitflags! { @@ -303,6 +306,27 @@ impl NormalModule { ) -> &mut Option>> { &mut self.presentational_dependencies } + + fn init_build_hash( + &self, + output_options: &OutputOptions, + build_meta: &BuildMeta, + ) -> RspackHashDigest { + let mut hasher = RspackHash::from(output_options); + "source".hash(&mut hasher); + match &self.source { + NormalModuleSource::Unbuild => panic!("NormalModule should already build"), + NormalModuleSource::BuiltSucceed(s) => s.hash(&mut hasher), + NormalModuleSource::BuiltFailed(e) => e.message().hash(&mut hasher), + } + "meta".hash(&mut hasher); + build_meta.hash(&mut hasher); + hasher.digest(&output_options.hash_digest) + } + + pub fn get_generator_options(&self) -> Option<&GeneratorOptions> { + self.generator_options.as_ref() + } } impl Identifiable for NormalModule { @@ -417,13 +441,12 @@ impl Module for NormalModule { .with_hide_stack(hide_stack); self.source = NormalModuleSource::BuiltFailed(d.clone()); self.add_diagnostic(d); - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - build_meta.hash(&mut hasher); - build_info.hash = Some(hasher.digest(&build_context.compiler_options.output.hash_digest)); + + build_info.hash = + Some(self.init_build_hash(&build_context.compiler_options.output, &build_meta)); return Ok(BuildResult { build_info, - build_meta: Default::default(), + build_meta, dependencies: Vec::new(), blocks: Vec::new(), optimization_bailouts: vec![], @@ -452,11 +475,8 @@ impl Module for NormalModule { self.code_generation_dependencies = Some(Vec::new()); self.presentational_dependencies = Some(Vec::new()); - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - build_meta.hash(&mut hasher); - - build_info.hash = Some(hasher.digest(&build_context.compiler_options.output.hash_digest)); + build_info.hash = + Some(self.init_build_hash(&build_context.compiler_options.output, &build_meta)); build_info.cacheable = loader_result.cacheable; build_info.file_dependencies = loader_result.file_dependencies; build_info.context_dependencies = loader_result.context_dependencies; @@ -529,11 +549,8 @@ impl Module for NormalModule { self.code_generation_dependencies = Some(code_generation_dependencies); self.presentational_dependencies = Some(presentational_dependencies); - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - build_meta.hash(&mut hasher); - - build_info.hash = Some(hasher.digest(&build_context.compiler_options.output.hash_digest)); + build_info.hash = + Some(self.init_build_hash(&build_context.compiler_options.output, &build_meta)); Ok(BuildResult { build_info, @@ -544,6 +561,7 @@ impl Module for NormalModule { }) } + #[tracing::instrument(name = "NormalModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -569,7 +587,6 @@ impl Module for NormalModule { self, &mut GenerateContext { compilation, - module_generator_options: self.generator_options.as_ref(), runtime_requirements: &mut code_generation_result.runtime_requirements, data: &mut code_generation_result.data, requested_source_type: *source_type, @@ -612,6 +629,28 @@ impl Module for NormalModule { } } + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + self + .build_info + .as_ref() + .expect("should update_hash after build") + .hash + .dyn_hash(hasher); + // For built failed NormalModule, hash will be calculated by build_info.hash, which contains error message + if matches!(&self.source, NormalModuleSource::BuiltSucceed(_)) { + self + .parser_and_generator + .update_hash(self, hasher, compilation, runtime)?; + } + module_update_hash(self, hasher, compilation, runtime); + Ok(()) + } + fn name_for_condition(&self) -> Option> { // Align with https://github.com/webpack/webpack/blob/8241da7f1e75c5581ba535d127fa66aeb9eb2ac8/lib/NormalModule.js#L375 let resource = self.resource_data.resource.as_str(); @@ -742,14 +781,6 @@ impl Diagnosable for NormalModule { } } -impl PartialEq for NormalModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() - } -} - -impl Eq for NormalModule {} - impl NormalModule { fn create_source(&self, content: Content, source_map: Option) -> Result { if content.is_buffer() { @@ -785,12 +816,3 @@ impl NormalModule { .clear() } } - -impl Hash for NormalModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__NormalModule".hash(state); - if let Some(original_source) = &self.original_source { - original_source.hash(state); - } - } -} diff --git a/crates/rspack_core/src/old_cache/occasion/code_generate.rs b/crates/rspack_core/src/old_cache/occasion/code_generate.rs index 39af9d70758..e824c2d4f73 100644 --- a/crates/rspack_core/src/old_cache/occasion/code_generate.rs +++ b/crates/rspack_core/src/old_cache/occasion/code_generate.rs @@ -1,10 +1,10 @@ use rspack_collections::Identifier; use rspack_error::Result; -use crate::{get_runtime_key, RuntimeSpec, RuntimeSpecSet}; -use crate::{old_cache::storage, BoxModule, CodeGenerationResult, Compilation, NormalModuleSource}; +use crate::{old_cache::storage, CodeGenerationResult}; +use crate::{CodeGenerationJob, ModuleIdentifier, RuntimeSpec}; -type Storage = dyn storage::Storage>; +type Storage = dyn storage::Storage; #[derive(Debug)] pub struct CodeGenerateOccasion { @@ -16,56 +16,25 @@ impl CodeGenerateOccasion { Self { storage } } - pub fn use_cache<'a, G>( + pub fn use_cache( &self, - module: &'a BoxModule, - runtimes: RuntimeSpecSet, - compilation: &Compilation, - generator: G, - ) -> Result<(Vec<(CodeGenerationResult, RuntimeSpec)>, bool)> - where - G: Fn(&'a BoxModule, RuntimeSpecSet) -> Result>, - { + job: CodeGenerationJob, + provide: impl Fn(ModuleIdentifier, &RuntimeSpec) -> Result, + ) -> Result<(CodeGenerationResult, Vec, bool)> { let storage = match &self.storage { Some(s) => s, - // no cache return directly - None => return Ok((generator(module, runtimes)?, false)), - }; - - let mut cache_id = None; - - if let Some(normal_module) = module.as_normal_module() { - // only cache normal module - // TODO: cache all module type - let mut id = String::default(); - for runtime in runtimes.values() { - id.push_str(&compilation.chunk_graph.get_module_graph_hash( - module, - compilation, - Some(runtime), - true, - )); - id.push_str(&get_runtime_key(runtime.clone())); - } - let id = Identifier::from(id); - - // currently no need to separate module hash by runtime - if let Some(data) = storage.get(&id) { - return Ok((data, true)); + None => { + let res = provide(job.module, &job.runtime)?; + return Ok((res, job.runtimes, false)); } - - if matches!(normal_module.source(), NormalModuleSource::Unbuild) { - // unbuild and no cache is unexpected - panic!("unexpected unbuild module"); - } - cache_id = Some(id); - } - - // run generator and save to cache - let data = generator(module, runtimes)?; - if let Some(id) = cache_id { - storage.set(id, data.clone()); + }; + let cache_key = Identifier::from(format!("{}|{}", job.module, job.hash.encoded())); + if let Some(value) = storage.get(&cache_key) { + Ok((value, job.runtimes, true)) + } else { + let res = provide(job.module, &job.runtime)?; + storage.set(cache_key, res.clone()); + Ok((res, job.runtimes, false)) } - Ok((data, false)) } } diff --git a/crates/rspack_core/src/options/module.rs b/crates/rspack_core/src/options/module.rs index 43fbb641689..3318d43c20d 100644 --- a/crates/rspack_core/src/options/module.rs +++ b/crates/rspack_core/src/options/module.rs @@ -387,13 +387,13 @@ impl MergeFrom for AssetGeneratorDataUrl { } } -#[derive(Debug, Clone, MergeFrom)] +#[derive(Debug, Clone, MergeFrom, Hash)] pub struct AssetGeneratorDataUrlOptions { pub encoding: Option, pub mimetype: Option, } -#[derive(Debug, Clone, MergeFrom)] +#[derive(Debug, Clone, MergeFrom, Hash)] pub enum DataUrlEncoding { None, Base64, diff --git a/crates/rspack_core/src/parser_and_generator.rs b/crates/rspack_core/src/parser_and_generator.rs index cbfb2651bda..271999144ec 100644 --- a/crates/rspack_core/src/parser_and_generator.rs +++ b/crates/rspack_core/src/parser_and_generator.rs @@ -12,9 +12,8 @@ use swc_core::common::Span; use crate::{ AsyncDependenciesBlock, BoxDependency, BoxLoader, BuildInfo, BuildMeta, CodeGenerationData, - Compilation, CompilerOptions, DependencyTemplate, GeneratorOptions, Module, ModuleDependency, - ModuleIdentifier, ModuleLayer, ModuleType, ParserOptions, RuntimeGlobals, RuntimeSpec, - SourceType, + Compilation, CompilerOptions, DependencyTemplate, Module, ModuleDependency, ModuleIdentifier, + ModuleLayer, ModuleType, NormalModule, ParserOptions, RuntimeGlobals, RuntimeSpec, SourceType, }; use crate::{ChunkGraph, ConcatenationScope, Context, ModuleGraph}; @@ -77,7 +76,6 @@ pub struct ParseResult { #[derive(Debug)] pub struct GenerateContext<'a> { pub compilation: &'a Compilation, - pub module_generator_options: Option<&'a GeneratorOptions>, pub runtime_requirements: &'a mut RuntimeGlobals, pub data: &'a mut CodeGenerationData, pub requested_source_type: SourceType, @@ -106,6 +104,16 @@ pub trait ParserAndGenerator: Send + Sync + Debug + AsAny { _mg: &ModuleGraph, _cg: &ChunkGraph, ) -> Option>; + + fn update_hash( + &self, + _module: &NormalModule, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + Ok(()) + } } impl dyn ParserAndGenerator + '_ { diff --git a/crates/rspack_core/src/raw_module.rs b/crates/rspack_core/src/raw_module.rs index 2d7db6b9ea0..56210cbb336 100644 --- a/crates/rspack_core/src/raw_module.rs +++ b/crates/rspack_core/src/raw_module.rs @@ -1,9 +1,7 @@ use std::borrow::Cow; -use std::hash::Hash; use rspack_collections::Identifiable; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_macros::impl_source_map_config; use rspack_sources::{BoxSource, RawSource, Source, SourceExt}; use rspack_util::source_map::SourceMapKind; @@ -13,7 +11,7 @@ use crate::{ BuildInfo, BuildMeta, BuildResult, CodeGenerationResult, Context, DependenciesBlock, DependencyId, Module, ModuleIdentifier, ModuleType, RuntimeGlobals, RuntimeSpec, SourceType, }; -use crate::{Compilation, ConcatenationScope, FactoryMeta}; +use crate::{module_update_hash, Compilation, ConcatenationScope, FactoryMeta}; #[impl_source_map_config] #[derive(Debug)] @@ -108,14 +106,11 @@ impl Module for RawModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); Ok(BuildResult { build_info: BuildInfo { - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), cacheable: true, strict: true, ..Default::default() @@ -125,6 +120,7 @@ impl Module for RawModule { }) } + #[tracing::instrument(name = "RawModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &crate::Compilation, @@ -141,22 +137,17 @@ impl Module for RawModule { ); Ok(cgr) } -} - -impl_empty_diagnosable_trait!(RawModule); - -impl Hash for RawModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__RawModule".hash(state); - self.identifier().hash(state); - self.source.hash(state); - } -} -impl PartialEq for RawModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + self.source.dyn_hash(hasher); + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for RawModule {} +impl_empty_diagnosable_trait!(RawModule); diff --git a/crates/rspack_core/src/runtime.rs b/crates/rspack_core/src/runtime.rs index f44a04ce388..bf3e8f31e5a 100644 --- a/crates/rspack_core/src/runtime.rs +++ b/crates/rspack_core/src/runtime.rs @@ -287,6 +287,15 @@ pub struct RuntimeSpecMap { } impl RuntimeSpecMap { + pub fn new() -> Self { + Self { + mode: RuntimeMode::Empty, + map: Default::default(), + single_runtime: None, + single_value: None, + } + } + pub fn size(&self) -> usize { let mode = self.mode as usize; diff --git a/crates/rspack_core/src/runtime_module.rs b/crates/rspack_core/src/runtime_module.rs index 7ff99da87bd..9d528a30895 100644 --- a/crates/rspack_core/src/runtime_module.rs +++ b/crates/rspack_core/src/runtime_module.rs @@ -41,7 +41,7 @@ pub trait CustomSourceRuntimeModule { pub type BoxRuntimeModule = Box; -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RuntimeModuleStage { Normal, // Runtime modules without any dependencies to other runtime modules Basic, // Runtime modules with simple dependencies on other runtime modules diff --git a/crates/rspack_core/src/self_module.rs b/crates/rspack_core/src/self_module.rs index 4a26bf9a440..fedc417fea9 100644 --- a/crates/rspack_core/src/self_module.rs +++ b/crates/rspack_core/src/self_module.rs @@ -1,10 +1,8 @@ use std::borrow::Cow; -use std::hash::Hash; use async_trait::async_trait; use rspack_collections::{Identifiable, Identifier}; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_macros::impl_source_map_config; use rspack_sources::Source; use rspack_util::source_map::SourceMapKind; @@ -106,15 +104,11 @@ impl Module for SelfModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let build_info = BuildInfo { strict: true, - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), ..Default::default() }; @@ -127,7 +121,7 @@ impl Module for SelfModule { }) } - #[allow(clippy::unwrap_in_result)] + #[tracing::instrument(name = "SelfModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, _compilation: &Compilation, @@ -136,21 +130,16 @@ impl Module for SelfModule { ) -> Result { Ok(CodeGenerationResult::default()) } -} - -impl_empty_diagnosable_trait!(SelfModule); -impl Hash for SelfModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__SelfModule".hash(state); - self.identifier().hash(state); - } -} - -impl PartialEq for SelfModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + // do nothing, since this is self reference, the module itself (parent module of this self module) should take effects + Ok(()) } } -impl Eq for SelfModule {} +impl_empty_diagnosable_trait!(SelfModule); diff --git a/crates/rspack_core/src/update_hash.rs b/crates/rspack_core/src/update_hash.rs deleted file mode 100644 index 7b7f47bc70d..00000000000 --- a/crates/rspack_core/src/update_hash.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::hash::Hasher; - -use crate::{Compilation, RuntimeSpec}; - -#[allow(dead_code)] -pub struct UpdateHashContext<'a> { - pub compilation: &'a Compilation, - pub runtime: Option<&'a RuntimeSpec>, -} - -pub trait UpdateRspackHash { - fn update_hash(&self, state: &mut H, context: &UpdateHashContext); -} diff --git a/crates/rspack_hash/src/lib.rs b/crates/rspack_hash/src/lib.rs index 31b842e8db8..5552e71e763 100644 --- a/crates/rspack_hash/src/lib.rs +++ b/crates/rspack_hash/src/lib.rs @@ -56,7 +56,7 @@ impl From> for HashSalt { #[derive(Clone)] pub enum RspackHash { Xxhash64(Box), - MD4(md4::Md4), + MD4(Box), } impl fmt::Debug for RspackHash { @@ -72,7 +72,7 @@ impl RspackHash { pub fn new(function: &HashFunction) -> Self { match function { HashFunction::Xxhash64 => Self::Xxhash64(Box::new(Xxh64::new(0))), - HashFunction::MD4 => Self::MD4(md4::Md4::new()), + HashFunction::MD4 => Self::MD4(Box::new(md4::Md4::new())), } } diff --git a/crates/rspack_macros/src/runtime_module.rs b/crates/rspack_macros/src/runtime_module.rs index e7213072b5e..a73613ad299 100644 --- a/crates/rspack_macros/src/runtime_module.rs +++ b/crates/rspack_macros/src/runtime_module.rs @@ -87,20 +87,6 @@ pub fn impl_runtime_module( } } - impl #impl_generics PartialEq for #name #ty_generics #where_clause { - fn eq(&self, other: &Self) -> bool { - self.name() == other.name() - } - } - - impl #impl_generics Eq for #name #ty_generics #where_clause {} - - impl #impl_generics std::hash::Hash for #name #ty_generics #where_clause { - fn hash(&self, _state: &mut H) { - unreachable!() - } - } - impl #impl_generics ::rspack_core::DependenciesBlock for #name #ty_generics #where_clause { fn add_block_id(&mut self, _: ::rspack_core::AsyncDependenciesBlockIdentifier) { unreachable!() @@ -177,6 +163,19 @@ pub fn impl_runtime_module( ); Ok(result) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &::rspack_core::Compilation, + _runtime: Option<&::rspack_core::RuntimeSpec>, + ) -> ::rspack_error::Result<()> { + use rspack_util::ext::DynHash; + self.name().dyn_hash(hasher); + self.stage().dyn_hash(hasher); + self.get_generated_code(compilation)?.dyn_hash(hasher); + Ok(()) + } } impl #impl_generics rspack_error::Diagnosable for #name #ty_generics #where_clause {} diff --git a/crates/rspack_macros_test/tests/runtime_module.rs b/crates/rspack_macros_test/tests/runtime_module.rs index 7188b83b328..b8926bd6dfb 100644 --- a/crates/rspack_macros_test/tests/runtime_module.rs +++ b/crates/rspack_macros_test/tests/runtime_module.rs @@ -1,8 +1,7 @@ -use std::{marker::PhantomData, sync::Arc}; +use std::marker::PhantomData; use rspack_collections::Identifier; -use rspack_core::{rspack_sources::Source, Compilation}; -use rspack_error::Result; +use rspack_core::{rspack_sources::Source, Compilation, RuntimeModule}; use rspack_macros::impl_runtime_module; #[allow(dead_code)] @@ -14,11 +13,15 @@ fn with_generic() { marker: PhantomData, } - impl Foo { + impl RuntimeModule for Foo { fn name(&self) -> Identifier { - String::new().into() + todo!() } - fn generate_with_custom(&self, _compilation: &Compilation) -> Result> { + + fn generate( + &self, + _: &Compilation, + ) -> rspack_error::Result { todo!() } } diff --git a/crates/rspack_plugin_asset/src/lib.rs b/crates/rspack_plugin_asset/src/lib.rs index bd5c8529cc9..e4a8736e57c 100644 --- a/crates/rspack_plugin_asset/src/lib.rs +++ b/crates/rspack_plugin_asset/src/lib.rs @@ -6,17 +6,18 @@ use async_trait::async_trait; use rayon::prelude::*; use rspack_core::{ rspack_sources::{BoxSource, RawSource, SourceExt}, - AssetGeneratorDataUrl, AssetGeneratorDataUrlFnArgs, AssetParserDataUrl, BuildMetaDefaultObject, - BuildMetaExportsType, ChunkGraph, ChunkUkey, CodeGenerationDataAssetInfo, + AssetGeneratorDataUrl, AssetGeneratorDataUrlFnArgs, AssetInfo, AssetParserDataUrl, + BuildMetaDefaultObject, BuildMetaExportsType, ChunkGraph, ChunkUkey, CodeGenerationDataAssetInfo, CodeGenerationDataFilename, CodeGenerationDataUrl, Compilation, CompilationRenderManifest, - CompilerOptions, GenerateContext, Module, ModuleGraph, NormalModule, ParseContext, - ParserAndGenerator, PathData, Plugin, PublicPath, RenderManifestEntry, ResourceData, - RuntimeGlobals, SourceType, NAMESPACE_OBJECT_EXPORT, + CompilerOptions, Filename, GenerateContext, GeneratorOptions, LocalFilenameFn, Module, + ModuleGraph, NormalModule, ParseContext, ParserAndGenerator, PathData, Plugin, PublicPath, + RenderManifestEntry, ResourceData, RuntimeGlobals, RuntimeSpec, SourceType, + NAMESPACE_OBJECT_EXPORT, }; use rspack_error::{error, Diagnostic, IntoTWithDiagnosticArray, Result}; use rspack_hash::{RspackHash, RspackHashDigest}; use rspack_hook::{plugin, plugin_hook}; -use rspack_util::identifier::make_paths_relative; +use rspack_util::{ext::DynHash, identifier::make_paths_relative}; #[plugin] #[derive(Debug, Default)] @@ -209,6 +210,51 @@ impl AssetParserAndGenerator { } relative } + + fn get_asset_module_filename( + &self, + module: &NormalModule, + module_generator_options: Option<&GeneratorOptions>, + compilation: &Compilation, + contenthash: Option<&str>, + source_file_name: &str, + ) -> Result<(String, AssetInfo)> { + // Use [Rule.generator.filename] if it is set, otherwise use [output.assetModuleFilename]. + let asset_filename_template = module_generator_options + .and_then(|x| x.asset_filename()) + .unwrap_or(&compilation.options.output.asset_module_filename); + + compilation.get_asset_path_with_info( + asset_filename_template, + PathData::default() + .module(module) + .chunk_graph(&compilation.chunk_graph) + .content_hash_optional(contenthash) + .hash_optional(contenthash) + .filename(source_file_name), + ) + } + + fn get_public_path( + &self, + module: &NormalModule, + compilation: &Compilation, + contenthash: Option<&str>, + source_file_name: &str, + template: &Filename, + ) -> Result<(String, AssetInfo), F::Error> { + let (public_path, info) = compilation.get_asset_path_with_info( + template, + PathData::default() + .module(module) + .chunk_graph(&compilation.chunk_graph) + .content_hash_optional(contenthash) + .hash_optional(contenthash) + .filename(source_file_name), + )?; + let public_path = PublicPath::ensure_ends_with_slash(public_path); + Ok((public_path, info)) + } } // Webpack's default parser.dataUrlCondition.maxSize @@ -336,14 +382,13 @@ impl ParserAndGenerator for AssetParserAndGenerator { let normal_module = module .as_normal_module() .expect("module should be a NormalModule in AssetParserAndGenerator"); + let module_generator_options = normal_module.get_generator_options(); let result = match generate_context.requested_source_type { SourceType::JavaScript => { let exported_content = if parsed_asset_config.is_inline() { let resource_data: &ResourceData = normal_module.resource_resolved_data(); - let data_url = generate_context - .module_generator_options - .and_then(|x| x.asset_data_url()); + let data_url = module_generator_options.and_then(|x| x.asset_data_url()); let encoded_source: String; @@ -369,43 +414,32 @@ impl ParserAndGenerator for AssetParserAndGenerator { serde_json::to_string(&encoded_source).map_err(|e| error!(e.to_string()))? } else if parsed_asset_config.is_resource() { - // Use [Rule.generator.filename] if it is set, otherwise use [output.assetModuleFilename]. - let asset_filename_template = generate_context - .module_generator_options - .and_then(|x| x.asset_filename()) - .unwrap_or(&compilation.options.output.asset_module_filename); - let contenthash = self.hash_for_source(source, &compilation.options); let contenthash = contenthash.rendered(compilation.options.output.hash_digest_length); let source_file_name = self.get_source_file_name(normal_module, compilation); - let (filename, mut asset_info) = compilation.get_asset_path_with_info( - asset_filename_template, - PathData::default() - .module(module) - .chunk_graph(&generate_context.compilation.chunk_graph) - .content_hash(contenthash) - .hash(contenthash) - .filename(&source_file_name), + let (filename, mut asset_info) = self.get_asset_module_filename( + normal_module, + module_generator_options, + compilation, + Some(contenthash), + &source_file_name, )?; - let asset_path = if let Some(public_path) = generate_context - .module_generator_options - .and_then(|x| x.asset_public_path()) + let asset_path = if let Some(public_path) = + module_generator_options.and_then(|x| x.asset_public_path()) { let public_path = match public_path { PublicPath::Filename(template) => { - let (public_path, another_asset_info) = compilation.get_asset_path_with_info( + let (public_path, another_asset_info) = self.get_public_path( + normal_module, + compilation, + Some(contenthash), + &source_file_name, template, - PathData::default() - .module(module) - .chunk_graph(&generate_context.compilation.chunk_graph) - .content_hash(contenthash) - .hash(contenthash) - .filename(&source_file_name), )?; asset_info.merge_another(another_asset_info); - PublicPath::ensure_ends_with_slash(public_path) + public_path } PublicPath::Auto => public_path.render(compilation, &filename), }; @@ -423,8 +457,7 @@ impl ParserAndGenerator for AssetParserAndGenerator { .data .insert(CodeGenerationDataFilename::new( filename, - generate_context - .module_generator_options + module_generator_options .and_then(|x| x.asset_public_path()) .unwrap_or_else(|| &compilation.options.output.public_path) .clone(), @@ -483,6 +516,48 @@ impl ParserAndGenerator for AssetParserAndGenerator { ) -> Option> { None } + + fn update_hash( + &self, + module: &NormalModule, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + let parsed_asset_config = self + .parsed_asset_config + .as_ref() + .expect("should have parsed_asset_config in generate phase"); + let module_generator_options = module.get_generator_options(); + if parsed_asset_config.is_inline() + && let Some(AssetGeneratorDataUrl::Options(data_url_options)) = + module_generator_options.and_then(|x| x.asset_data_url()) + { + data_url_options.dyn_hash(hasher); + } else if parsed_asset_config.is_resource() { + let source_file_name = self.get_source_file_name(module, compilation); + let (filename, _) = self.get_asset_module_filename( + module, + module_generator_options, + compilation, + None, + &source_file_name, + )?; + filename.dyn_hash(hasher); + match module_generator_options.and_then(|x| x.asset_public_path()) { + Some(public_path) => match public_path { + PublicPath::Filename(template) => { + let (public_path, _) = + self.get_public_path(module, compilation, None, &source_file_name, template)?; + public_path.dyn_hash(hasher); + } + PublicPath::Auto => "auto".dyn_hash(hasher), + }, + None => "no-path".dyn_hash(hasher), + }; + } + Ok(()) + } } #[plugin_hook(CompilationRenderManifest for AssetPlugin)] diff --git a/crates/rspack_plugin_css/src/dependency/export.rs b/crates/rspack_plugin_css/src/dependency/export.rs index e8e79ae58c9..3b1e8d18860 100644 --- a/crates/rspack_plugin_css/src/dependency/export.rs +++ b/crates/rspack_plugin_css/src/dependency/export.rs @@ -1,7 +1,7 @@ use rspack_core::{ - AsContextDependency, AsModuleDependency, Dependency, DependencyCategory, DependencyId, - DependencyTemplate, DependencyType, ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, - ExportsSpec, TemplateContext, TemplateReplaceSource, + AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyCategory, + DependencyId, DependencyTemplate, DependencyType, ExportNameOrSpec, ExportSpec, + ExportsOfExportsSpec, ExportsSpec, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; #[derive(Debug, Clone)] @@ -65,6 +65,15 @@ impl DependencyTemplate for CssExportDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + // No DependencyTemplate::apply, no need to update hash + } } impl AsContextDependency for CssExportDependency {} diff --git a/crates/rspack_plugin_css/src/dependency/import.rs b/crates/rspack_plugin_css/src/dependency/import.rs index 1d0764b275c..5700c11094f 100644 --- a/crates/rspack_plugin_css/src/dependency/import.rs +++ b/crates/rspack_plugin_css/src/dependency/import.rs @@ -1,6 +1,7 @@ use rspack_core::{ - AsContextDependency, Dependency, DependencyCategory, DependencyId, DependencyTemplate, - DependencyType, ErrorSpan, ModuleDependency, TemplateContext, TemplateReplaceSource, + AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, + DependencyTemplate, DependencyType, ErrorSpan, ModuleDependency, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; #[derive(Debug, Clone)] @@ -68,6 +69,14 @@ impl DependencyTemplate for CssImportDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for CssImportDependency {} diff --git a/crates/rspack_plugin_css/src/dependency/local_ident.rs b/crates/rspack_plugin_css/src/dependency/local_ident.rs index 7520e56af88..5624ad87cbd 100644 --- a/crates/rspack_plugin_css/src/dependency/local_ident.rs +++ b/crates/rspack_plugin_css/src/dependency/local_ident.rs @@ -1,8 +1,9 @@ use rspack_core::{ - AsContextDependency, AsModuleDependency, Dependency, DependencyCategory, DependencyId, - DependencyTemplate, DependencyType, ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, - ExportsSpec, TemplateContext, TemplateReplaceSource, + AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyCategory, + DependencyId, DependencyTemplate, DependencyType, ExportNameOrSpec, ExportSpec, + ExportsOfExportsSpec, ExportsSpec, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; +use rspack_util::ext::DynHash; #[derive(Debug, Clone)] pub struct CssLocalIdentDependency { @@ -70,6 +71,15 @@ impl DependencyTemplate for CssLocalIdentDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.local_ident.dyn_hash(hasher); + } } impl AsContextDependency for CssLocalIdentDependency {} diff --git a/crates/rspack_plugin_css/src/dependency/url.rs b/crates/rspack_plugin_css/src/dependency/url.rs index 95669307509..7f14e16ec50 100644 --- a/crates/rspack_plugin_css/src/dependency/url.rs +++ b/crates/rspack_plugin_css/src/dependency/url.rs @@ -1,7 +1,8 @@ use rspack_core::{ AsContextDependency, CodeGenerationDataFilename, CodeGenerationDataUrl, Compilation, Dependency, DependencyCategory, DependencyId, DependencyTemplate, DependencyType, ErrorSpan, - ModuleDependency, ModuleIdentifier, PublicPath, TemplateContext, TemplateReplaceSource, + ModuleDependency, ModuleIdentifier, PublicPath, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; use crate::utils::{css_escape_string, AUTO_PUBLIC_PATH_PLACEHOLDER}; @@ -117,6 +118,14 @@ impl DependencyTemplate for CssUrlDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for CssUrlDependency {} diff --git a/crates/rspack_plugin_css/src/parser_and_generator/mod.rs b/crates/rspack_plugin_css/src/parser_and_generator/mod.rs index 05be975ca62..cd2277f1663 100644 --- a/crates/rspack_plugin_css/src/parser_and_generator/mod.rs +++ b/crates/rspack_plugin_css/src/parser_and_generator/mod.rs @@ -9,15 +9,17 @@ use regex::Regex; use rspack_core::{ diagnostics::map_box_diagnostics_to_module_parse_diagnostics, rspack_sources::{BoxSource, ConcatSource, RawSource, ReplaceSource, Source, SourceExt}, - BuildMetaDefaultObject, BuildMetaExportsType, ChunkGraph, ConstDependency, CssExportsConvention, - Dependency, DependencyId, DependencyTemplate, ErrorSpan, GenerateContext, LocalIdentName, Module, - ModuleDependency, ModuleGraph, ModuleIdentifier, ModuleType, ParseContext, ParseResult, - ParserAndGenerator, RuntimeSpec, SourceType, TemplateContext, UsageState, + BuildMetaDefaultObject, BuildMetaExportsType, ChunkGraph, Compilation, ConstDependency, + CssExportsConvention, Dependency, DependencyId, DependencyTemplate, ErrorSpan, GenerateContext, + LocalIdentName, Module, ModuleDependency, ModuleGraph, ModuleIdentifier, ModuleType, + NormalModule, ParseContext, ParseResult, ParserAndGenerator, RuntimeSpec, SourceType, + TemplateContext, UsageState, }; use rspack_core::{ModuleInitFragments, RuntimeGlobals}; use rspack_error::{ miette::Diagnostic, IntoTWithDiagnosticArray, Result, RspackSeverity, TWithDiagnosticArray, }; +use rspack_util::ext::DynHash; use rustc_hash::FxHashSet; use crate::utils::{css_modules_exports_to_string, escape_css, LocalIdentOptions}; @@ -557,6 +559,17 @@ impl ParserAndGenerator for CssParserAndGenerator { ) -> Option> { Some("Module Concatenation is not implemented for CssParserAndGenerator".into()) } + + fn update_hash( + &self, + _module: &NormalModule, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + self.es_module.dyn_hash(hasher); + Ok(()) + } } fn get_used_exports<'a>( diff --git a/crates/rspack_plugin_css/src/plugin/mod.rs b/crates/rspack_plugin_css/src/plugin/mod.rs index b3a9ae8b282..9d958cac098 100644 --- a/crates/rspack_plugin_css/src/plugin/mod.rs +++ b/crates/rspack_plugin_css/src/plugin/mod.rs @@ -160,7 +160,7 @@ impl CssPlugin { continue; } let last_module = *list.last().expect("TODO:"); - if last_module == selected_module { + if last_module.identifier() == selected_module.identifier() { continue; } if !set.contains(&selected_module.identifier()) { @@ -214,11 +214,15 @@ impl CssPlugin { // Remove the selected module from all lists for SortedModules { set, list } in &mut modules_by_chunk_group { let last_module = list.last(); - if last_module.map_or(false, |last_module| last_module == &selected_module) { + if last_module.map_or(false, |last_module| { + last_module.identifier() == selected_module.identifier() + }) { list.pop(); set.remove(&selected_module.identifier()); } else if has_failed.is_some() && set.contains(&selected_module.identifier()) { - let idx = list.iter().position(|m| m == &selected_module); + let idx = list + .iter() + .position(|m| m.identifier() == selected_module.identifier()); if let Some(idx) = idx { list.remove(idx); } diff --git a/crates/rspack_plugin_extract_css/src/css_module.rs b/crates/rspack_plugin_extract_css/src/css_module.rs index 7b0cc58067f..075b5bec12d 100644 --- a/crates/rspack_plugin_extract_css/src/css_module.rs +++ b/crates/rspack_plugin_extract_css/src/css_module.rs @@ -5,14 +5,16 @@ use std::sync::LazyLock; use rspack_collections::{Identifiable, Identifier}; use rspack_core::rspack_sources::Source; use rspack_core::{ - impl_module_meta_info, impl_source_map_config, AsyncDependenciesBlockIdentifier, BuildContext, - BuildInfo, BuildMeta, BuildResult, CodeGenerationResult, Compilation, CompilerOptions, - ConcatenationScope, DependenciesBlock, DependencyId, DependencyType, FactoryMeta, Module, - ModuleFactory, ModuleFactoryCreateData, ModuleFactoryResult, RuntimeSpec, SourceType, + impl_module_meta_info, impl_source_map_config, module_update_hash, + AsyncDependenciesBlockIdentifier, BuildContext, BuildInfo, BuildMeta, BuildResult, + CodeGenerationResult, Compilation, CompilerOptions, ConcatenationScope, DependenciesBlock, + DependencyId, DependencyType, FactoryMeta, Module, ModuleFactory, ModuleFactoryCreateData, + ModuleFactoryResult, RuntimeSpec, SourceType, }; use rspack_error::Result; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic}; use rspack_hash::{RspackHash, RspackHashDigest}; +use rspack_util::ext::DynHash; use rustc_hash::FxHashSet; use crate::css_dependency::CssDependency; @@ -47,20 +49,6 @@ pub(crate) struct CssModule { build_dependencies: FxHashSet, } -impl Hash for CssModule { - fn hash(&self, state: &mut H) { - self.identifier.hash(state); - } -} - -impl PartialEq for CssModule { - fn eq(&self, other: &Self) -> bool { - self.identifier == other.identifier - } -} - -impl Eq for CssModule {} - impl CssModule { pub fn new(dep: CssDependency) -> Self { let identifier__ = format!( @@ -172,6 +160,7 @@ impl Module for CssModule { }) } + #[tracing::instrument(name = "ExtractCssModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, _compilation: &Compilation, @@ -184,6 +173,22 @@ impl Module for CssModule { fn get_diagnostics(&self) -> Vec { vec![] } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + self + .build_info + .as_ref() + .expect("should update_hash after build") + .hash + .dyn_hash(hasher); + Ok(()) + } } impl Identifiable for CssModule { diff --git a/crates/rspack_plugin_extract_css/src/plugin.rs b/crates/rspack_plugin_extract_css/src/plugin.rs index d7b6ab71cfd..6fb5181f228 100644 --- a/crates/rspack_plugin_extract_css/src/plugin.rs +++ b/crates/rspack_plugin_extract_css/src/plugin.rs @@ -533,8 +533,7 @@ async fn content_hash( let used_modules = rspack_plugin_css::CssPlugin::get_modules_in_order(chunk, rendered_modules, compilation) .0 - .into_iter() - .filter_map(|module| module.downcast_ref::()); + .into_iter(); let mut hasher = hashes .entry(SOURCE_TYPE[0]) @@ -542,15 +541,11 @@ async fn content_hash( used_modules .map(|m| { - m.build_info() - .expect("css module built") - .hash - .as_ref() - .expect("css module should have hash") + compilation + .chunk_graph + .get_module_hash(m.identifier(), &chunk.runtime) }) - .for_each(|current| { - current.hash(&mut hasher); - }); + .for_each(|current| current.hash(&mut hasher)); Ok(()) } diff --git a/crates/rspack_plugin_hmr/Cargo.toml b/crates/rspack_plugin_hmr/Cargo.toml index 80d3f08b335..c8de0cec6e6 100644 --- a/crates/rspack_plugin_hmr/Cargo.toml +++ b/crates/rspack_plugin_hmr/Cargo.toml @@ -5,11 +5,11 @@ license = "MIT" name = "rspack_plugin_hmr" repository = "https://github.com/web-infra-dev/rspack" version = "0.1.0" + [dependencies] rspack_collections = { version = "0.1.0", path = "../rspack_collections" } rspack_core = { version = "0.1.0", path = "../rspack_core" } rspack_error = { version = "0.1.0", path = "../rspack_error" } -rspack_hash = { version = "0.1.0", path = "../rspack_hash" } rspack_hook = { version = "0.1.0", path = "../rspack_hook" } rspack_util = { version = "0.1.0", path = "../rspack_util" } diff --git a/crates/rspack_plugin_hmr/src/lib.rs b/crates/rspack_plugin_hmr/src/lib.rs index ef48ebdb66c..595195755b4 100644 --- a/crates/rspack_plugin_hmr/src/lib.rs +++ b/crates/rspack_plugin_hmr/src/lib.rs @@ -1,7 +1,5 @@ mod hot_module_replacement; -use std::hash::Hash; - use async_trait::async_trait; use hot_module_replacement::HotModuleReplacementRuntimeModule; use rspack_collections::{IdentifierSet, UkeyMap}; @@ -12,10 +10,9 @@ use rspack_core::{ CompilationAdditionalTreeRuntimeRequirements, CompilationAsset, CompilationParams, CompilationProcessAssets, CompilationRecords, CompilerCompilation, CompilerOptions, DependencyType, LoaderContext, NormalModuleLoader, PathData, Plugin, PluginContext, - RunnerContext, RuntimeGlobals, RuntimeModuleExt, RuntimeSpec, SourceType, + RunnerContext, RuntimeGlobals, RuntimeModuleExt, RuntimeSpec, }; use rspack_error::Result; -use rspack_hash::RspackHash; use rspack_hook::{plugin, plugin_hook}; use rspack_util::infallible::ResultInfallibleExt as _; use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; @@ -186,8 +183,8 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { let mut hot_update_chunk = Chunk::new(None, ChunkKind::HotUpdate); hot_update_chunk.id = Some(chunk_id.to_string()); hot_update_chunk.runtime = new_runtime.clone(); - let mut chunk_hash = RspackHash::from(&compilation.options.output); let ukey = hot_update_chunk.ukey; + if let Some(current_chunk) = current_chunk { current_chunk .groups @@ -195,22 +192,6 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> { .for_each(|group| hot_update_chunk.add_group(*group)) } - for module_identifier in new_modules.iter() { - if let Some(module) = compilation - .get_module_graph() - .module_by_identifier(module_identifier) - { - module.hash(&mut chunk_hash); - } - } - let digest = chunk_hash.digest(&compilation.options.output.hash_digest); - hot_update_chunk - .content_hash - .insert(SourceType::JavaScript, digest.clone()); - hot_update_chunk - .content_hash - .insert(SourceType::Css, digest); - compilation.chunk_by_ukey.add(hot_update_chunk); compilation.chunk_graph.add_chunk(ukey); diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_export_require_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_export_require_dependency.rs index ec00e2cd667..a9c40933d9e 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_export_require_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_export_require_dependency.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use rspack_core::{ - module_raw, process_export_info, property_access, AsContextDependency, Dependency, + module_raw, process_export_info, property_access, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, DependencyTemplate, DependencyType, ErrorSpan, ExportInfoProvided, ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, ExportsSpec, ExportsType, ExtendedReferencedExport, ModuleDependency, ModuleGraph, ModuleIdentifier, Nullable, @@ -432,6 +432,14 @@ impl DependencyTemplate for CommonJsExportRequireDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl ModuleDependency for CommonJsExportRequireDependency { diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_exports_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_exports_dependency.rs index d0ebd7d0dd6..7f621a48745 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_exports_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_exports_dependency.rs @@ -1,9 +1,9 @@ use rspack_core::{ - property_access, AsContextDependency, AsModuleDependency, Dependency, DependencyCategory, - DependencyId, DependencyTemplate, DependencyType, ExportNameOrSpec, ExportSpec, - ExportsOfExportsSpec, ExportsSpec, InitFragmentExt, InitFragmentKey, InitFragmentStage, - ModuleGraph, NormalInitFragment, RuntimeGlobals, TemplateContext, TemplateReplaceSource, - UsedName, + property_access, AsContextDependency, AsModuleDependency, Compilation, Dependency, + DependencyCategory, DependencyId, DependencyTemplate, DependencyType, ExportNameOrSpec, + ExportSpec, ExportsOfExportsSpec, ExportsSpec, InitFragmentExt, InitFragmentKey, + InitFragmentStage, ModuleGraph, NormalInitFragment, RuntimeGlobals, RuntimeSpec, TemplateContext, + TemplateReplaceSource, UsedName, }; use swc_core::atoms::Atom; @@ -225,6 +225,14 @@ impl DependencyTemplate for CommonJsExportsDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for CommonJsExportsDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_full_require_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_full_require_dependency.rs index c78fc41e408..46489ca66e6 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_full_require_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_full_require_dependency.rs @@ -1,6 +1,6 @@ use rspack_core::{ - module_id, property_access, to_normal_comment, ExportsType, ExtendedReferencedExport, - ModuleGraph, RuntimeGlobals, RuntimeSpec, UsedName, + module_id, property_access, to_normal_comment, Compilation, ExportsType, + ExtendedReferencedExport, ModuleGraph, RuntimeGlobals, RuntimeSpec, UsedName, }; use rspack_core::{AsContextDependency, Dependency, DependencyCategory, DependencyLocation}; use rspack_core::{DependencyId, DependencyTemplate}; @@ -154,6 +154,14 @@ impl DependencyTemplate for CommonJsFullRequireDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for CommonJsFullRequireDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_require_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_require_dependency.rs index 7f3db636ac4..b871c5bc479 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_require_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_require_dependency.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use rspack_core::module_id; +use rspack_core::{module_id, Compilation, RuntimeSpec}; use rspack_core::{AsContextDependency, Dependency, DependencyCategory, DependencyLocation}; use rspack_core::{DependencyId, DependencyTemplate}; use rspack_core::{DependencyType, ErrorSpan, ModuleDependency}; @@ -95,6 +95,14 @@ impl DependencyTemplate for CommonJsRequireDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for CommonJsRequireDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_self_reference_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_self_reference_dependency.rs index 75bcd58423e..4a432be6eab 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_self_reference_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/common_js_self_reference_dependency.rs @@ -1,5 +1,5 @@ use rspack_core::{ - property_access, AsContextDependency, Dependency, DependencyCategory, DependencyId, + property_access, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, DependencyTemplate, DependencyType, ExtendedReferencedExport, ModuleDependency, ModuleGraph, RuntimeGlobals, RuntimeSpec, TemplateContext, TemplateReplaceSource, UsedName, }; @@ -136,4 +136,12 @@ impl DependencyTemplate for CommonJsSelfReferenceDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/module_decorator_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/module_decorator_dependency.rs index 3069524a531..4f09eb7ecc2 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/module_decorator_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/module_decorator_dependency.rs @@ -1,8 +1,10 @@ use rspack_core::{ - create_exports_object_referenced, create_no_exports_referenced, AsContextDependency, Dependency, - DependencyId, DependencyTemplate, DependencyType, InitFragmentKey, InitFragmentStage, - ModuleDependency, NormalInitFragment, RuntimeGlobals, TemplateContext, TemplateReplaceSource, + create_exports_object_referenced, create_no_exports_referenced, AsContextDependency, Compilation, + Dependency, DependencyId, DependencyTemplate, DependencyType, InitFragmentKey, InitFragmentStage, + ModuleDependency, NormalInitFragment, RuntimeGlobals, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; +use rspack_util::ext::DynHash; #[derive(Debug, Clone)] pub struct ModuleDecoratorDependency { @@ -76,6 +78,16 @@ impl DependencyTemplate for ModuleDecoratorDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.decorator.dyn_hash(hasher); + self.allow_exports_access.dyn_hash(hasher); + } } impl AsContextDependency for ModuleDecoratorDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/require_header_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/require_header_dependency.rs index 7cb9b82f6f8..105c1b31531 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/require_header_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/require_header_dependency.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use rspack_core::{AsContextDependency, AsModuleDependency, Dependency}; +use rspack_core::{AsContextDependency, AsModuleDependency, Compilation, Dependency, RuntimeSpec}; use rspack_core::{DependencyId, DependencyLocation}; use rspack_core::{DependencyTemplate, RuntimeGlobals, TemplateContext}; use swc_core::common::SourceMap; @@ -52,4 +52,12 @@ impl DependencyTemplate for RequireHeaderDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } diff --git a/crates/rspack_plugin_javascript/src/dependency/commonjs/require_resolve_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/commonjs/require_resolve_dependency.rs index 470e4cd18eb..a38b4402cce 100644 --- a/crates/rspack_plugin_javascript/src/dependency/commonjs/require_resolve_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/commonjs/require_resolve_dependency.rs @@ -1,7 +1,7 @@ use rspack_core::{ - module_id, AsContextDependency, Dependency, DependencyCategory, DependencyId, DependencyTemplate, - DependencyType, ErrorSpan, ExtendedReferencedExport, ModuleDependency, ModuleGraph, RuntimeSpec, - TemplateContext, TemplateReplaceSource, + module_id, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, + DependencyTemplate, DependencyType, ErrorSpan, ExtendedReferencedExport, ModuleDependency, + ModuleGraph, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; #[derive(Debug, Clone)] @@ -107,6 +107,14 @@ impl DependencyTemplate for RequireResolveDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for RequireResolveDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/context/common_js_require_context_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/context/common_js_require_context_dependency.rs index 4e8cd86327a..f06fbbe2082 100644 --- a/crates/rspack_plugin_javascript/src/dependency/context/common_js_require_context_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/context/common_js_require_context_dependency.rs @@ -1,4 +1,4 @@ -use rspack_core::{AsModuleDependency, ContextDependency}; +use rspack_core::{AsModuleDependency, Compilation, ContextDependency, RuntimeSpec}; use rspack_core::{ContextOptions, Dependency, TemplateReplaceSource}; use rspack_core::{DependencyCategory, DependencyId, DependencyTemplate}; use rspack_core::{DependencyType, ErrorSpan, TemplateContext}; @@ -109,6 +109,14 @@ impl DependencyTemplate for CommonJsRequireContextDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsModuleDependency for CommonJsRequireContextDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/context/import_context_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/context/import_context_dependency.rs index 6d2f9cbea73..2bc14b131d5 100644 --- a/crates/rspack_plugin_javascript/src/dependency/context/import_context_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/context/import_context_dependency.rs @@ -1,4 +1,4 @@ -use rspack_core::{AsModuleDependency, ContextDependency}; +use rspack_core::{AsModuleDependency, Compilation, ContextDependency, RuntimeSpec}; use rspack_core::{ContextOptions, Dependency, TemplateReplaceSource}; use rspack_core::{DependencyCategory, DependencyId, DependencyTemplate}; use rspack_core::{DependencyType, ErrorSpan, TemplateContext}; @@ -109,6 +109,14 @@ impl DependencyTemplate for ImportContextDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsModuleDependency for ImportContextDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/context/import_meta_context_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/context/import_meta_context_dependency.rs index d8eddfc00c1..75fc95cd213 100644 --- a/crates/rspack_plugin_javascript/src/dependency/context/import_meta_context_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/context/import_meta_context_dependency.rs @@ -1,4 +1,4 @@ -use rspack_core::{module_raw, AsModuleDependency, ContextDependency}; +use rspack_core::{module_raw, AsModuleDependency, Compilation, ContextDependency, RuntimeSpec}; use rspack_core::{ContextOptions, Dependency, DependencyCategory, DependencyId}; use rspack_core::{DependencyTemplate, DependencyType, ErrorSpan}; use rspack_core::{TemplateContext, TemplateReplaceSource}; @@ -110,6 +110,14 @@ impl DependencyTemplate for ImportMetaContextDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsModuleDependency for ImportMetaContextDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/context/require_context_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/context/require_context_dependency.rs index 14111062f96..60a5b5ac7bf 100644 --- a/crates/rspack_plugin_javascript/src/dependency/context/require_context_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/context/require_context_dependency.rs @@ -1,4 +1,4 @@ -use rspack_core::{module_raw, AsModuleDependency, ContextDependency}; +use rspack_core::{module_raw, AsModuleDependency, Compilation, ContextDependency, RuntimeSpec}; use rspack_core::{ContextOptions, Dependency, DependencyCategory, DependencyId}; use rspack_core::{DependencyTemplate, DependencyType, ErrorSpan}; use rspack_core::{TemplateContext, TemplateReplaceSource}; @@ -110,6 +110,14 @@ impl DependencyTemplate for RequireContextDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsModuleDependency for RequireContextDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/external_module_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/external_module_dependency.rs index be5ff93eb0f..384ca9e855c 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/external_module_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/external_module_dependency.rs @@ -1,7 +1,8 @@ use rspack_core::{ - AsDependency, DependencyId, DependencyTemplate, ExternalModuleInitFragment, InitFragmentExt, - InitFragmentStage, TemplateContext, TemplateReplaceSource, + AsDependency, Compilation, DependencyId, DependencyTemplate, ExternalModuleInitFragment, + InitFragmentExt, InitFragmentStage, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; +use rspack_util::ext::DynHash; #[derive(Debug, Clone)] pub struct ExternalModuleDependency { @@ -46,6 +47,17 @@ impl DependencyTemplate for ExternalModuleDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.module.dyn_hash(hasher); + self.import_specifier.dyn_hash(hasher); + self.default_import.dyn_hash(hasher); + } } impl AsDependency for ExternalModuleDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_compatibility_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_compatibility_dependency.rs index 5b373cb8192..52754deaa04 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_compatibility_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_compatibility_dependency.rs @@ -1,6 +1,7 @@ use rspack_core::{ - AsDependency, DependencyTemplate, InitFragmentKey, InitFragmentStage, NormalInitFragment, - RuntimeGlobals, TemplateContext, TemplateReplaceSource, UsageState, + AsDependency, Compilation, DependencyTemplate, InitFragmentKey, InitFragmentStage, + NormalInitFragment, RuntimeGlobals, RuntimeSpec, TemplateContext, TemplateReplaceSource, + UsageState, }; use swc_core::atoms::Atom; @@ -76,5 +77,13 @@ impl DependencyTemplate for HarmonyCompatibilityDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsDependency for HarmonyCompatibilityDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_expression_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_expression_dependency.rs index b7c487fc768..71ce9a712e3 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_expression_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_expression_dependency.rs @@ -239,4 +239,12 @@ impl DependencyTemplate for HarmonyExportExpressionDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_header_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_header_dependency.rs index af7f9a1890b..66c6331549b 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_header_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_header_dependency.rs @@ -1,6 +1,6 @@ use rspack_core::{ - AsContextDependency, AsModuleDependency, Dependency, DependencyId, DependencyRange, - DependencyTemplate, DependencyType, TemplateContext, TemplateReplaceSource, + AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyId, DependencyRange, + DependencyTemplate, DependencyType, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; // Remove `export` label. @@ -58,6 +58,14 @@ impl DependencyTemplate for HarmonyExportHeaderDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsModuleDependency for HarmonyExportHeaderDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_imported_specifier_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_imported_specifier_dependency.rs index a8dc8d6bf4b..f3128159d6c 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_imported_specifier_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_imported_specifier_dependency.rs @@ -6,10 +6,10 @@ use rspack_collections::IdentifierSet; use rspack_core::{ create_exports_object_referenced, create_no_exports_referenced, filter_runtime, get_exports_type, process_export_info, property_access, property_name, string_of_used_name, AsContextDependency, - ConditionalInitFragment, ConnectionState, Dependency, DependencyCategory, DependencyCondition, - DependencyId, DependencyRange, DependencyTemplate, DependencyType, ErrorSpan, ExportInfo, - ExportInfoProvided, ExportNameOrSpec, ExportPresenceMode, ExportSpec, ExportsInfo, - ExportsOfExportsSpec, ExportsSpec, ExportsType, ExtendedReferencedExport, + Compilation, ConditionalInitFragment, ConnectionState, Dependency, DependencyCategory, + DependencyCondition, DependencyId, DependencyRange, DependencyTemplate, DependencyType, + ErrorSpan, ExportInfo, ExportInfoProvided, ExportNameOrSpec, ExportPresenceMode, ExportSpec, + ExportsInfo, ExportsOfExportsSpec, ExportsSpec, ExportsType, ExtendedReferencedExport, HarmonyExportInitFragment, ImportAttributes, InitFragmentExt, InitFragmentKey, InitFragmentStage, JavascriptParserOptions, ModuleDependency, ModuleGraph, ModuleIdentifier, NormalInitFragment, RuntimeCondition, RuntimeGlobals, RuntimeSpec, Template, TemplateContext, TemplateReplaceSource, @@ -954,7 +954,7 @@ impl HarmonyExportImportedSpecifierDependency { else { continue; }; - if conflicting_module == imported_module { + if conflicting_module.identifier() == imported_module.identifier() { continue; } let Some(conflicting_export_info) = @@ -1035,6 +1035,14 @@ impl DependencyTemplate for HarmonyExportImportedSpecifierDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl Dependency for HarmonyExportImportedSpecifierDependency { diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs index 87a276ebb82..d6dfa483360 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_export_specifier_dependency.rs @@ -1,9 +1,9 @@ use rspack_collections::IdentifierSet; use rspack_core::{ - AsContextDependency, AsModuleDependency, Dependency, DependencyCategory, DependencyId, - DependencyRange, DependencyTemplate, DependencyType, ExportNameOrSpec, ExportsOfExportsSpec, - ExportsSpec, HarmonyExportInitFragment, ModuleGraph, TemplateContext, TemplateReplaceSource, - UsedName, + AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyCategory, + DependencyId, DependencyRange, DependencyTemplate, DependencyType, ExportNameOrSpec, + ExportsOfExportsSpec, ExportsSpec, HarmonyExportInitFragment, ModuleGraph, RuntimeSpec, + TemplateContext, TemplateReplaceSource, UsedName, }; use swc_core::ecma::atoms::Atom; @@ -115,6 +115,14 @@ impl DependencyTemplate for HarmonyExportSpecifierDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for HarmonyExportSpecifierDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_dependency.rs index 59ea9d5bed7..5e03fe6d947 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_dependency.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use std::sync::LazyLock; use rspack_collections::{IdentifierDashMap, IdentifierMap, IdentifierSet}; +use rspack_core::Compilation; use rspack_core::DependencyRange; use rspack_core::{ filter_runtime, import_statement, merge_runtime, AsContextDependency, @@ -488,6 +489,14 @@ impl DependencyTemplate for HarmonyImportSideEffectDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for HarmonyImportSideEffectDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs index 718c332f105..bdedab7882b 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/harmony_import_specifier_dependency.rs @@ -1,9 +1,9 @@ use rspack_collections::IdentifierSet; use rspack_core::{ create_exports_object_referenced, export_from_import, get_dependency_used_by_exports_condition, - get_exports_type, AsContextDependency, ConnectionState, Dependency, DependencyCategory, - DependencyCondition, DependencyId, DependencyRange, DependencyTemplate, DependencyType, - ExportPresenceMode, ExportsType, ExtendedReferencedExport, ImportAttributes, + get_exports_type, AsContextDependency, Compilation, ConnectionState, Dependency, + DependencyCategory, DependencyCondition, DependencyId, DependencyRange, DependencyTemplate, + DependencyType, ExportPresenceMode, ExportsType, ExtendedReferencedExport, ImportAttributes, JavascriptParserOptions, ModuleDependency, ModuleGraph, ReferencedExport, RuntimeSpec, TemplateContext, TemplateReplaceSource, UsedByExports, }; @@ -209,6 +209,14 @@ impl DependencyTemplate for HarmonyImportSpecifierDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl Dependency for HarmonyImportSpecifierDependency { diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/import_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/import_dependency.rs index a95ef9a2db5..f01f3495710 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/import_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/import_dependency.rs @@ -1,6 +1,7 @@ use rspack_core::{ - create_exports_object_referenced, module_namespace_promise, DependencyType, ErrorSpan, - ExportsType, ExtendedReferencedExport, ImportAttributes, ModuleGraph, ReferencedExport, + create_exports_object_referenced, module_namespace_promise, Compilation, DependencyType, + ErrorSpan, ExportsType, ExtendedReferencedExport, ImportAttributes, ModuleGraph, + ReferencedExport, RuntimeSpec, }; use rspack_core::{AsContextDependency, Dependency}; use rspack_core::{DependencyCategory, DependencyId, DependencyTemplate}; @@ -162,6 +163,14 @@ impl DependencyTemplate for ImportDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for ImportDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/import_eager_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/import_eager_dependency.rs index dbe38409fb8..ef224399d76 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/import_eager_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/import_eager_dependency.rs @@ -1,7 +1,7 @@ use rspack_core::{ - module_namespace_promise, AsContextDependency, Dependency, DependencyCategory, DependencyId, - DependencyTemplate, DependencyType, ErrorSpan, ImportAttributes, ModuleDependency, - TemplateContext, TemplateReplaceSource, + module_namespace_promise, AsContextDependency, Compilation, Dependency, DependencyCategory, + DependencyId, DependencyTemplate, DependencyType, ErrorSpan, ImportAttributes, ModuleDependency, + RuntimeSpec, TemplateContext, TemplateReplaceSource, }; use swc_core::ecma::atoms::Atom; @@ -121,6 +121,14 @@ impl DependencyTemplate for ImportEagerDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for ImportEagerDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/esm/provide_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/esm/provide_dependency.rs index 04cfeffecc1..65fad19679c 100644 --- a/crates/rspack_plugin_javascript/src/dependency/esm/provide_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/esm/provide_dependency.rs @@ -1,12 +1,13 @@ use itertools::Itertools; use rspack_core::{ - create_exports_object_referenced, module_raw, ExtendedReferencedExport, ModuleGraph, + create_exports_object_referenced, module_raw, Compilation, ExtendedReferencedExport, ModuleGraph, NormalInitFragment, RuntimeSpec, UsedName, }; use rspack_core::{AsContextDependency, Dependency, InitFragmentKey, InitFragmentStage}; use rspack_core::{DependencyCategory, DependencyId, DependencyTemplate}; use rspack_core::{DependencyType, ErrorSpan}; use rspack_core::{ModuleDependency, TemplateContext, TemplateReplaceSource}; +use rspack_util::ext::DynHash; use swc_core::atoms::Atom; #[derive(Debug, Clone)] @@ -120,6 +121,16 @@ impl DependencyTemplate for ProvideDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.identifier.dyn_hash(hasher); + self.ids.dyn_hash(hasher); + } } fn path_to_string(path: Option<&UsedName>) -> String { diff --git a/crates/rspack_plugin_javascript/src/dependency/export_info_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/export_info_dependency.rs index f9a952e74b7..0652c4efbb6 100644 --- a/crates/rspack_plugin_javascript/src/dependency/export_info_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/export_info_dependency.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use rspack_core::{ - AsDependency, DependencyTemplate, ExportProvided, TemplateContext, TemplateReplaceSource, - UsageState, UsedExports, UsedName, + AsDependency, Compilation, DependencyTemplate, ExportProvided, RuntimeSpec, TemplateContext, + TemplateReplaceSource, UsageState, UsedExports, UsedName, }; use swc_core::ecma::atoms::Atom; @@ -38,6 +38,14 @@ impl DependencyTemplate for ExportInfoDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl ExportInfoDependency { diff --git a/crates/rspack_plugin_javascript/src/dependency/hmr/harmony_accept_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/hmr/harmony_accept_dependency.rs index 7dca3a6112a..cdf9b735286 100644 --- a/crates/rspack_plugin_javascript/src/dependency/hmr/harmony_accept_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/hmr/harmony_accept_dependency.rs @@ -1,6 +1,7 @@ use rspack_core::{ - import_statement, runtime_condition_expression, AsDependency, DependencyId, DependencyTemplate, - ErrorSpan, RuntimeCondition, TemplateContext, TemplateReplaceSource, + import_statement, runtime_condition_expression, AsDependency, Compilation, DependencyId, + DependencyTemplate, ErrorSpan, RuntimeCondition, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; use rspack_error::ErrorLocation; @@ -124,6 +125,14 @@ impl DependencyTemplate for HarmonyAcceptDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsDependency for HarmonyAcceptDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_accept.rs b/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_accept.rs index 9be45ec0b56..f3af3a60f21 100644 --- a/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_accept.rs +++ b/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_accept.rs @@ -1,6 +1,7 @@ use rspack_core::{ - module_id, AsContextDependency, Dependency, DependencyCategory, DependencyId, DependencyTemplate, - DependencyType, ErrorSpan, ModuleDependency, TemplateContext, TemplateReplaceSource, + module_id, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, + DependencyTemplate, DependencyType, ErrorSpan, ModuleDependency, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; use swc_core::ecma::atoms::Atom; @@ -84,6 +85,14 @@ impl DependencyTemplate for ImportMetaHotAcceptDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for ImportMetaHotAcceptDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_decline.rs b/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_decline.rs index a1da007815f..31554b5c840 100644 --- a/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_decline.rs +++ b/crates/rspack_plugin_javascript/src/dependency/hmr/import_meta_hot_decline.rs @@ -1,6 +1,7 @@ use rspack_core::{ - module_id, AsContextDependency, Dependency, DependencyCategory, DependencyId, DependencyTemplate, - DependencyType, ErrorSpan, ModuleDependency, TemplateContext, TemplateReplaceSource, + module_id, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, + DependencyTemplate, DependencyType, ErrorSpan, ModuleDependency, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; use swc_core::ecma::atoms::Atom; @@ -84,6 +85,14 @@ impl DependencyTemplate for ImportMetaHotDeclineDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for ImportMetaHotDeclineDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_accept.rs b/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_accept.rs index 3b57db4a1f1..f1052375a3a 100644 --- a/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_accept.rs +++ b/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_accept.rs @@ -1,6 +1,7 @@ use rspack_core::{ - module_id, AsContextDependency, Dependency, DependencyCategory, DependencyId, DependencyTemplate, - DependencyType, ErrorSpan, ModuleDependency, TemplateContext, TemplateReplaceSource, + module_id, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, + DependencyTemplate, DependencyType, ErrorSpan, ModuleDependency, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; use swc_core::ecma::atoms::Atom; @@ -84,6 +85,14 @@ impl DependencyTemplate for ModuleHotAcceptDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for ModuleHotAcceptDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_decline.rs b/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_decline.rs index 52e4aacdb34..262872f1211 100644 --- a/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_decline.rs +++ b/crates/rspack_plugin_javascript/src/dependency/hmr/module_hot_decline.rs @@ -1,6 +1,7 @@ use rspack_core::{ - module_id, AsContextDependency, Dependency, DependencyCategory, DependencyId, DependencyTemplate, - DependencyType, ErrorSpan, ModuleDependency, TemplateContext, TemplateReplaceSource, + module_id, AsContextDependency, Compilation, Dependency, DependencyCategory, DependencyId, + DependencyTemplate, DependencyType, ErrorSpan, ModuleDependency, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; use swc_core::ecma::atoms::Atom; @@ -84,6 +85,14 @@ impl DependencyTemplate for ModuleHotDeclineDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for ModuleHotDeclineDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/is_included_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/is_included_dependency.rs index 28c03e95706..4dd7e4a012d 100644 --- a/crates/rspack_plugin_javascript/src/dependency/is_included_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/is_included_dependency.rs @@ -1,5 +1,5 @@ use rspack_core::{ - AsContextDependency, Dependency, DependencyId, DependencyTemplate, DependencyType, + AsContextDependency, Compilation, Dependency, DependencyId, DependencyTemplate, DependencyType, ExtendedReferencedExport, ModuleDependency, ModuleGraph, RuntimeSpec, TemplateContext, TemplateReplaceSource, }; @@ -78,4 +78,12 @@ impl DependencyTemplate for WebpackIsIncludedDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } diff --git a/crates/rspack_plugin_javascript/src/dependency/module_argument_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/module_argument_dependency.rs index 0ba1b337774..f30bf6df795 100644 --- a/crates/rspack_plugin_javascript/src/dependency/module_argument_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/module_argument_dependency.rs @@ -1,8 +1,9 @@ use rspack_core::{ - AsDependency, DependencyTemplate, ErrorSpan, RuntimeGlobals, TemplateContext, - TemplateReplaceSource, + AsDependency, Compilation, DependencyTemplate, ErrorSpan, RuntimeGlobals, RuntimeSpec, + TemplateContext, TemplateReplaceSource, }; use rspack_error::ErrorLocation; +use rspack_util::ext::DynHash; #[derive(Debug, Clone)] pub struct ModuleArgumentDependency { @@ -54,6 +55,16 @@ impl DependencyTemplate for ModuleArgumentDependency { fn dependency_id(&self) -> Option { None } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.id.dyn_hash(hasher); + self.span.dyn_hash(hasher); + } } impl AsDependency for ModuleArgumentDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/pure_expression_dependency.rs b/crates/rspack_plugin_javascript/src/dependency/pure_expression_dependency.rs index f0aa760101e..0cf1a0ac722 100644 --- a/crates/rspack_plugin_javascript/src/dependency/pure_expression_dependency.rs +++ b/crates/rspack_plugin_javascript/src/dependency/pure_expression_dependency.rs @@ -1,9 +1,11 @@ use rspack_collections::IdentifierSet; use rspack_core::{ filter_runtime, runtime_condition_expression, AsContextDependency, AsModuleDependency, - ConnectionState, Dependency, DependencyId, DependencyTemplate, ModuleGraph, ModuleIdentifier, - TemplateContext, TemplateReplaceSource, UsageState, UsedByExports, UsedName, + Compilation, ConnectionState, Dependency, DependencyId, DependencyTemplate, ModuleGraph, + ModuleIdentifier, RuntimeCondition, RuntimeSpec, TemplateContext, TemplateReplaceSource, + UsageState, UsedByExports, UsedName, }; +use rspack_util::ext::DynHash; #[derive(Debug, Clone)] pub struct PureExpressionDependency { @@ -24,6 +26,34 @@ impl PureExpressionDependency { module_identifier, } } + + fn get_runtime_condition( + &self, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> RuntimeCondition { + match self.used_by_exports { + Some(UsedByExports::Bool(true)) => { + unreachable!() + } + Some(UsedByExports::Bool(false)) => RuntimeCondition::Boolean(false), + Some(UsedByExports::Set(ref set)) => { + let module_graph = compilation.get_module_graph(); + let exports_info = module_graph.get_exports_info(&self.module_identifier); + filter_runtime(runtime, |cur_runtime| { + set.iter().any(|id| { + exports_info.get_used(&module_graph, UsedName::Str(id.clone()), cur_runtime) + != UsageState::Unused + }) + }) + } + None => { + // https://github.com/webpack/webpack/blob/ac7e531436b0d47cd88451f497cdfd0dad41535d/lib/dependencies/PureExpressionDependency.js#L32-L33 + // after check usedExports is not false, webpack ensure that usedExports is a set + unreachable!() + } + } + } } impl Dependency for PureExpressionDependency { @@ -48,37 +78,16 @@ impl AsModuleDependency for PureExpressionDependency {} impl DependencyTemplate for PureExpressionDependency { fn apply(&self, source: &mut TemplateReplaceSource, ctx: &mut TemplateContext) { - let condition = match self.used_by_exports { - Some(UsedByExports::Bool(true)) => { - unreachable!() - } - Some(UsedByExports::Bool(false)) => None, - Some(UsedByExports::Set(ref set)) => { - let module_graph = ctx.compilation.get_module_graph(); - let exports_info = module_graph.get_exports_info(&self.module_identifier); - let runtime = ctx.runtime; - let runtime_condition = filter_runtime(runtime, |cur_runtime| { - set.iter().any(|id| { - exports_info.get_used(&module_graph, UsedName::Str(id.clone()), cur_runtime) - != UsageState::Unused - }) - }); - match &runtime_condition { - rspack_core::RuntimeCondition::Boolean(true) => return, - rspack_core::RuntimeCondition::Boolean(false) => None, - rspack_core::RuntimeCondition::Spec(_spec) => Some(runtime_condition_expression( - &ctx.compilation.chunk_graph, - Some(&runtime_condition), - runtime, - ctx.runtime_requirements, - )), - } - } - None => { - // https://github.com/webpack/webpack/blob/ac7e531436b0d47cd88451f497cdfd0dad41535d/lib/dependencies/PureExpressionDependency.js#L32-L33 - // after check usedExports is not false, webpack ensure that usedExports is a set - unreachable!() - } + let runtime_condition = self.get_runtime_condition(ctx.compilation, ctx.runtime); + let condition = match &runtime_condition { + rspack_core::RuntimeCondition::Boolean(true) => return, + rspack_core::RuntimeCondition::Boolean(false) => None, + rspack_core::RuntimeCondition::Spec(_spec) => Some(runtime_condition_expression( + &ctx.compilation.chunk_graph, + Some(&runtime_condition), + ctx.runtime, + ctx.runtime_requirements, + )), }; if let Some(condition) = condition { @@ -101,6 +110,16 @@ impl DependencyTemplate for PureExpressionDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) { + let runtime_condition = self.get_runtime_condition(compilation, runtime); + runtime_condition.dyn_hash(hasher); + } } impl AsContextDependency for PureExpressionDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/url/mod.rs b/crates/rspack_plugin_javascript/src/dependency/url/mod.rs index b19de92f2bf..80f53bb0772 100644 --- a/crates/rspack_plugin_javascript/src/dependency/url/mod.rs +++ b/crates/rspack_plugin_javascript/src/dependency/url/mod.rs @@ -1,8 +1,8 @@ use rspack_core::{ - get_dependency_used_by_exports_condition, module_id, AsContextDependency, Dependency, - DependencyCategory, DependencyCondition, DependencyId, DependencyTemplate, DependencyType, - ErrorSpan, ModuleDependency, RuntimeGlobals, TemplateContext, TemplateReplaceSource, - UsedByExports, + get_dependency_used_by_exports_condition, module_id, AsContextDependency, Compilation, + Dependency, DependencyCategory, DependencyCondition, DependencyId, DependencyTemplate, + DependencyType, ErrorSpan, ModuleDependency, RuntimeGlobals, RuntimeSpec, TemplateContext, + TemplateReplaceSource, UsedByExports, }; use swc_core::ecma::atoms::Atom; @@ -127,6 +127,14 @@ impl DependencyTemplate for URLDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + _hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + } } impl AsContextDependency for URLDependency {} diff --git a/crates/rspack_plugin_javascript/src/dependency/worker/mod.rs b/crates/rspack_plugin_javascript/src/dependency/worker/mod.rs index 52cf09b8530..7ca38efa96c 100644 --- a/crates/rspack_plugin_javascript/src/dependency/worker/mod.rs +++ b/crates/rspack_plugin_javascript/src/dependency/worker/mod.rs @@ -1,8 +1,10 @@ use rspack_core::{ - get_chunk_from_ukey, AsContextDependency, Dependency, DependencyCategory, DependencyId, - DependencyTemplate, DependencyType, ErrorSpan, ExtendedReferencedExport, ModuleDependency, - ModuleGraph, RuntimeGlobals, RuntimeSpec, TemplateContext, TemplateReplaceSource, + get_chunk_from_ukey, AsContextDependency, Compilation, Dependency, DependencyCategory, + DependencyId, DependencyTemplate, DependencyType, ErrorSpan, ExtendedReferencedExport, + ModuleDependency, ModuleGraph, RuntimeGlobals, RuntimeSpec, TemplateContext, + TemplateReplaceSource, }; +use rspack_util::ext::DynHash; #[derive(Debug, Clone)] pub struct WorkerDependency { @@ -125,6 +127,15 @@ impl DependencyTemplate for WorkerDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.public_path.dyn_hash(hasher); + } } impl AsContextDependency for WorkerDependency {} diff --git a/crates/rspack_plugin_javascript/src/parser_plugin/common_js_exports_parse_plugin.rs b/crates/rspack_plugin_javascript/src/parser_plugin/common_js_exports_parse_plugin.rs index 416fa399ef5..5a04b65c152 100644 --- a/crates/rspack_plugin_javascript/src/parser_plugin/common_js_exports_parse_plugin.rs +++ b/crates/rspack_plugin_javascript/src/parser_plugin/common_js_exports_parse_plugin.rs @@ -70,11 +70,7 @@ fn is_module_exports_member_expr_start(expr: &E) -> bool { } fn get_value_of_property_description(expr_or_spread: &ExprOrSpread) -> Option<&Expr> { - if let ExprOrSpread { - expr: box Expr::Object(ObjectLit { props, .. }), - .. - } = expr_or_spread - { + if let Expr::Object(ObjectLit { props, .. }) = expr_or_spread.expr.unwrap_parens() { for prop in props { if let PropOrSpread::Prop(prop) = prop && let Prop::KeyValue(key_value_prop) = &**prop diff --git a/crates/rspack_plugin_json/Cargo.toml b/crates/rspack_plugin_json/Cargo.toml index 70a917e3e02..01dcafd9fef 100644 --- a/crates/rspack_plugin_json/Cargo.toml +++ b/crates/rspack_plugin_json/Cargo.toml @@ -12,3 +12,4 @@ json = { workspace = true } ropey = "1.6.1" rspack_core = { version = "0.1.0", path = "../rspack_core" } rspack_error = { version = "0.1.0", path = "../rspack_error" } +rspack_util = { version = "0.1.0", path = "../rspack_util" } diff --git a/crates/rspack_plugin_json/src/json_exports_dependency.rs b/crates/rspack_plugin_json/src/json_exports_dependency.rs index 6a143a22c1d..7888a524bbe 100644 --- a/crates/rspack_plugin_json/src/json_exports_dependency.rs +++ b/crates/rspack_plugin_json/src/json_exports_dependency.rs @@ -1,9 +1,11 @@ use json::JsonValue; use rspack_core::{ - AsContextDependency, AsModuleDependency, Dependency, DependencyId, DependencyTemplate, - ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, ExportsSpec, ModuleGraph, TemplateContext, - TemplateReplaceSource, + AsContextDependency, AsModuleDependency, Compilation, Dependency, DependencyId, + DependencyTemplate, ExportNameOrSpec, ExportSpec, ExportsOfExportsSpec, ExportsSpec, ModuleGraph, + RuntimeSpec, TemplateContext, TemplateReplaceSource, }; +use rspack_util::ext::DynHash; + #[derive(Debug, Clone)] pub struct JsonExportsDependency { id: DependencyId, @@ -46,6 +48,15 @@ impl DependencyTemplate for JsonExportsDependency { fn dependency_id(&self) -> Option { Some(self.id) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + _compilation: &Compilation, + _runtime: Option<&RuntimeSpec>, + ) { + self.data.to_string().dyn_hash(hasher); + } } fn get_exports_from_data(data: &JsonValue) -> Option { diff --git a/crates/rspack_plugin_lazy_compilation/src/module.rs b/crates/rspack_plugin_lazy_compilation/src/module.rs index 358faa03675..074ee51790e 100644 --- a/crates/rspack_plugin_lazy_compilation/src/module.rs +++ b/crates/rspack_plugin_lazy_compilation/src/module.rs @@ -1,8 +1,8 @@ -use std::{hash::Hash, path::PathBuf, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use rspack_collections::Identifiable; use rspack_core::{ - impl_module_meta_info, module_namespace_promise, + impl_module_meta_info, module_namespace_promise, module_update_hash, rspack_sources::{RawSource, Source}, AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildResult, CodeGenerationData, CodeGenerationResult, Compilation, @@ -12,7 +12,10 @@ use rspack_core::{ }; use rspack_error::{Diagnosable, Diagnostic, Result}; use rspack_plugin_javascript::dependency::CommonJsRequireDependency; -use rspack_util::source_map::{ModuleSourceMapConfig, SourceMapKind}; +use rspack_util::{ + ext::DynHash, + source_map::{ModuleSourceMapConfig, SourceMapKind}, +}; use rustc_hash::FxHashSet; use crate::dependency::LazyCompilationDependency; @@ -25,7 +28,6 @@ pub(crate) struct LazyCompilationProxyModule { build_info: Option, build_meta: Option, factory_meta: Option, - original_module: ModuleIdentifier, cacheable: bool, readable_identifier: String, @@ -43,27 +45,6 @@ pub(crate) struct LazyCompilationProxyModule { pub client: String, } -impl Hash for LazyCompilationProxyModule { - fn hash(&self, state: &mut H) { - self.build_meta.hash(state); - self.original_module.hash(state); - self.readable_identifier.hash(state); - self.identifier.hash(state); - self.blocks.hash(state); - self.dependencies.hash(state); - } -} - -impl PartialEq for LazyCompilationProxyModule { - fn eq(&self, other: &Self) -> bool { - self.original_module == other.original_module - && self.readable_identifier == other.readable_identifier - && self.identifier == other.identifier - } -} - -impl Eq for LazyCompilationProxyModule {} - impl ModuleSourceMapConfig for LazyCompilationProxyModule { fn get_source_map_kind(&self) -> &SourceMapKind { &self.source_map_kind @@ -94,7 +75,6 @@ impl LazyCompilationProxyModule { build_info: None, build_meta: None, cacheable, - original_module, create_data, readable_identifier, resource, @@ -191,6 +171,7 @@ impl Module for LazyCompilationProxyModule { }) } + #[tracing::instrument(name = "LazyCompilationProxyModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -305,6 +286,18 @@ impl Module for LazyCompilationProxyModule { Ok(codegen_result) } + + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + self.active.dyn_hash(hasher); + self.data.dyn_hash(hasher); + Ok(()) + } } impl Identifiable for LazyCompilationProxyModule { diff --git a/crates/rspack_plugin_mf/Cargo.toml b/crates/rspack_plugin_mf/Cargo.toml index 35d9139b56c..7fc2a96f0f9 100644 --- a/crates/rspack_plugin_mf/Cargo.toml +++ b/crates/rspack_plugin_mf/Cargo.toml @@ -11,7 +11,6 @@ version = "0.1.0" rspack_collections = { version = "0.1.0", path = "../rspack_collections" } rspack_core = { version = "0.1.0", path = "../rspack_core" } rspack_error = { version = "0.1.0", path = "../rspack_error" } -rspack_hash = { version = "0.1.0", path = "../rspack_hash" } rspack_hook = { version = "0.1.0", path = "../rspack_hook" } rspack_loader_runner = { version = "0.1.0", path = "../rspack_loader_runner" } rspack_plugin_runtime = { version = "0.1.0", path = "../rspack_plugin_runtime" } diff --git a/crates/rspack_plugin_mf/src/container/container_entry_module.rs b/crates/rspack_plugin_mf/src/container/container_entry_module.rs index ace855a788e..52fd1bcaf0f 100644 --- a/crates/rspack_plugin_mf/src/container/container_entry_module.rs +++ b/crates/rspack_plugin_mf/src/container/container_entry_module.rs @@ -1,10 +1,10 @@ -use std::{borrow::Cow, hash::Hash}; +use std::borrow::Cow; use async_trait::async_trait; use rspack_collections::{Identifiable, Identifier}; use rspack_core::{ basic_function, block_promise, impl_module_meta_info, impl_source_map_config, module_raw, - returning_function, + module_update_hash, returning_function, rspack_sources::{RawSource, Source, SourceExt}, throw_missing_module_error_block, AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildMetaExportsType, BuildResult, @@ -14,7 +14,6 @@ use rspack_core::{ StaticExportsDependency, StaticExportsSpec, }; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_util::source_map::SourceMapKind; use rustc_hash::FxHashSet; @@ -122,13 +121,9 @@ impl Module for ContainerEntryModule { } async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let hash = hasher.digest(&build_context.compiler_options.output.hash_digest); - let mut blocks = vec![]; let mut dependencies: Vec = vec![]; for (name, options) in &self.exposes { @@ -160,7 +155,6 @@ impl Module for ContainerEntryModule { Ok(BuildResult { build_info: BuildInfo { - hash: Some(hash), strict: true, top_level_declarations: Some(FxHashSet::default()), ..Default::default() @@ -175,7 +169,7 @@ impl Module for ContainerEntryModule { }) } - #[allow(clippy::unwrap_in_result)] + #[tracing::instrument(name = "ContainerEntryModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -274,24 +268,19 @@ var init = function(shareScope, initScope) {{ } Ok(code_generation_result) } -} - -impl_empty_diagnosable_trait!(ContainerEntryModule); - -impl Hash for ContainerEntryModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__ContainerEntryModule".hash(state); - self.identifier().hash(state); - } -} -impl PartialEq for ContainerEntryModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for ContainerEntryModule {} +impl_empty_diagnosable_trait!(ContainerEntryModule); #[derive(Debug, Clone)] pub struct ExposeModuleMap(Vec<(String, String)>); diff --git a/crates/rspack_plugin_mf/src/container/fallback_module.rs b/crates/rspack_plugin_mf/src/container/fallback_module.rs index 056162bdeaa..942808dc8bb 100644 --- a/crates/rspack_plugin_mf/src/container/fallback_module.rs +++ b/crates/rspack_plugin_mf/src/container/fallback_module.rs @@ -1,10 +1,9 @@ use std::borrow::Cow; -use std::hash::Hash; use async_trait::async_trait; use rspack_collections::{Identifiable, Identifier}; use rspack_core::{ - impl_module_meta_info, impl_source_map_config, + impl_module_meta_info, impl_source_map_config, module_update_hash, rspack_sources::{RawSource, Source, SourceExt}, AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildResult, ChunkUkey, CodeGenerationResult, Compilation, ConcatenationScope, Context, DependenciesBlock, @@ -12,7 +11,6 @@ use rspack_core::{ RuntimeSpec, SourceType, }; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_util::source_map::SourceMapKind; use super::fallback_item_dependency::FallbackItemDependency; @@ -119,15 +117,11 @@ impl Module for FallbackModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let build_info = BuildInfo { strict: true, - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), ..Default::default() }; @@ -145,7 +139,7 @@ impl Module for FallbackModule { }) } - #[allow(clippy::unwrap_in_result)] + #[tracing::instrument(name = "FallbackModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -189,21 +183,16 @@ module.exports = loop(); codegen = codegen.with_javascript(RawSource::from(code).boxed()); Ok(codegen) } -} - -impl_empty_diagnosable_trait!(FallbackModule); - -impl Hash for FallbackModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__FallbackModule".hash(state); - self.identifier().hash(state); - } -} -impl PartialEq for FallbackModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for FallbackModule {} +impl_empty_diagnosable_trait!(FallbackModule); diff --git a/crates/rspack_plugin_mf/src/container/remote_module.rs b/crates/rspack_plugin_mf/src/container/remote_module.rs index 057f3d61b89..a8d77aeae7f 100644 --- a/crates/rspack_plugin_mf/src/container/remote_module.rs +++ b/crates/rspack_plugin_mf/src/container/remote_module.rs @@ -1,17 +1,15 @@ use std::borrow::Cow; -use std::hash::Hash; use async_trait::async_trait; use rspack_collections::{Identifiable, Identifier}; use rspack_core::{ - impl_module_meta_info, impl_source_map_config, + impl_module_meta_info, impl_source_map_config, module_update_hash, rspack_sources::{RawSource, Source, SourceExt}, AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildResult, CodeGenerationResult, Compilation, ConcatenationScope, Context, DependenciesBlock, DependencyId, FactoryMeta, LibIdentOptions, Module, ModuleIdentifier, ModuleType, RuntimeSpec, SourceType, }; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_util::source_map::SourceMapKind; use super::{ @@ -136,15 +134,11 @@ impl Module for RemoteModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let build_info = BuildInfo { strict: true, - hash: Some(hasher.digest(&build_context.compiler_options.output.hash_digest)), ..Default::default() }; @@ -166,7 +160,7 @@ impl Module for RemoteModule { }) } - #[allow(clippy::unwrap_in_result)] + #[tracing::instrument(name = "RemoteModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -187,21 +181,16 @@ impl Module for RemoteModule { }); Ok(codegen) } -} - -impl_empty_diagnosable_trait!(RemoteModule); - -impl Hash for RemoteModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__RemoteModule".hash(state); - self.identifier().hash(state); - } -} -impl PartialEq for RemoteModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for RemoteModule {} +impl_empty_diagnosable_trait!(RemoteModule); diff --git a/crates/rspack_plugin_mf/src/sharing/consume_shared_module.rs b/crates/rspack_plugin_mf/src/sharing/consume_shared_module.rs index f932ee7f1d7..46c023964ef 100644 --- a/crates/rspack_plugin_mf/src/sharing/consume_shared_module.rs +++ b/crates/rspack_plugin_mf/src/sharing/consume_shared_module.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, hash::Hash}; +use std::borrow::Cow; use async_trait::async_trait; use rspack_collections::{Identifiable, Identifier}; @@ -9,9 +9,9 @@ use rspack_core::{ DependenciesBlock, DependencyId, LibIdentOptions, Module, ModuleIdentifier, ModuleType, RuntimeGlobals, RuntimeSpec, SourceType, }; -use rspack_core::{ConcatenationScope, FactoryMeta}; +use rspack_core::{module_update_hash, ConcatenationScope, FactoryMeta}; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; +use rspack_util::ext::DynHash; use rspack_util::source_map::SourceMapKind; use super::{ @@ -145,13 +145,9 @@ impl Module for ConsumeSharedModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let hash = hasher.digest(&build_context.compiler_options.output.hash_digest); - let mut blocks = vec![]; let mut dependencies = vec![]; if let Some(fallback) = &self.options.import { @@ -165,10 +161,7 @@ impl Module for ConsumeSharedModule { } Ok(BuildResult { - build_info: BuildInfo { - hash: Some(hash), - ..Default::default() - }, + build_info: Default::default(), build_meta: Default::default(), dependencies, blocks, @@ -176,7 +169,7 @@ impl Module for ConsumeSharedModule { }) } - #[allow(clippy::unwrap_in_result)] + #[tracing::instrument(name = "ConsumeSharedModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -236,21 +229,17 @@ impl Module for ConsumeSharedModule { }); Ok(code_generation_result) } -} - -impl_empty_diagnosable_trait!(ConsumeSharedModule); - -impl Hash for ConsumeSharedModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__ConsumeSharedModule".hash(state); - self.identifier().hash(state); - } -} -impl PartialEq for ConsumeSharedModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + self.options.dyn_hash(hasher); + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for ConsumeSharedModule {} +impl_empty_diagnosable_trait!(ConsumeSharedModule); diff --git a/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs b/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs index c9c24e25fd5..5e9270e401b 100644 --- a/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs +++ b/crates/rspack_plugin_mf/src/sharing/consume_shared_plugin.rs @@ -21,7 +21,7 @@ use super::{ consume_shared_runtime_module::ConsumeSharedRuntimeModule, }; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash)] pub struct ConsumeOptions { pub import: Option, pub import_resolved: Option, diff --git a/crates/rspack_plugin_mf/src/sharing/provide_shared_module.rs b/crates/rspack_plugin_mf/src/sharing/provide_shared_module.rs index 975c66c293a..29d47fd581b 100644 --- a/crates/rspack_plugin_mf/src/sharing/provide_shared_module.rs +++ b/crates/rspack_plugin_mf/src/sharing/provide_shared_module.rs @@ -1,16 +1,16 @@ -use std::{borrow::Cow, hash::Hash}; +use std::borrow::Cow; use async_trait::async_trait; use rspack_collections::{Identifiable, Identifier}; use rspack_core::{ - async_module_factory, impl_module_meta_info, impl_source_map_config, rspack_sources::Source, - sync_module_factory, AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, BoxDependency, - BuildContext, BuildInfo, BuildMeta, BuildResult, CodeGenerationResult, Compilation, - ConcatenationScope, Context, DependenciesBlock, DependencyId, FactoryMeta, LibIdentOptions, - Module, ModuleIdentifier, ModuleType, RuntimeGlobals, RuntimeSpec, SourceType, + async_module_factory, impl_module_meta_info, impl_source_map_config, module_update_hash, + rspack_sources::Source, sync_module_factory, AsyncDependenciesBlock, + AsyncDependenciesBlockIdentifier, BoxDependency, BuildContext, BuildInfo, BuildMeta, BuildResult, + CodeGenerationResult, Compilation, ConcatenationScope, Context, DependenciesBlock, DependencyId, + FactoryMeta, LibIdentOptions, Module, ModuleIdentifier, ModuleType, RuntimeGlobals, RuntimeSpec, + SourceType, }; use rspack_error::{impl_empty_diagnosable_trait, Diagnostic, Result}; -use rspack_hash::RspackHash; use rspack_util::source_map::SourceMapKind; use super::{ @@ -139,13 +139,9 @@ impl Module for ProvideSharedModule { async fn build( &mut self, - build_context: BuildContext<'_>, + _build_context: BuildContext<'_>, _: Option<&Compilation>, ) -> Result { - let mut hasher = RspackHash::from(&build_context.compiler_options.output); - self.update_hash(&mut hasher); - let hash = hasher.digest(&build_context.compiler_options.output.hash_digest); - let mut blocks = vec![]; let mut dependencies = vec![]; let dep = Box::new(ProvideForSharedDependency::new(self.request.clone())); @@ -158,7 +154,6 @@ impl Module for ProvideSharedModule { Ok(BuildResult { build_info: BuildInfo { - hash: Some(hash), strict: true, ..Default::default() }, @@ -169,7 +164,7 @@ impl Module for ProvideSharedModule { }) } - #[allow(clippy::unwrap_in_result)] + #[tracing::instrument(name = "ProvideSharedModule::code_generation", skip_all, fields(identifier = ?self.identifier()))] fn code_generation( &self, compilation: &Compilation, @@ -214,21 +209,16 @@ impl Module for ProvideSharedModule { }); Ok(code_generation_result) } -} - -impl_empty_diagnosable_trait!(ProvideSharedModule); - -impl Hash for ProvideSharedModule { - fn hash(&self, state: &mut H) { - "__rspack_internal__ProvideSharedModule".hash(state); - self.identifier().hash(state); - } -} -impl PartialEq for ProvideSharedModule { - fn eq(&self, other: &Self) -> bool { - self.identifier() == other.identifier() + fn update_hash( + &self, + hasher: &mut dyn std::hash::Hasher, + compilation: &Compilation, + runtime: Option<&RuntimeSpec>, + ) -> Result<()> { + module_update_hash(self, hasher, compilation, runtime); + Ok(()) } } -impl Eq for ProvideSharedModule {} +impl_empty_diagnosable_trait!(ProvideSharedModule); diff --git a/crates/rspack_plugin_split_chunks/src/plugin/max_size.rs b/crates/rspack_plugin_split_chunks/src/plugin/max_size.rs index 41c85d15ea9..d2117049a86 100644 --- a/crates/rspack_plugin_split_chunks/src/plugin/max_size.rs +++ b/crates/rspack_plugin_split_chunks/src/plugin/max_size.rs @@ -1,5 +1,5 @@ -use std::borrow::Cow; use std::sync::LazyLock; +use std::{borrow::Cow, hash::Hash}; use rayon::prelude::*; use regex::Regex; @@ -9,7 +9,7 @@ use rspack_core::{ }; use rspack_error::Result; use rspack_hash::{RspackHash, RspackHashDigest}; -use rspack_util::{ext::DynHash, identifier::make_paths_relative}; +use rspack_util::identifier::make_paths_relative; use super::MaxSizeSetting; use crate::{SplitChunkSizes, SplitChunksPlugin}; @@ -53,7 +53,7 @@ fn get_size(module: &dyn Module, compilation: &Compilation) -> SplitChunkSizes { fn hash_filename(filename: &str, options: &CompilerOptions) -> String { let mut filename_hash = RspackHash::from(&options.output); - filename.dyn_hash(&mut filename_hash); + filename.hash(&mut filename_hash); let hash_digest: RspackHashDigest = filename_hash.digest(&options.output.hash_digest); hash_digest.rendered(8).to_string() } diff --git a/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$2faf8431c36246aaa99efe65186ef7b1$.css b/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$4b5109fbbb7c7970bd73f145985a8713$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$2faf8431c36246aaa99efe65186ef7b1$.css rename to tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$4b5109fbbb7c7970bd73f145985a8713$.css diff --git a/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$108a632b35566ba6e10f21437dc1e449$.css b/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$765cfc26ddecf262088215f69c92da3e$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$108a632b35566ba6e10f21437dc1e449$.css rename to tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$765cfc26ddecf262088215f69c92da3e$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$2948667d05523e0bdd4b433a8b432330$.css b/tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$c414a55a331514d313ce34913a677700$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$2948667d05523e0bdd4b433a8b432330$.css rename to tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$c414a55a331514d313ce34913a677700$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$63eb4b2b7412624c84340d8ef2383cb3$.css b/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$5038057b5dc54d459c2090d9455373d6$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$63eb4b2b7412624c84340d8ef2383cb3$.css rename to tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$5038057b5dc54d459c2090d9455373d6$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$7dc4057bc127528eb3d6e30affb70fc5$.css b/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$8ddf1fb367ac73deeba175a1de156238$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$7dc4057bc127528eb3d6e30affb70fc5$.css rename to tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$8ddf1fb367ac73deeba175a1de156238$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$fcf981e297c26c27907740d422c8fbb8$.css b/tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$7a92eedfa1f9813bd6a40e1910d3ecc0$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$fcf981e297c26c27907740d422c8fbb8$.css rename to tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$7a92eedfa1f9813bd6a40e1910d3ecc0$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$a033229f200a2cfbacbc9213dd60155a$.css b/tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$4f43297fc0af2c899c5e56fd341c7258$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$a033229f200a2cfbacbc9213dd60155a$.css rename to tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$4f43297fc0af2c899c5e56fd341c7258$.css diff --git a/tests/plugin-test/css-extract/cases/issue-6649/expected/main.js b/tests/plugin-test/css-extract/cases/issue-6649/expected/main.js index 2cba9427f59..4a43f6e9c50 100644 --- a/tests/plugin-test/css-extract/cases/issue-6649/expected/main.js +++ b/tests/plugin-test/css-extract/cases/issue-6649/expected/main.js @@ -100,14 +100,14 @@ __webpack_require__.e = function (chunkId) { // return url for filenames not based on template // return url for filenames based on template - return "" + chunkId + ".$" + "fcf981e297c26c279077" + "$.css"; + return "" + chunkId + ".$" + "51f879692dc41105d447" + "$.css"; }; })(); // webpack/runtime/get_full_hash (() => { __webpack_require__.h = function () { - return "9795acfd15167201fff0"; + return "5e241c5760a3e354e528"; }; })(); diff --git a/tests/plugin-test/css-extract/cases/js-hash/expected/style.$fc35cd7d3442366ea0e20c936c0d399c$.1.css b/tests/plugin-test/css-extract/cases/js-hash/expected/style.$33888ee88d16a14ff101cdf362266f8f$.1.css similarity index 100% rename from tests/plugin-test/css-extract/cases/js-hash/expected/style.$fc35cd7d3442366ea0e20c936c0d399c$.1.css rename to tests/plugin-test/css-extract/cases/js-hash/expected/style.$33888ee88d16a14ff101cdf362266f8f$.1.css diff --git a/tests/plugin-test/css-extract/cases/js-hash/expected/style.$2ebc9424ae217f7031ea75743effd066$.2.css b/tests/plugin-test/css-extract/cases/js-hash/expected/style.$cdffad3f0b38fa11c50b5a3ca2766a33$.2.css similarity index 100% rename from tests/plugin-test/css-extract/cases/js-hash/expected/style.$2ebc9424ae217f7031ea75743effd066$.2.css rename to tests/plugin-test/css-extract/cases/js-hash/expected/style.$cdffad3f0b38fa11c50b5a3ca2766a33$.2.css