Skip to content

Commit 696026b

Browse files
authored
refactor: use Module.needBuild to trigger lazy modules compile (#11507)
1 parent d453d86 commit 696026b

File tree

27 files changed

+121
-147
lines changed

27 files changed

+121
-147
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/node_binding/napi-binding.d.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,11 +2348,11 @@ export interface RawJsonParserOptions {
23482348
}
23492349

23502350
export interface RawLazyCompilationOption {
2351-
module: ((err: Error | null, arg: RawModuleArg) => RawModuleInfo)
2351+
currentActiveModules: ((err: Error | null, ) => Set<string>)
23522352
test?: RawLazyCompilationTest
23532353
entries: boolean
23542354
imports: boolean
2355-
cacheable: boolean
2355+
client: string
23562356
}
23572357

23582358
export interface RawLibManifestPluginOptions {
@@ -2410,11 +2410,6 @@ export interface RawLimitChunkCountPluginOptions {
24102410
maxChunks: number
24112411
}
24122412

2413-
export interface RawModuleArg {
2414-
module: string
2415-
path: string
2416-
}
2417-
24182413
export interface RawModuleFederationRuntimePluginOptions {
24192414
entryRuntime?: string | undefined
24202415
}

crates/rspack_binding_api/src/raw_options/raw_builtins/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,11 @@ impl<'a> BuiltinPlugin<'a> {
720720
let js_backend = JsBackend::from(&options);
721721
plugins.push(Box::new(
722722
rspack_plugin_lazy_compilation::plugin::LazyCompilationPlugin::new(
723-
options.cacheable,
724723
js_backend,
725724
options.test.map(|test| test.into()),
726725
options.entries,
727726
options.imports,
727+
options.client,
728728
),
729729
) as Box<dyn Plugin>)
730730
}

crates/rspack_binding_api/src/raw_options/raw_builtins/raw_lazy_compilation.rs

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use napi::{
55
bindgen_prelude::{FromNapiValue, ToNapiValue, ValidateNapiValue},
66
};
77
use napi_derive::napi;
8+
use rspack_collections::IdentifierSet;
89
use rspack_core::{CompilationId, CompilerId, Module, ModuleIdentifier};
910
use rspack_napi::threadsafe_function::ThreadsafeFunction;
1011
use rspack_plugin_lazy_compilation::{
11-
backend::{Backend, ModuleInfo},
12+
backend::Backend,
1213
plugin::{LazyCompilationTest, LazyCompilationTestCheck},
1314
};
1415
use rspack_regex::RspackRegex;
@@ -88,21 +89,15 @@ pub struct RawModuleInfo {
8889

8990
#[napi(object, object_to_js = false)]
9091
pub struct RawLazyCompilationOption {
91-
pub module: ThreadsafeFunction<RawModuleArg, RawModuleInfo>,
92+
pub current_active_modules: ThreadsafeFunction<(), std::collections::HashSet<String>>,
9293
pub test: Option<RawLazyCompilationTest>,
9394
pub entries: bool,
9495
pub imports: bool,
95-
pub cacheable: bool,
96-
}
97-
98-
#[napi(object)]
99-
pub struct RawModuleArg {
100-
pub module: String,
101-
pub path: String,
96+
pub client: String,
10297
}
10398

10499
pub(crate) struct JsBackend {
105-
module: ThreadsafeFunction<RawModuleArg, RawModuleInfo>,
100+
current_active_modules: ThreadsafeFunction<(), std::collections::HashSet<String>>,
106101
}
107102

108103
impl std::fmt::Debug for JsBackend {
@@ -114,31 +109,20 @@ impl std::fmt::Debug for JsBackend {
114109
impl From<&RawLazyCompilationOption> for JsBackend {
115110
fn from(value: &RawLazyCompilationOption) -> Self {
116111
Self {
117-
module: value.module.clone(),
112+
current_active_modules: value.current_active_modules.clone(),
118113
}
119114
}
120115
}
121116

122117
#[async_trait::async_trait]
123118
impl Backend for JsBackend {
124-
async fn module(
125-
&mut self,
126-
identifier: ModuleIdentifier,
127-
path: String,
128-
) -> rspack_error::Result<ModuleInfo> {
129-
let module_info = self
130-
.module
131-
.call_with_sync(RawModuleArg {
132-
module: identifier.to_string(),
133-
path,
134-
})
119+
async fn current_active_modules(&mut self) -> rspack_error::Result<IdentifierSet> {
120+
let active_modules = self
121+
.current_active_modules
122+
.call_with_sync(())
135123
.await
136124
.expect("channel should have result");
137125

138-
Ok(ModuleInfo {
139-
active: module_info.active,
140-
client: module_info.client,
141-
data: module_info.data,
142-
})
126+
Ok(active_modules.into_iter().map(Into::into).collect())
143127
}
144128
}

crates/rspack_plugin_lazy_compilation/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ version.workspace = true
1111
[dependencies]
1212
async-trait = { workspace = true }
1313
rustc-hash = { workspace = true }
14+
serde_json = { workspace = true }
1415
tokio = { workspace = true }
1516
tracing = { workspace = true }
1617

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
use rspack_core::ModuleIdentifier;
1+
use rspack_collections::IdentifierSet;
22
use rspack_error::Result;
33

4-
pub struct ModuleInfo {
5-
pub active: bool,
6-
pub data: String,
7-
pub client: String,
8-
}
9-
104
#[async_trait::async_trait]
115
pub trait Backend: std::fmt::Debug + Send + Sync {
12-
async fn module(&mut self, original_module: ModuleIdentifier, path: String)
13-
-> Result<ModuleInfo>;
6+
async fn current_active_modules(&mut self) -> Result<IdentifierSet>;
147
}

crates/rspack_plugin_lazy_compilation/src/module.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use rspack_core::{
77
BuildMeta, BuildResult, ChunkGraph, CodeGenerationData, CodeGenerationResult, Compilation,
88
ConcatenationScope, Context, DependenciesBlock, DependencyId, DependencyRange, FactoryMeta,
99
LibIdentOptions, Module, ModuleFactoryCreateData, ModuleGraph, ModuleIdentifier, ModuleLayer,
10-
ModuleType, RuntimeGlobals, RuntimeSpec, SourceType, TemplateContext, impl_module_meta_info,
11-
module_namespace_promise, module_update_hash,
10+
ModuleType, RuntimeGlobals, RuntimeSpec, SourceType, TemplateContext, ValueCacheVersions,
11+
impl_module_meta_info, module_namespace_promise, module_update_hash,
1212
rspack_sources::{BoxSource, RawStringSource},
1313
};
1414
use rspack_error::{Result, impl_empty_diagnosable_trait};
@@ -32,8 +32,6 @@ pub(crate) struct LazyCompilationProxyModule {
3232
build_info: BuildInfo,
3333
build_meta: BuildMeta,
3434
factory_meta: Option<FactoryMeta>,
35-
cacheable: bool,
36-
3735
readable_identifier: String,
3836
identifier: ModuleIdentifier,
3937
lib_ident: Option<String>,
@@ -46,11 +44,13 @@ pub(crate) struct LazyCompilationProxyModule {
4644
pub resource: String,
4745

4846
pub active: bool,
49-
pub data: String,
47+
5048
// TODO:
5149
// The client field may be refreshed when rspack restart,
5250
// so this is not safe to cache at the moment
5351
pub client: String,
52+
53+
pub need_build: bool,
5454
}
5555

5656
impl ModuleSourceMapConfig for LazyCompilationProxyModule {
@@ -70,9 +70,7 @@ impl LazyCompilationProxyModule {
7070
lib_ident: Option<String>,
7171
create_data: ModuleFactoryCreateData,
7272
resource: String,
73-
cacheable: bool,
7473
active: bool,
75-
data: String,
7674
client: String,
7775
) -> Self {
7876
let readable_identifier = format!(
@@ -86,7 +84,6 @@ impl LazyCompilationProxyModule {
8684
Self {
8785
build_info: Default::default(),
8886
build_meta: Default::default(),
89-
cacheable,
9087
create_data,
9188
readable_identifier,
9289
lib_ident,
@@ -97,8 +94,8 @@ impl LazyCompilationProxyModule {
9794
blocks: vec![],
9895
dependencies: vec![],
9996
active,
97+
need_build: false,
10098
client,
101-
data,
10299
}
103100
}
104101
}
@@ -138,6 +135,10 @@ impl Module for LazyCompilationProxyModule {
138135
self.lib_ident.as_ref().map(|s| Cow::Borrowed(s.as_str()))
139136
}
140137

138+
fn need_build(&self, _value_cache_versions: &ValueCacheVersions) -> bool {
139+
self.need_build
140+
}
141+
141142
async fn build(
142143
&mut self,
143144
_build_context: BuildContext,
@@ -177,8 +178,6 @@ impl Module for LazyCompilationProxyModule {
177178
self.build_info.file_dependencies = files;
178179
}
179180

180-
self.build_info.cacheable = self.cacheable;
181-
182181
Ok(BuildResult {
183182
dependencies,
184183
blocks,
@@ -208,10 +207,10 @@ impl Module for LazyCompilationProxyModule {
208207
let block = self.blocks.first();
209208

210209
let client = format!(
211-
"var client = __webpack_require__(\"{}\");\nvar data = \"{}\"",
210+
"var client = __webpack_require__(\"{}\");\nvar data = {};",
212211
ChunkGraph::get_module_id(&compilation.module_ids_artifact, *client_module)
213212
.expect("should have module id"),
214-
self.data
213+
serde_json::to_string(&self.identifier).expect("should serialize identifier")
215214
);
216215

217216
let keep_active = format!(
@@ -296,7 +295,7 @@ impl Module for LazyCompilationProxyModule {
296295
let mut hasher = RspackHash::from(&compilation.options.output);
297296
module_update_hash(self, &mut hasher, compilation, runtime);
298297
self.active.dyn_hash(&mut hasher);
299-
self.data.dyn_hash(&mut hasher);
298+
self.identifier.dyn_hash(&mut hasher);
300299
Ok(hasher.digest(&compilation.options.output.hash_digest))
301300
}
302301
}

crates/rspack_plugin_lazy_compilation/src/plugin.rs

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ use std::{
33
sync::{Arc, LazyLock},
44
};
55

6+
use rspack_collections::IdentifierSet;
67
use rspack_core::{
78
BoxModule, Compilation, CompilationId, CompilationParams, CompilerCompilation, CompilerId,
8-
DependencyType, EntryDependency, LibIdentOptions, Module, ModuleFactory, ModuleFactoryCreateData,
9-
NormalModuleCreateData, NormalModuleFactoryModule, Plugin,
9+
CompilerMake, DependencyType, EntryDependency, LibIdentOptions, Module, ModuleFactory,
10+
ModuleFactoryCreateData, NormalModuleCreateData, NormalModuleFactoryModule, Plugin,
1011
};
1112
use rspack_error::Result;
1213
use rspack_hook::{plugin, plugin_hook};
1314
use rspack_regex::RspackRegex;
14-
use tokio::sync::Mutex;
15+
use tokio::sync::{Mutex, RwLock};
1516

1617
use crate::{
1718
backend::Backend, factory::LazyCompilationDependencyFactory, module::LazyCompilationProxyModule,
@@ -63,18 +64,26 @@ pub struct LazyCompilationPlugin<T: Backend, F: LazyCompilationTestCheck> {
6364
entries: bool, // enable for entries
6465
imports: bool, // enable for imports
6566
test: Option<LazyCompilationTest<F>>,
66-
cacheable: bool,
67+
client: String,
68+
active_modules: RwLock<IdentifierSet>,
6769
}
6870

6971
impl<T: Backend, F: LazyCompilationTestCheck> LazyCompilationPlugin<T, F> {
7072
pub fn new(
71-
cacheable: bool,
7273
backend: T,
7374
test: Option<LazyCompilationTest<F>>,
7475
entries: bool,
7576
imports: bool,
77+
client: String,
7678
) -> Self {
77-
Self::new_inner(Mutex::new(backend), entries, imports, test, cacheable)
79+
Self::new_inner(
80+
Mutex::new(backend),
81+
entries,
82+
imports,
83+
test,
84+
client,
85+
Default::default(),
86+
)
7887
}
7988

8089
async fn check_test(
@@ -180,33 +189,53 @@ async fn normal_module_factory_module(
180189
return Ok(());
181190
}
182191

183-
let mut backend = self.backend.lock().await;
184192
let module_identifier = module.identifier();
185193

186194
let lib_ident = module.lib_ident(LibIdentOptions {
187195
context: module_factory_create_data.options.context.as_str(),
188196
});
189-
let info = backend
190-
.module(
191-
module_identifier,
192-
create_data.resource_resolve_data.resource.clone(),
193-
)
194-
.await?;
195197

196198
*module = Box::new(LazyCompilationProxyModule::new(
197199
module_identifier,
198200
lib_ident.map(|ident| ident.into_owned()),
199201
module_factory_create_data.clone(),
200202
create_data.resource_resolve_data.resource.clone(),
201-
self.cacheable,
202-
info.active,
203-
info.data,
204-
info.client,
203+
self
204+
.active_modules
205+
.read()
206+
.await
207+
.contains(&format!("lazy-compilation-proxy|{module_identifier}").into()),
208+
self.client.clone(),
205209
));
206210

207211
Ok(())
208212
}
209213

214+
#[plugin_hook(CompilerMake for LazyCompilationPlugin<T: Backend, F: LazyCompilationTestCheck>)]
215+
async fn compiler_make(&self, compilation: &mut Compilation) -> Result<()> {
216+
let active_modules = self.backend.lock().await.current_active_modules().await?;
217+
let mut module_graph = compilation.get_module_graph_mut();
218+
let mut errors = vec![];
219+
for module_id in &active_modules {
220+
let Some(active_module) = module_graph.module_by_identifier_mut(module_id) else {
221+
errors.push(rspack_error::error!("cannot find module instance for id {module_id}").into());
222+
continue;
223+
};
224+
225+
let Some(active_module) = active_module.downcast_mut::<LazyCompilationProxyModule>() else {
226+
errors.push(rspack_error::error!("cannot find module instance for id {module_id}").into());
227+
continue;
228+
};
229+
230+
active_module.need_build = true;
231+
}
232+
233+
*self.active_modules.write().await = active_modules.into_iter().collect();
234+
235+
compilation.extend_diagnostics(errors);
236+
Ok(())
237+
}
238+
210239
#[async_trait::async_trait]
211240
impl<T: Backend + 'static, F: LazyCompilationTestCheck + 'static> Plugin
212241
for LazyCompilationPlugin<T, F>
@@ -218,6 +247,8 @@ impl<T: Backend + 'static, F: LazyCompilationTestCheck + 'static> Plugin
218247
.normal_module_factory_hooks
219248
.module
220249
.tap(normal_module_factory_module::new(self));
250+
251+
ctx.compiler_hooks.make.tap(compiler_make::new(self));
221252
Ok(())
222253
}
223254
}

packages/rspack-test-tools/tests/hotCases/lazy-compilation/context/__snapshots__/web/1.snap.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- Bundle: modules_module_js_lazy-compilation-proxy.chunk.CURRENT_HASH.js
1111
- Manifest: main.LAST_HASH.hot-update.json, size: 69
1212
- Update: main.LAST_HASH.hot-update.js, size: 582
13-
- Update: modules_demo_js_lazy-compilation-proxy.LAST_HASH.hot-update.js, size: 1412
13+
- Update: modules_demo_js_lazy-compilation-proxy.LAST_HASH.hot-update.js, size: 1436
1414

1515
## Manifest
1616

@@ -79,7 +79,7 @@ self["webpackHotUpdate"]("modules_demo_js_lazy-compilation-proxy", {
7979
\*********************************************************************************************************************/
8080
(function (module, __unused_webpack_exports, __webpack_require__) {
8181
var client = __webpack_require__("../../../../../rspack/hot/lazy-compilation-web.js?http%3A%2F%2Flocalhost%3APORT%2Flazy-compilation-using-");
82-
var data = "<TEST_TOOLS_ROOT>/dist/helper/loaders/hot-update.js??ruleSet[1].rules[0].use[0]!<TEST_TOOLS_ROOT>/tests/hotCases/lazy-compilation/context/modules/demo.js"
82+
var data = "lazy-compilation-proxy|<TEST_TOOLS_ROOT>/dist/helper/loaders/hot-update.js??ruleSet[1].rules[0].use[0]!<TEST_TOOLS_ROOT>/tests/hotCases/lazy-compilation/context/modules/demo.js";
8383
module.exports = __webpack_require__.e(/*! import() */ "modules_demo_js").then(__webpack_require__.bind(__webpack_require__, /*! ./modules/demo.js */ "./modules/demo.js"));
8484
if (module.hot) {
8585
module.hot.accept();

0 commit comments

Comments
 (0)