From 0937ecd2024c1064445457511935ee42b09633d3 Mon Sep 17 00:00:00 2001 From: ahabhgk Date: Thu, 19 Sep 2024 17:37:21 +0800 Subject: [PATCH 1/4] fix: infer async modules when incremental enabled --- .../rspack_core/src/compiler/compilation.rs | 100 +++++++----------- crates/rspack_core/src/lib.rs | 2 +- crates/rspack_core/src/module.rs | 2 +- crates/rspack_core/src/module_graph/mod.rs | 10 +- .../rspack_core/src/unaffected_cache/mod.rs | 3 + .../src/unaffected_cache/mutations.rs | 53 ++++++++++ .../src/plugin/infer_async_modules_plugin.rs | 80 +++++++++----- .../async-modules/top-level-await/0/a.js | 1 + .../async-modules/top-level-await/0/b.js | 2 + .../async-modules/top-level-await/0/index.js | 45 ++++++++ .../async-modules/top-level-await/1/b.js | 2 + .../async-modules/top-level-await/2/b.js | 2 + 12 files changed, 212 insertions(+), 90 deletions(-) create mode 100644 crates/rspack_core/src/unaffected_cache/mutations.rs create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/a.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index 3e64444207e..576c496653d 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -34,14 +34,14 @@ use crate::{ get_chunk_from_ukey, get_mut_chunk_from_ukey, is_source_equal, old_cache::{use_code_splitting_cache, Cache as OldCache, CodeSplittingCache}, to_identifier, - unaffected_cache::UnaffectedModulesCache, + unaffected_cache::{Mutation, Mutations, UnaffectedModulesCache}, BoxDependency, BoxModule, CacheCount, CacheOptions, Chunk, ChunkByUkey, ChunkContentHash, ChunkGraph, ChunkGroupByUkey, ChunkGroupUkey, ChunkKind, ChunkUkey, CodeGenerationJob, CodeGenerationResult, 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, RuntimeSpecMap, SharedPluginDriver, SourceType, Stats, + Entrypoint, ExecuteModuleId, Filename, ImportVarMap, LocalFilenameFn, Logger, ModuleFactory, + ModuleGraph, ModuleGraphPartial, ModuleIdentifier, PathData, ResolverFactory, RuntimeGlobals, + RuntimeModule, RuntimeSpecMap, SharedPluginDriver, SourceType, Stats, }; pub type BuildDependency = ( @@ -173,6 +173,7 @@ pub struct Compilation { pub old_cache: Arc, pub code_splitting_cache: CodeSplittingCache, pub unaffected_modules_cache: Arc, + pub mutations: Option, pub hash: Option, pub used_chunk_ids: HashSet, @@ -227,6 +228,9 @@ impl Compilation { modified_files: HashSet, removed_files: HashSet, ) -> Self { + let mutations = options + .new_incremental_enabled() + .then(|| Mutations::default()); Self { id: CompilationId::new(), hot_index: 0, @@ -262,6 +266,7 @@ impl Compilation { build_time_executed_modules: Default::default(), old_cache, unaffected_modules_cache, + mutations, code_splitting_cache: Default::default(), hash: None, used_chunk_ids: Default::default(), @@ -757,57 +762,30 @@ impl Compilation { .collect::>())) } - #[instrument(name = "compilation:code_generation", skip(self))] - fn code_generation(&mut self) -> Result<()> { + #[instrument(name = "compilation:code_generation", skip_all)] + fn code_generation(&mut self, modules: IdentifierSet) -> Result<()> { let logger = self.get_logger("rspack.Compilation"); let mut codegen_cache_counter = match self.options.cache { CacheOptions::Disabled => None, _ => Some(logger.cache("module code generation cache")), }; - fn run_iteration( - compilation: &mut Compilation, - cache_counter: &mut Option, - filter_op: impl Fn(&(ModuleIdentifier, &Box)) -> bool + Sync + Send, - ) -> Result<()> { - let module_graph = compilation.get_module_graph(); - let modules: IdentifierSet = if compilation.options.new_incremental_enabled() { - let affected_modules = compilation - .unaffected_modules_cache - .get_affected_modules_with_chunk_graph() - .lock() - .expect("should lock") - .clone(); - affected_modules - .into_iter() - .map(|module_identifier| { - let module = module_graph - .module_by_identifier(&module_identifier) - .expect("should have module"); - (module_identifier, module) - }) - .filter(filter_op) - .map(|(id, _)| id) - .collect() + let module_graph = self.get_module_graph(); + let mut no_codegen_dependencies_modules = IdentifierSet::default(); + let mut has_codegen_dependencies_modules = IdentifierSet::default(); + for module_identifier in modules { + let module = module_graph + .module_by_identifier(&module_identifier) + .expect("should have module"); + if module.get_code_generation_dependencies().is_none() { + no_codegen_dependencies_modules.insert(module_identifier); } else { - compilation - .get_module_graph() - .modules() - .into_iter() - .filter(filter_op) - .map(|(id, _)| id) - .collect() - }; - compilation.code_generation_modules(cache_counter, modules) + has_codegen_dependencies_modules.insert(module_identifier); + } } - run_iteration(self, &mut codegen_cache_counter, |(_, module)| { - module.get_code_generation_dependencies().is_none() - })?; - - run_iteration(self, &mut codegen_cache_counter, |(_, module)| { - module.get_code_generation_dependencies().is_some() - })?; + self.code_generation_modules(&mut codegen_cache_counter, no_codegen_dependencies_modules)?; + self.code_generation_modules(&mut codegen_cache_counter, has_codegen_dependencies_modules)?; if let Some(counter) = codegen_cache_counter { logger.cache_end(counter); @@ -1216,16 +1194,25 @@ impl Compilation { .compute_affected_modules_with_chunk_graph(self); } - self.create_module_hashes(if self.options.new_incremental_enabled() { - self + let modules = if self.options.new_incremental_enabled() + && let Some(mutations) = &self.mutations + { + let mut modules = self .unaffected_modules_cache .get_affected_modules_with_chunk_graph() .lock() .expect("should lock") - .clone() + .clone(); + modules.extend(mutations.iter().filter_map(|mutation| match mutation { + Mutation::ModuleGraphModuleSetAsync { module } => Some(module), + _ => None, + })); + modules } else { self.get_module_graph().modules().keys().copied().collect() - })?; + }; + + self.create_module_hashes(modules.clone())?; let start = logger.time("optimize code generation"); plugin_driver @@ -1235,22 +1222,13 @@ impl Compilation { logger.time_end(start); let start = logger.time("code generation"); - self.code_generation()?; + self.code_generation(modules.clone())?; logger.time_end(start); let start = logger.time("runtime requirements"); self .process_runtime_requirements( - if self.options.new_incremental_enabled() { - self - .unaffected_modules_cache - .get_affected_modules_with_chunk_graph() - .lock() - .expect("should lock") - .clone() - } else { - self.get_module_graph().modules().keys().copied().collect() - }, + modules, self .chunk_by_ukey .keys() diff --git a/crates/rspack_core/src/lib.rs b/crates/rspack_core/src/lib.rs index 5127abbfc3e..063b75c9594 100644 --- a/crates/rspack_core/src/lib.rs +++ b/crates/rspack_core/src/lib.rs @@ -11,7 +11,7 @@ mod cgm_hash_results; mod cgm_runtime_requirement_results; mod dependencies_block; pub mod diagnostics; -mod unaffected_cache; +pub mod unaffected_cache; pub use dependencies_block::{ AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, DependenciesBlock, }; diff --git a/crates/rspack_core/src/module.rs b/crates/rspack_core/src/module.rs index a234a70d174..68733cc6a87 100644 --- a/crates/rspack_core/src/module.rs +++ b/crates/rspack_core/src/module.rs @@ -153,7 +153,7 @@ pub struct BuildMeta { } // webpack build info -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default)] pub struct BuildResult { /// Whether the result is cacheable, i.e shared between builds. pub build_meta: BuildMeta, diff --git a/crates/rspack_core/src/module_graph/mod.rs b/crates/rspack_core/src/module_graph/mod.rs index 38a47d5962e..7d708ab292b 100644 --- a/crates/rspack_core/src/module_graph/mod.rs +++ b/crates/rspack_core/src/module_graph/mod.rs @@ -985,10 +985,14 @@ impl<'a> ModuleGraph<'a> { .map(|mgm| mgm.is_async) } - pub fn set_async(&mut self, module_id: &ModuleIdentifier) { - if let Some(mgm) = self.module_graph_module_by_identifier_mut(module_id) { - mgm.is_async = true + pub fn set_async(&mut self, module_id: &ModuleIdentifier, is_async: bool) -> bool { + if let Some(mgm) = self.module_graph_module_by_identifier_mut(module_id) + && mgm.is_async != is_async + { + mgm.is_async = is_async; + return true; } + false } pub fn get_outgoing_connections( diff --git a/crates/rspack_core/src/unaffected_cache/mod.rs b/crates/rspack_core/src/unaffected_cache/mod.rs index 6d6044adbe5..4212639236b 100644 --- a/crates/rspack_core/src/unaffected_cache/mod.rs +++ b/crates/rspack_core/src/unaffected_cache/mod.rs @@ -1,8 +1,11 @@ +mod mutations; + use std::{ hash::{BuildHasherDefault, Hash, Hasher}, sync::Mutex, }; +pub use mutations::{Mutation, Mutations}; use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rspack_collections::{IdentifierDashMap, IdentifierHasher, IdentifierMap, IdentifierSet}; use rspack_util::fx_hash::FxIndexSet; diff --git a/crates/rspack_core/src/unaffected_cache/mutations.rs b/crates/rspack_core/src/unaffected_cache/mutations.rs new file mode 100644 index 00000000000..a28e35a8f6e --- /dev/null +++ b/crates/rspack_core/src/unaffected_cache/mutations.rs @@ -0,0 +1,53 @@ +use crate::ModuleIdentifier; + +#[derive(Debug, Default)] +pub struct Mutations { + inner: Vec, +} + +#[derive(Debug)] +pub enum Mutation { + ModuleGraphModuleSetAsync { module: ModuleIdentifier }, + PlaceholderForExtendable, +} + +impl Mutations { + pub fn add(&mut self, mutation: Mutation) { + self.inner.push(mutation); + } +} + +impl Mutations { + pub fn iter(&self) -> std::slice::Iter { + self.inner.iter() + } +} + +pub struct IntoIter { + inner: std::vec::IntoIter, +} + +impl Iterator for IntoIter { + type Item = Mutation; + + fn next(&mut self) -> Option { + self.inner.next() + } +} + +impl IntoIterator for Mutations { + type Item = Mutation; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { + inner: self.inner.into_iter(), + } + } +} + +impl Extend for Mutations { + fn extend>(&mut self, iter: T) { + self.inner.extend(iter); + } +} diff --git a/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs index 63320ee19e6..5adcf627895 100644 --- a/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs @@ -1,10 +1,9 @@ -use std::collections::HashSet; - use linked_hash_set::LinkedHashSet; -use rspack_collections::Identifier; +use rspack_collections::IdentifierSet; use rspack_core::{ - ApplyContext, Compilation, CompilationFinishModules, CompilerOptions, DependencyType, Plugin, - PluginContext, + unaffected_cache::{Mutation, Mutations}, + ApplyContext, Compilation, CompilationFinishModules, CompilerOptions, DependencyType, + ModuleIdentifier, Plugin, PluginContext, }; use rspack_error::Result; use rspack_hook::{plugin, plugin_hook}; @@ -15,30 +14,64 @@ pub struct InferAsyncModulesPlugin; #[plugin_hook(CompilationFinishModules for InferAsyncModulesPlugin)] async fn finish_modules(&self, compilation: &mut Compilation) -> Result<()> { - // fix: mut for-in - let mut queue = LinkedHashSet::new(); - let mut uniques = HashSet::new(); + let module_graph = compilation.get_module_graph(); + let modules: IdentifierSet = if compilation.options.new_incremental_enabled() { + compilation + .unaffected_modules_cache + .get_affected_modules_with_module_graph() + .lock() + .expect("should lock") + .clone() + } else { + module_graph.modules().keys().copied().collect() + }; + + let mut sync_modules = LinkedHashSet::new(); + let mut async_modules = LinkedHashSet::new(); + for module_identifier in modules { + let module = module_graph + .module_by_identifier(&module_identifier) + .expect("should have module"); + let build_meta = module.build_meta().expect("should have build meta"); + if build_meta.has_top_level_await { + async_modules.insert(module_identifier); + } else { + sync_modules.insert(module_identifier); + } + } - let mut modules: Vec = compilation - .get_module_graph() - .modules() - .values() - .filter(|m| { - if let Some(meta) = &m.build_meta() { - meta.has_top_level_await - } else { - false - } - }) - .map(|m| m.identifier()) - .collect(); + let mut mutations = compilation + .options + .new_incremental_enabled() + .then(|| Mutations::default()); - modules.retain(|m| queue.insert(*m)); + set_async_modules(compilation, sync_modules, false, &mut mutations); + set_async_modules(compilation, async_modules, true, &mut mutations); + + if let Some(compilation_mutations) = &mut compilation.mutations + && let Some(mutations) = mutations + { + compilation_mutations.extend(mutations); + } + Ok(()) +} + +fn set_async_modules( + compilation: &mut Compilation, + modules: LinkedHashSet, + is_async: bool, + mutations: &mut Option, +) { + let mut uniques = IdentifierSet::from_iter(modules.iter().copied()); + let mut queue = modules; let mut module_graph = compilation.get_module_graph_mut(); while let Some(module) = queue.pop_front() { - module_graph.set_async(&module); + let changed = module_graph.set_async(&module, is_async); + if changed && let Some(mutations) = mutations { + mutations.add(Mutation::ModuleGraphModuleSetAsync { module }); + } module_graph .get_incoming_connections(&module) .iter() @@ -60,7 +93,6 @@ async fn finish_modules(&self, compilation: &mut Compilation) -> Result<()> { } }); } - Ok(()) } impl Plugin for InferAsyncModulesPlugin { diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/a.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/a.js new file mode 100644 index 00000000000..78ae12cc7e1 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/a.js @@ -0,0 +1 @@ +import "./b" diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js new file mode 100644 index 00000000000..e7534f41882 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js @@ -0,0 +1,2 @@ +export const b = 1; +globalThis.b = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js new file mode 100644 index 00000000000..4f6c6640094 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js @@ -0,0 +1,45 @@ +// -- code start -- + +import "./a" + +// bailout inline modules optimization +module; +// fs +const fs = __non_webpack_require__("fs"); + +it("should have correct value", async () => { + expect(globalThis.b).toBe(1) + const content = await fs.promises.readFile(__filename, "utf-8") + switch (WATCH_STEP) { + case "0": + case "2": { + expect(!isAsyncModule(content, "./index.js")) + expect(!isAsyncModule(content, "./a.js")) + expect(!isAsyncModule(content, "./b.js")) + expect(!hasAsyncModuleRuntime(content)) + break; + } + case "1": { + expect(isAsyncModule(content, "./index.js")) + expect(isAsyncModule(content, "./a.js")) + expect(isAsyncModule(content, "./b.js")) + expect(hasAsyncModuleRuntime(content)) + break; + } + } +}) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +function isAsyncModule(content, moduleId) { + const regex = new RegExp(`\\"${escapeRegExp(moduleId)}":.*\\{\\s([\\S\\s]*)\\/\\/ -- code start --`) + const [, header] = regex.exec(content) + return header.trim().startsWith("__webpack_require__.a(") +} + +function hasAsyncModuleRuntime(content) { + const comment = "//" + ["webpack", "runtime", "async_module"].join("/"); + return content.includes(comment) +} diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js new file mode 100644 index 00000000000..1673ae7e116 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js @@ -0,0 +1,2 @@ +export const b = await 1; +globalThis.b = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js new file mode 100644 index 00000000000..e7534f41882 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js @@ -0,0 +1,2 @@ +export const b = 1; +globalThis.b = b; From 663959b0c93f6ea0884b681d79e3498c0f30102e Mon Sep 17 00:00:00 2001 From: ahabhgk Date: Thu, 19 Sep 2024 17:41:14 +0800 Subject: [PATCH 2/4] fix: infer async modules when incremental enabled --- crates/rspack_core/src/compiler/compilation.rs | 4 +--- .../src/plugin/infer_async_modules_plugin.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/rspack_core/src/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index 576c496653d..0c90760278e 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -228,9 +228,7 @@ impl Compilation { modified_files: HashSet, removed_files: HashSet, ) -> Self { - let mutations = options - .new_incremental_enabled() - .then(|| Mutations::default()); + let mutations = options.new_incremental_enabled().then(Mutations::default); Self { id: CompilationId::new(), hot_index: 0, diff --git a/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs index 5adcf627895..a0276e6168d 100644 --- a/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs @@ -43,7 +43,7 @@ async fn finish_modules(&self, compilation: &mut Compilation) -> Result<()> { let mut mutations = compilation .options .new_incremental_enabled() - .then(|| Mutations::default()); + .then(Mutations::default); set_async_modules(compilation, sync_modules, false, &mut mutations); set_async_modules(compilation, async_modules, true, &mut mutations); From 78f5ae46876e7fb5a07c4b0bef3f28de73066f21 Mon Sep 17 00:00:00 2001 From: ahabhgk Date: Fri, 20 Sep 2024 18:26:49 +0800 Subject: [PATCH 3/4] fix: perf and more test --- .../src/chunk_graph/chunk_graph_module.rs | 6 +- .../rspack_core/src/compiler/compilation.rs | 2 + crates/rspack_core/src/compiler/hmr.rs | 1 + .../src/dependency/runtime_template.rs | 14 +-- crates/rspack_core/src/module_graph/mod.rs | 42 ++++--- crates/rspack_core/src/module_graph/module.rs | 2 - .../esm/harmony_compatibility_dependency.rs | 4 +- ...ny_export_imported_specifier_dependency.rs | 6 +- .../esm/harmony_import_dependency.rs | 2 +- .../src/plugin/infer_async_modules_plugin.rs | 103 +++++++++++++----- .../src/plugin/module_concatenation_plugin.rs | 10 +- .../src/module_library_plugin.rs | 8 +- .../src/parser_and_generator.rs | 4 +- .../async-modules/top-level-await/0/b.js | 2 - .../top-level-await/0/{ => case1}/a.js | 0 .../top-level-await/0/case1/b.js | 2 + .../top-level-await/0/case1/index.js | 27 +++++ .../top-level-await/0/case2/a.js | 1 + .../top-level-await/0/case2/b.js | 4 + .../top-level-await/0/case2/c.js | 1 + .../top-level-await/0/case2/index.js | 22 ++++ .../top-level-await/0/case3/a.js | 2 + .../top-level-await/0/case3/b.js | 2 + .../top-level-await/0/case3/c.js | 1 + .../top-level-await/0/case3/index.js | 22 ++++ .../async-modules/top-level-await/0/index.js | 45 -------- .../async-modules/top-level-await/0/utils.js | 20 ++++ .../top-level-await/1/{ => case1}/b.js | 2 +- .../top-level-await/1/case2/b.js | 4 + .../top-level-await/1/case3/b.js | 2 + .../async-modules/top-level-await/2/b.js | 2 - .../top-level-await/2/case1/b.js | 2 + .../top-level-await/2/case2/b.js | 4 + .../top-level-await/2/case3/b.js | 2 + .../top-level-await/rspack.config.js | 27 +++++ .../top-level-await/test.config.js | 12 ++ 36 files changed, 284 insertions(+), 128 deletions(-) delete mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js rename packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/{ => case1}/a.js (100%) create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/index.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/a.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/c.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/index.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/a.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/c.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/index.js delete mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/utils.js rename packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/{ => case1}/b.js (54%) create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case2/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case3/b.js delete mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case1/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case2/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case3/b.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/rspack.config.js create mode 100644 packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/test.config.js 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 90b9a4d0980..650571d0808 100644 --- a/crates/rspack_core/src/chunk_graph/chunk_graph_module.rs +++ b/crates/rspack_core/src/chunk_graph/chunk_graph_module.rs @@ -10,8 +10,8 @@ use tracing::instrument; use crate::{ get_chunk_group_from_ukey, AsyncDependenciesBlockIdentifier, ChunkByUkey, ChunkGroup, - ChunkGroupByUkey, ChunkGroupUkey, ChunkUkey, Compilation, ModuleIdentifier, RuntimeGlobals, - RuntimeSpec, RuntimeSpecMap, RuntimeSpecSet, + ChunkGroupByUkey, ChunkGroupUkey, ChunkUkey, Compilation, ModuleGraph, ModuleIdentifier, + RuntimeGlobals, RuntimeSpec, RuntimeSpecMap, RuntimeSpecSet, }; use crate::{ChunkGraph, Module}; @@ -219,7 +219,7 @@ impl ChunkGraph { 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); + ModuleGraph::is_async(compilation, &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/compiler/compilation.rs b/crates/rspack_core/src/compiler/compilation.rs index ea6f9b9c6d4..bbbe6e7ce82 100644 --- a/crates/rspack_core/src/compiler/compilation.rs +++ b/crates/rspack_core/src/compiler/compilation.rs @@ -164,6 +164,7 @@ pub struct Compilation { pub named_chunks: HashMap, pub named_chunk_groups: HashMap, + pub async_modules: IdentifierSet, pub code_generation_results: CodeGenerationResults, pub cgm_hash_results: CgmHashResults, pub cgm_runtime_requirements_results: CgmRuntimeRequirementsResults, @@ -256,6 +257,7 @@ impl Compilation { named_chunks: Default::default(), named_chunk_groups: Default::default(), + async_modules: Default::default(), code_generation_results: Default::default(), cgm_hash_results: Default::default(), cgm_runtime_requirements_results: Default::default(), diff --git a/crates/rspack_core/src/compiler/hmr.rs b/crates/rspack_core/src/compiler/hmr.rs index e6c709d1ffc..8c318d6d003 100644 --- a/crates/rspack_core/src/compiler/hmr.rs +++ b/crates/rspack_core/src/compiler/hmr.rs @@ -98,6 +98,7 @@ impl Compiler { } if self.options.new_incremental_enabled() { + new_compilation.async_modules = std::mem::take(&mut self.compilation.async_modules); new_compilation.cgm_hash_results = std::mem::take(&mut self.compilation.cgm_hash_results); new_compilation.code_generation_results = std::mem::take(&mut self.compilation.code_generation_results); diff --git a/crates/rspack_core/src/dependency/runtime_template.rs b/crates/rspack_core/src/dependency/runtime_template.rs index 18ab437e495..189d33da560 100644 --- a/crates/rspack_core/src/dependency/runtime_template.rs +++ b/crates/rspack_core/src/dependency/runtime_template.rs @@ -472,14 +472,12 @@ pub fn module_namespace_promise( fake_type |= FakeNamespaceObjectMode::MERGE_PROPERTIES; } runtime_requirements.insert(RuntimeGlobals::CREATE_FAKE_NAMESPACE_OBJECT); - if matches!( - compilation.get_module_graph().is_async( - compilation - .get_module_graph() - .module_identifier_by_dependency_id(dep_id) - .expect("should have module") - ), - Some(true) + if ModuleGraph::is_async( + compilation, + compilation + .get_module_graph() + .module_identifier_by_dependency_id(dep_id) + .expect("should have module"), ) { if let Some(header) = header { appending = format!( diff --git a/crates/rspack_core/src/module_graph/mod.rs b/crates/rspack_core/src/module_graph/mod.rs index 7d708ab292b..fab1573ed5f 100644 --- a/crates/rspack_core/src/module_graph/mod.rs +++ b/crates/rspack_core/src/module_graph/mod.rs @@ -7,8 +7,8 @@ use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet}; use swc_core::ecma::atoms::Atom; use crate::{ - AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, Dependency, ExportProvided, - ProvidedExports, RuntimeSpec, UsedExports, + AsyncDependenciesBlock, AsyncDependenciesBlockIdentifier, Compilation, Dependency, + ExportProvided, ProvidedExports, RuntimeSpec, UsedExports, }; mod module; pub use module::*; @@ -370,11 +370,12 @@ impl<'a> ModuleGraph<'a> { /// Make sure both source and target module are exists in module graph pub fn clone_module_attributes( - &mut self, + compilation: &mut Compilation, source_module: &ModuleIdentifier, target_module: &ModuleIdentifier, ) { - let old_mgm = self + let mut module_graph = compilation.get_module_graph_mut(); + let old_mgm = module_graph .module_graph_module_by_identifier(source_module) .expect("should have mgm"); @@ -384,16 +385,17 @@ impl<'a> ModuleGraph<'a> { old_mgm.pre_order_index, old_mgm.depth, old_mgm.exports, - old_mgm.is_async, ); - let new_mgm = self + let new_mgm = module_graph .module_graph_module_by_identifier_mut(target_module) .expect("should have mgm"); new_mgm.post_order_index = assign_tuple.0; new_mgm.pre_order_index = assign_tuple.1; new_mgm.depth = assign_tuple.2; new_mgm.exports = assign_tuple.3; - new_mgm.is_async = assign_tuple.4; + + let is_async = ModuleGraph::is_async(compilation, source_module); + ModuleGraph::set_async(compilation, *target_module, is_async); } pub fn move_module_connections( @@ -979,20 +981,24 @@ impl<'a> ModuleGraph<'a> { has_connections } - pub fn is_async(&self, module_id: &ModuleIdentifier) -> Option { - self - .module_graph_module_by_identifier(module_id) - .map(|mgm| mgm.is_async) + pub fn is_async(compilation: &Compilation, module_id: &ModuleIdentifier) -> bool { + compilation.async_modules.contains(module_id) } - pub fn set_async(&mut self, module_id: &ModuleIdentifier, is_async: bool) -> bool { - if let Some(mgm) = self.module_graph_module_by_identifier_mut(module_id) - && mgm.is_async != is_async - { - mgm.is_async = is_async; - return true; + pub fn set_async( + compilation: &mut Compilation, + module_id: ModuleIdentifier, + is_async: bool, + ) -> bool { + let original = Self::is_async(compilation, &module_id); + if original == is_async { + return false; + } + if original { + compilation.async_modules.remove(&module_id) + } else { + compilation.async_modules.insert(module_id) } - false } pub fn get_outgoing_connections( diff --git a/crates/rspack_core/src/module_graph/module.rs b/crates/rspack_core/src/module_graph/module.rs index d3738ce206e..8e981e45e80 100644 --- a/crates/rspack_core/src/module_graph/module.rs +++ b/crates/rspack_core/src/module_graph/module.rs @@ -23,7 +23,6 @@ pub struct ModuleGraphModule { pub post_order_index: Option, pub exports: ExportsInfo, pub profile: Option>, - pub is_async: bool, pub depth: Option, pub optimization_bailout: Vec, } @@ -41,7 +40,6 @@ impl ModuleGraphModule { post_order_index: None, exports: exports_info, profile: None, - is_async: false, depth: None, optimization_bailout: vec![], } 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 52754deaa04..50c89896581 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,5 +1,5 @@ use rspack_core::{ - AsDependency, Compilation, DependencyTemplate, InitFragmentKey, InitFragmentStage, + AsDependency, Compilation, DependencyTemplate, InitFragmentKey, InitFragmentStage, ModuleGraph, NormalInitFragment, RuntimeGlobals, RuntimeSpec, TemplateContext, TemplateReplaceSource, UsageState, }; @@ -54,7 +54,7 @@ impl DependencyTemplate for HarmonyCompatibilityDependency { ))); } - if matches!(module_graph.is_async(&module.identifier()), Some(true)) { + if ModuleGraph::is_async(compilation, &module.identifier()) { runtime_requirements.insert(RuntimeGlobals::MODULE); runtime_requirements.insert(RuntimeGlobals::ASYNC_MODULE); init_fragments.push(Box::new(NormalInitFragment::new( 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 c05e3a8c341..c4105b00c05 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 @@ -469,11 +469,11 @@ impl HarmonyExportImportedSpecifierDependency { fn add_export_fragments(&self, ctxt: &mut TemplateContext, mut mode: ExportMode) { let TemplateContext { - compilation, module, runtime_requirements, .. } = ctxt; + let compilation = ctxt.compilation; let mut fragments = vec![]; let mg = &compilation.get_module_graph(); let module_identifier = module.identifier(); @@ -624,7 +624,6 @@ impl HarmonyExportImportedSpecifierDependency { } else { RuntimeCondition::Boolean(true) }; - let is_async = mg.is_async(&module_identifier).unwrap_or_default(); let stmt = self.get_conditional_reexport_statement( ctxt, name, @@ -632,6 +631,7 @@ impl HarmonyExportImportedSpecifierDependency { ids[0].clone(), ValueKey::Vec(ids), ); + let is_async = ModuleGraph::is_async(compilation, &module_identifier); fragments.push(Box::new(ConditionalInitFragment::new( stmt, if is_async { @@ -691,7 +691,7 @@ impl HarmonyExportImportedSpecifierDependency { .module_by_identifier(&module.identifier()) .expect("should have module graph module"); let exports_name = module.get_exports_argument(); - let is_async = mg.is_async(&module.identifier()).unwrap_or_default(); + let is_async = ModuleGraph::is_async(compilation, &module.identifier()); fragments.push( NormalInitFragment::new( format!( 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 781e98593a9..8437204e183 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 @@ -169,7 +169,7 @@ pub fn harmony_import_dependency_apply( } let is_async_module = - matches!(ref_module, Some(ref_module) if module_graph.is_async(ref_module) == Some(true)); + matches!(ref_module, Some(ref_module) if ModuleGraph::is_async(compilation, ref_module)); if is_async_module { init_fragments.push(Box::new(ConditionalInitFragment::new( content.0, diff --git a/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs index a0276e6168d..45d1bc7d712 100644 --- a/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/infer_async_modules_plugin.rs @@ -3,7 +3,7 @@ use rspack_collections::IdentifierSet; use rspack_core::{ unaffected_cache::{Mutation, Mutations}, ApplyContext, Compilation, CompilationFinishModules, CompilerOptions, DependencyType, - ModuleIdentifier, Plugin, PluginContext, + ModuleGraph, ModuleIdentifier, Plugin, PluginContext, }; use rspack_error::Result; use rspack_hook::{plugin, plugin_hook}; @@ -45,8 +45,8 @@ async fn finish_modules(&self, compilation: &mut Compilation) -> Result<()> { .new_incremental_enabled() .then(Mutations::default); - set_async_modules(compilation, sync_modules, false, &mut mutations); - set_async_modules(compilation, async_modules, true, &mut mutations); + set_sync_modules(compilation, sync_modules, &mut mutations); + set_async_modules(compilation, async_modules, &mut mutations); if let Some(compilation_mutations) = &mut compilation.mutations && let Some(mutations) = mutations @@ -57,41 +57,88 @@ async fn finish_modules(&self, compilation: &mut Compilation) -> Result<()> { Ok(()) } -fn set_async_modules( +fn set_sync_modules( compilation: &mut Compilation, modules: LinkedHashSet, - is_async: bool, mutations: &mut Option, ) { - let mut uniques = IdentifierSet::from_iter(modules.iter().copied()); let mut queue = modules; - let mut module_graph = compilation.get_module_graph_mut(); while let Some(module) = queue.pop_front() { - let changed = module_graph.set_async(&module, is_async); - if changed && let Some(mutations) = mutations { - mutations.add(Mutation::ModuleGraphModuleSetAsync { module }); - } - module_graph - .get_incoming_connections(&module) + let module_graph = compilation.get_module_graph(); + if module_graph + .get_outgoing_connections(&module) .iter() - .filter(|con| { - if let Some(dep) = module_graph.dependency_by_id(&con.dependency_id) { - matches!( - dep.dependency_type(), - DependencyType::EsmImport | DependencyType::EsmExport - ) - } else { - false - } - }) - .for_each(|con| { - if let Some(id) = &con.original_module_identifier { - if uniques.insert(*id) { + .filter_map(|con| module_graph.module_identifier_by_dependency_id(&con.dependency_id)) + .any(|module| ModuleGraph::is_async(compilation, module)) + { + // We can't safely reset is_async to false if there are any outgoing module is async + continue; + } + // The module is_async will also decide its parent module is_async, so if the module is_async + // is not changed, this means its parent module will be not affected, so we stop the infer at here. + // This also applies to set_async_modules + if ModuleGraph::set_async(compilation, module, false) { + if let Some(mutations) = mutations { + mutations.add(Mutation::ModuleGraphModuleSetAsync { module }); + } + let module_graph = compilation.get_module_graph(); + module_graph + .get_incoming_connections(&module) + .iter() + .filter(|con| { + module_graph + .dependency_by_id(&con.dependency_id) + .map(|dep| { + matches!( + dep.dependency_type(), + DependencyType::EsmImport | DependencyType::EsmExport + ) + }) + .unwrap_or_default() + }) + .for_each(|con| { + if let Some(id) = &con.original_module_identifier { + queue.insert(*id); + } + }); + } + } +} + +fn set_async_modules( + compilation: &mut Compilation, + modules: LinkedHashSet, + mutations: &mut Option, +) { + let mut queue = modules; + + while let Some(module) = queue.pop_front() { + if ModuleGraph::set_async(compilation, module, true) { + if let Some(mutations) = mutations { + mutations.add(Mutation::ModuleGraphModuleSetAsync { module }); + } + let module_graph = compilation.get_module_graph(); + module_graph + .get_incoming_connections(&module) + .iter() + .filter(|con| { + module_graph + .dependency_by_id(&con.dependency_id) + .map(|dep| { + matches!( + dep.dependency_type(), + DependencyType::EsmImport | DependencyType::EsmExport + ) + }) + .unwrap_or_default() + }) + .for_each(|con| { + if let Some(id) = &con.original_module_identifier { queue.insert(*id); } - } - }); + }); + } } } diff --git a/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs b/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs index 1ba8421a3f8..1db1876b6be 100644 --- a/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs +++ b/crates/rspack_plugin_javascript/src/plugin/module_concatenation_plugin.rs @@ -654,9 +654,10 @@ impl ModuleConcatenationPlugin { .exports; let module_graph_module = ModuleGraphModule::new(new_module.id(), root_mgm_exports); module_graph.add_module_graph_module(module_graph_module); - module_graph.clone_module_attributes(&root_module_id, &new_module.id()); + ModuleGraph::clone_module_attributes(compilation, &root_module_id, &new_module.id()); // integrate + let mut module_graph = compilation.get_module_graph_mut(); for m in modules_set { if m == &root_module_id { continue; @@ -752,12 +753,7 @@ impl ModuleConcatenationPlugin { let m = module_graph.module_by_identifier(&module_id); - // If the result is `None`, that means we have some differences with webpack, - // https://github.com/webpack/webpack/blob/1f99ad6367f2b8a6ef17cce0e058f7a67fb7db18/lib/optimize/ModuleConcatenationPlugin.js#L168-L171 - if module_graph - .is_async(&module_id) - .expect("should have async result") - { + if ModuleGraph::is_async(compilation, &module_id) { bailout_reason.push("Module is async".into()); return (false, false, module_id, bailout_reason); } diff --git a/crates/rspack_plugin_library/src/module_library_plugin.rs b/crates/rspack_plugin_library/src/module_library_plugin.rs index 624786b410d..a9dac69199a 100644 --- a/crates/rspack_plugin_library/src/module_library_plugin.rs +++ b/crates/rspack_plugin_library/src/module_library_plugin.rs @@ -3,7 +3,8 @@ use std::hash::Hash; use rspack_core::rspack_sources::{ConcatSource, RawSource, SourceExt}; use rspack_core::{ property_access, to_identifier, ApplyContext, ChunkUkey, Compilation, CompilationParams, - CompilerCompilation, CompilerOptions, LibraryOptions, ModuleIdentifier, Plugin, PluginContext, + CompilerCompilation, CompilerOptions, LibraryOptions, ModuleGraph, ModuleIdentifier, Plugin, + PluginContext, }; use rspack_error::{error_bail, Result}; use rspack_hash::RspackHash; @@ -64,12 +65,11 @@ fn render_startup( return Ok(()); }; let mut source = ConcatSource::default(); + let is_async = ModuleGraph::is_async(compilation, module); let module_graph = compilation.get_module_graph(); source.add(render_source.source.clone()); let mut exports = vec![]; - if let Some(is_async) = module_graph.is_async(module) - && is_async - { + if is_async { source.add(RawSource::from( "__webpack_exports__ = await __webpack_exports__;\n", )); diff --git a/crates/rspack_plugin_wasm/src/parser_and_generator.rs b/crates/rspack_plugin_wasm/src/parser_and_generator.rs index 8f2cea3f1fa..b424d5047b3 100644 --- a/crates/rspack_plugin_wasm/src/parser_and_generator.rs +++ b/crates/rspack_plugin_wasm/src/parser_and_generator.rs @@ -8,7 +8,7 @@ use rspack_core::rspack_sources::{BoxSource, RawSource, Source, SourceExt}; use rspack_core::DependencyType::WasmImport; use rspack_core::{ AssetInfo, BoxDependency, BuildMetaExportsType, Compilation, FilenameTemplate, GenerateContext, - Module, ModuleDependency, ModuleIdentifier, NormalModule, ParseContext, ParseResult, + Module, ModuleDependency, ModuleGraph, ModuleIdentifier, NormalModule, ParseContext, ParseResult, ParserAndGenerator, PathData, RuntimeGlobals, SourceType, StaticExportsDependency, StaticExportsSpec, UsedName, }; @@ -173,7 +173,7 @@ impl ParserAndGenerator for AsyncWasmParserAndGenerator { let import_var = format!("WEBPACK_IMPORTED_MODULE_{}", itoa!(dep_modules.len())); let val = (import_var.clone(), mgm.id(chunk_graph)); - if matches!(module_graph.is_async(&mgm.module_identifier), Some(true)) { + if ModuleGraph::is_async(compilation, &mgm.module_identifier) { promises.push(import_var); } dep_modules.insert(mgm.module_identifier, val); diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js deleted file mode 100644 index e7534f41882..00000000000 --- a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/b.js +++ /dev/null @@ -1,2 +0,0 @@ -export const b = 1; -globalThis.b = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/a.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/a.js similarity index 100% rename from packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/a.js rename to packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/a.js diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/b.js new file mode 100644 index 00000000000..c8e753943c0 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/b.js @@ -0,0 +1,2 @@ +export const b = 0; +globalThis.case1 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/index.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/index.js new file mode 100644 index 00000000000..6d50c6f18ce --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case1/index.js @@ -0,0 +1,27 @@ +import "./a" +import { isAsyncModule, hasAsyncModuleRuntime } from "../utils" + +module; // bailout inline entry modules optimization +const fs = __non_webpack_require__("fs"); + +it("should have correct value", async () => { + expect(globalThis.case1).toBe(parseInt(WATCH_STEP, 10)) + const content = await fs.promises.readFile(__filename, "utf-8") + switch (WATCH_STEP) { + case "0": + case "2": { + expect(!isAsyncModule(content, "./case1/index.js")) + expect(!isAsyncModule(content, "./case1/a.js")) + expect(!isAsyncModule(content, "./case1/b.js")) + expect(!hasAsyncModuleRuntime(content)) + break; + } + case "1": { + expect(isAsyncModule(content, "./case1/index.js")) + expect(isAsyncModule(content, "./case1/a.js")) + expect(isAsyncModule(content, "./case1/b.js")) + expect(hasAsyncModuleRuntime(content)) + break; + } + } +}) diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/a.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/a.js new file mode 100644 index 00000000000..78ae12cc7e1 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/a.js @@ -0,0 +1 @@ +import "./b" diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/b.js new file mode 100644 index 00000000000..0b88fd6da9a --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/b.js @@ -0,0 +1,4 @@ +import "./c" + +export const b = 0; +globalThis.case2 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/c.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/c.js new file mode 100644 index 00000000000..79fb2770887 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/c.js @@ -0,0 +1 @@ +export const c = await 1; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/index.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/index.js new file mode 100644 index 00000000000..578080b11da --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case2/index.js @@ -0,0 +1,22 @@ +import "./a" +import { isAsyncModule, hasAsyncModuleRuntime } from "../utils" + +module; // bailout inline entry modules optimization +const fs = __non_webpack_require__("fs"); + +it("should have correct value", async () => { + expect(globalThis.case2).toBe(parseInt(WATCH_STEP, 10)) + const content = await fs.promises.readFile(__filename, "utf-8") + switch (WATCH_STEP) { + case "0": + case "1": + case "2": { + expect(isAsyncModule(content, "./case2/index.js")) + expect(isAsyncModule(content, "./case2/a.js")) + expect(isAsyncModule(content, "./case2/b.js")) + expect(isAsyncModule(content, "./case2/c.js")) + expect(hasAsyncModuleRuntime(content)) + break; + } + } +}) diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/a.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/a.js new file mode 100644 index 00000000000..d2063e2e953 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/a.js @@ -0,0 +1,2 @@ +import "./b" +import "./c" diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/b.js new file mode 100644 index 00000000000..7432315994e --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/b.js @@ -0,0 +1,2 @@ +export const b = 0; +globalThis.case3 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/c.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/c.js new file mode 100644 index 00000000000..79fb2770887 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/c.js @@ -0,0 +1 @@ +export const c = await 1; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/index.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/index.js new file mode 100644 index 00000000000..b4286c612ea --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/case3/index.js @@ -0,0 +1,22 @@ +import "./a" +import { isAsyncModule, hasAsyncModuleRuntime } from "../utils" + +module; // bailout inline entry modules optimization +const fs = __non_webpack_require__("fs"); + +it("should have correct value", async () => { + expect(globalThis.case3).toBe(parseInt(WATCH_STEP, 10)) + const content = await fs.promises.readFile(__filename, "utf-8") + switch (WATCH_STEP) { + case "0": + case "1": + case "2": { + expect(isAsyncModule(content, "./case3/index.js")) + expect(isAsyncModule(content, "./case3/a.js")) + expect(isAsyncModule(content, "./case3/b.js")) + expect(isAsyncModule(content, "./case3/c.js")) + expect(hasAsyncModuleRuntime(content)) + break; + } + } +}) diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js deleted file mode 100644 index 4f6c6640094..00000000000 --- a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/index.js +++ /dev/null @@ -1,45 +0,0 @@ -// -- code start -- - -import "./a" - -// bailout inline modules optimization -module; -// fs -const fs = __non_webpack_require__("fs"); - -it("should have correct value", async () => { - expect(globalThis.b).toBe(1) - const content = await fs.promises.readFile(__filename, "utf-8") - switch (WATCH_STEP) { - case "0": - case "2": { - expect(!isAsyncModule(content, "./index.js")) - expect(!isAsyncModule(content, "./a.js")) - expect(!isAsyncModule(content, "./b.js")) - expect(!hasAsyncModuleRuntime(content)) - break; - } - case "1": { - expect(isAsyncModule(content, "./index.js")) - expect(isAsyncModule(content, "./a.js")) - expect(isAsyncModule(content, "./b.js")) - expect(hasAsyncModuleRuntime(content)) - break; - } - } -}) - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); -} - -function isAsyncModule(content, moduleId) { - const regex = new RegExp(`\\"${escapeRegExp(moduleId)}":.*\\{\\s([\\S\\s]*)\\/\\/ -- code start --`) - const [, header] = regex.exec(content) - return header.trim().startsWith("__webpack_require__.a(") -} - -function hasAsyncModuleRuntime(content) { - const comment = "//" + ["webpack", "runtime", "async_module"].join("/"); - return content.includes(comment) -} diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/utils.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/utils.js new file mode 100644 index 00000000000..1cc38be88aa --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/0/utils.js @@ -0,0 +1,20 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +export function isAsyncModule(content, moduleId) { + const regex = new RegExp(`\\"${escapeRegExp(moduleId)}\\":.*\\{\\s([\\S\\s]*?)__webpack_require__\\.r\\(__webpack_exports__\\);`) + const result = regex.exec(content) + try { + const [, header] = result; + return header.trim().startsWith("__webpack_require__.a(") + } catch (e) { + console.log(content, moduleId, result) + throw e; + } +} + +export function hasAsyncModuleRuntime(content) { + const comment = "//" + ["webpack", "runtime", "async_module"].join("/"); + return content.includes(comment) +} diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case1/b.js similarity index 54% rename from packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js rename to packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case1/b.js index 1673ae7e116..3929fd20be7 100644 --- a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/b.js +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case1/b.js @@ -1,2 +1,2 @@ export const b = await 1; -globalThis.b = b; +globalThis.case1 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case2/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case2/b.js new file mode 100644 index 00000000000..4cd4f5ac1b2 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case2/b.js @@ -0,0 +1,4 @@ +import "./c" + +export const b = await 1; +globalThis.case2 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case3/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case3/b.js new file mode 100644 index 00000000000..e4bddd3ba61 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/1/case3/b.js @@ -0,0 +1,2 @@ +export const b = await 1; +globalThis.case3 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js deleted file mode 100644 index e7534f41882..00000000000 --- a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/b.js +++ /dev/null @@ -1,2 +0,0 @@ -export const b = 1; -globalThis.b = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case1/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case1/b.js new file mode 100644 index 00000000000..15b84a3f40b --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case1/b.js @@ -0,0 +1,2 @@ +export const b = 2; +globalThis.case1 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case2/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case2/b.js new file mode 100644 index 00000000000..cb99a548298 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case2/b.js @@ -0,0 +1,4 @@ +import "./c" + +export const b = 2; +globalThis.case2 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case3/b.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case3/b.js new file mode 100644 index 00000000000..f0efb6869b1 --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/2/case3/b.js @@ -0,0 +1,2 @@ +export const b = 2; +globalThis.case3 = b; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/rspack.config.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/rspack.config.js new file mode 100644 index 00000000000..a04e0acc85d --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/rspack.config.js @@ -0,0 +1,27 @@ +/** @type {import('@rspack/core').Configuration} */ +module.exports = [ + { + entry: { + case1: "./case1/index.js" + }, + output: { + filename: "case1.js", + } + }, + { + entry: { + case2: "./case2/index.js" + }, + output: { + filename: "case2.js", + } + }, + { + entry: { + case3: "./case3/index.js" + }, + output: { + filename: "case3.js", + } + } +]; diff --git a/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/test.config.js b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/test.config.js new file mode 100644 index 00000000000..f59d679015d --- /dev/null +++ b/packages/rspack-test-tools/tests/watchCases/async-modules/top-level-await/test.config.js @@ -0,0 +1,12 @@ +module.exports = { + findBundle(i) { + switch (i) { + case 0: + return `case1.js` + case 1: + return `case2.js` + case 2: + return `case3.js` + } + } +} From 6d392a9cc4ed9bfc58909b9d41f6d71e665673dd Mon Sep 17 00:00:00 2001 From: ahabhgk Date: Fri, 20 Sep 2024 18:47:43 +0800 Subject: [PATCH 4/4] update snap --- tests/plugin-test/copy-plugin/build/main.js | 2 +- ...1b7$.css => one_js.$0fbead3fcf058a7bcaa810f0daaa02f8$.css} | 0 ...852$.css => two_js.$fcffed5bfc474a7dfac52aaf639f0ddb$.css} | 0 ...4706d$.css => main.$f31af5dba4768b1ffd65f0ecaac279f5$.css} | 0 ...fb8$.css => entryA.$a977c0cf8f971f151cb91fbca1c8ac9e$.css} | 0 ...21f$.css => entryB.$db6a85db2a2c81f567d8000861bf0d58$.css} | 0 ...6f4$.css => 1.main.$f8538f5e56ec62182291732e591c1adf$.css} | 0 ...99c$.css => 2.main.$d9f7eb2a8f97615867bf6cc133b9d1df$.css} | 0 .../plugin-test/css-extract/cases/issue-6649/expected/main.js | 4 ++-- ...$.2.css => style.$1ba2a4aac89178ce862c28f809f968bc$.2.css} | 0 ...$.1.css => style.$df926c7a640798a9cbbacdc248c1b320$.1.css} | 0 11 files changed, 3 insertions(+), 3 deletions(-) rename tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/{one_js.$023ac0d4bb230615c43315b6b064c1b7$.css => one_js.$0fbead3fcf058a7bcaa810f0daaa02f8$.css} (100%) rename tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/{two_js.$72a8dd45a3f95df1891fb79708a5f852$.css => two_js.$fcffed5bfc474a7dfac52aaf639f0ddb$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash-1/expected/{main.$d4641399bd65817bb933f6126404706d$.css => main.$f31af5dba4768b1ffd65f0ecaac279f5$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/{entryA.$b5f353a4b96240d34000ec2751896fb8$.css => entryA.$a977c0cf8f971f151cb91fbca1c8ac9e$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/{entryB.$8c016b564d25bd3d0bfd87e38be3421f$.css => entryB.$db6a85db2a2c81f567d8000861bf0d58$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash/expected/{1.main.$aacd0ad1c42de0978eb78d1b45f776f4$.css => 1.main.$f8538f5e56ec62182291732e591c1adf$.css} (100%) rename tests/plugin-test/css-extract/cases/contenthash/expected/{2.main.$7a8f6d01ccfee2f287001c866d1d099c$.css => 2.main.$d9f7eb2a8f97615867bf6cc133b9d1df$.css} (100%) rename tests/plugin-test/css-extract/cases/js-hash/expected/{style.$0f94f124eac78739b528d3fc9e386fe8$.2.css => style.$1ba2a4aac89178ce862c28f809f968bc$.2.css} (100%) rename tests/plugin-test/css-extract/cases/js-hash/expected/{style.$0807b2b8361eb34664fe98ac7f3ec0fe$.1.css => style.$df926c7a640798a9cbbacdc248c1b320$.1.css} (100%) diff --git a/tests/plugin-test/copy-plugin/build/main.js b/tests/plugin-test/copy-plugin/build/main.js index 428e8108b62..33c479f42ea 100644 --- a/tests/plugin-test/copy-plugin/build/main.js +++ b/tests/plugin-test/copy-plugin/build/main.js @@ -1 +1 @@ -(()=>{"use strict";var r={},t={};function e(i){var o=t[i];if(void 0!==o)return o.exports;var n=t[i]={exports:{}};return r[i](n,n.exports,e),n.exports}e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(r){if("object"==typeof window)return window}}(),e.rv=function(){return"1.0.4"},(()=>{e.g.importScripts&&(r=e.g.location+"");var r,t=e.g.document;if(!r&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(r=t.currentScript.src),!r)){var i=t.getElementsByTagName("script");if(i.length){for(var o=i.length-1;o>-1&&(!r||!/^http(s?):/.test(r));)r=i[o--].src}}if(!r)throw Error("Automatic publicPath is not supported in this browser");r=r.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),e.p=r})(),e.ruid="bundler=rspack@1.0.4",e.p})(); \ No newline at end of file +(()=>{"use strict";var r={},t={};function e(i){var o=t[i];if(void 0!==o)return o.exports;var n=t[i]={exports:{}};return r[i](n,n.exports,e),n.exports}e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(r){if("object"==typeof window)return window}}(),e.rv=function(){return"1.0.5"},(()=>{e.g.importScripts&&(r=e.g.location+"");var r,t=e.g.document;if(!r&&t&&(t.currentScript&&"SCRIPT"===t.currentScript.tagName.toUpperCase()&&(r=t.currentScript.src),!r)){var i=t.getElementsByTagName("script");if(i.length){for(var o=i.length-1;o>-1&&(!r||!/^http(s?):/.test(r));)r=i[o--].src}}if(!r)throw Error("Automatic publicPath is not supported in this browser");r=r.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),e.p=r})(),e.ruid="bundler=rspack@1.0.5",e.p})(); \ No newline at end of file diff --git a/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$023ac0d4bb230615c43315b6b064c1b7$.css b/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$0fbead3fcf058a7bcaa810f0daaa02f8$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$023ac0d4bb230615c43315b6b064c1b7$.css rename to tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/one_js.$0fbead3fcf058a7bcaa810f0daaa02f8$.css diff --git a/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$72a8dd45a3f95df1891fb79708a5f852$.css b/tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$fcffed5bfc474a7dfac52aaf639f0ddb$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$72a8dd45a3f95df1891fb79708a5f852$.css rename to tests/plugin-test/css-extract/cases/content-entries-with-same-import/expected/two_js.$fcffed5bfc474a7dfac52aaf639f0ddb$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$d4641399bd65817bb933f6126404706d$.css b/tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$f31af5dba4768b1ffd65f0ecaac279f5$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$d4641399bd65817bb933f6126404706d$.css rename to tests/plugin-test/css-extract/cases/contenthash-1/expected/main.$f31af5dba4768b1ffd65f0ecaac279f5$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$b5f353a4b96240d34000ec2751896fb8$.css b/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$a977c0cf8f971f151cb91fbca1c8ac9e$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$b5f353a4b96240d34000ec2751896fb8$.css rename to tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryA.$a977c0cf8f971f151cb91fbca1c8ac9e$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$8c016b564d25bd3d0bfd87e38be3421f$.css b/tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$db6a85db2a2c81f567d8000861bf0d58$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$8c016b564d25bd3d0bfd87e38be3421f$.css rename to tests/plugin-test/css-extract/cases/contenthash-multiple-entries/expected/entryB.$db6a85db2a2c81f567d8000861bf0d58$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$aacd0ad1c42de0978eb78d1b45f776f4$.css b/tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$f8538f5e56ec62182291732e591c1adf$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$aacd0ad1c42de0978eb78d1b45f776f4$.css rename to tests/plugin-test/css-extract/cases/contenthash/expected/1.main.$f8538f5e56ec62182291732e591c1adf$.css diff --git a/tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$7a8f6d01ccfee2f287001c866d1d099c$.css b/tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$d9f7eb2a8f97615867bf6cc133b9d1df$.css similarity index 100% rename from tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$7a8f6d01ccfee2f287001c866d1d099c$.css rename to tests/plugin-test/css-extract/cases/contenthash/expected/2.main.$d9f7eb2a8f97615867bf6cc133b9d1df$.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 d2be4934404..8fb0fbe7f15 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 + ".$" + "9311d6f1607d2d130d8e" + "$.css"; + return "" + chunkId + ".$" + "bb3ca0a2a8332b9ea9ee" + "$.css"; }; })(); // webpack/runtime/get_full_hash (() => { __webpack_require__.h = function () { - return "930b6e3f0ca31fc490a2"; + return "5fcc30abf165502e2631"; }; })(); diff --git a/tests/plugin-test/css-extract/cases/js-hash/expected/style.$0f94f124eac78739b528d3fc9e386fe8$.2.css b/tests/plugin-test/css-extract/cases/js-hash/expected/style.$1ba2a4aac89178ce862c28f809f968bc$.2.css similarity index 100% rename from tests/plugin-test/css-extract/cases/js-hash/expected/style.$0f94f124eac78739b528d3fc9e386fe8$.2.css rename to tests/plugin-test/css-extract/cases/js-hash/expected/style.$1ba2a4aac89178ce862c28f809f968bc$.2.css diff --git a/tests/plugin-test/css-extract/cases/js-hash/expected/style.$0807b2b8361eb34664fe98ac7f3ec0fe$.1.css b/tests/plugin-test/css-extract/cases/js-hash/expected/style.$df926c7a640798a9cbbacdc248c1b320$.1.css similarity index 100% rename from tests/plugin-test/css-extract/cases/js-hash/expected/style.$0807b2b8361eb34664fe98ac7f3ec0fe$.1.css rename to tests/plugin-test/css-extract/cases/js-hash/expected/style.$df926c7a640798a9cbbacdc248c1b320$.1.css