Skip to content

Commit

Permalink
refactor: finish make and finish modules hook (web-infra-dev#5990)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahabhgk authored Mar 21, 2024
1 parent c9eb712 commit 923e999
Show file tree
Hide file tree
Showing 21 changed files with 439 additions and 336 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,6 @@ export interface JsHooks {
afterOptimizeModules: (compilation: JsCompilation) => void
optimizeTree: () => void
optimizeChunkModules: (compilation: JsCompilation) => void
finishModules: (compilation: JsCompilation) => void
finishMake: (compilation: JsCompilation) => void
afterResolve: (data: AfterResolveData) => Promise<(boolean | void | AfterResolveCreateData)[]>
contextModuleFactoryBeforeResolve: (data: JsBeforeResolveArgs) => Promise<boolean | void>
contextModuleFactoryAfterResolve: (data: AfterResolveData) => Promise<boolean | void>
Expand Down Expand Up @@ -1283,12 +1281,14 @@ export interface RegisterJsTaps {
registerCompilerThisCompilationTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>
registerCompilerCompilationTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>
registerCompilerMakeTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => Promise<void>); stage: number; }>
registerCompilerFinishMakeTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>
registerCompilerShouldEmitTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => boolean | undefined); stage: number; }>
registerCompilationBuildModuleTaps: (stages: Array<number>) => Array<{ function: ((arg: JsModule) => void); stage: number; }>
registerCompilationStillValidModuleTaps: (stages: Array<number>) => Array<{ function: ((arg: JsModule) => void); stage: number; }>
registerCompilationSucceedModuleTaps: (stages: Array<number>) => Array<{ function: ((arg: JsModule) => void); stage: number; }>
registerCompilationExecuteModuleTaps: (stages: Array<number>) => Array<{ function: ((arg: JsExecuteModuleArg) => void); stage: number; }>
registerCompilationRuntimeModuleTaps: (stages: Array<number>) => Array<{ function: ((arg: JsRuntimeModuleArg) => JsRuntimeModule | undefined); stage: number; }>
registerCompilationFinishModulesTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => Promise<void>); stage: number; }>
registerCompilationChunkAssetTaps: (stages: Array<number>) => Array<{ function: ((arg: JsChunkAssetArgs) => void); stage: number; }>
registerCompilationProcessAssetsTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => Promise<void>); stage: number; }>
registerNormalModuleFactoryBeforeResolveTaps: (stages: Array<number>) => Array<{ function: ((arg: JsBeforeResolveArgs) => Promise<[boolean | undefined, JsBeforeResolveArgs]>); stage: number; }>
Expand Down
4 changes: 0 additions & 4 deletions crates/node_binding/src/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ use std::sync::RwLock;
/// rust support hooks
#[derive(PartialEq)]
pub enum Hook {
FinishMake,
AfterProcessAssets,
Emit,
AssetEmitted,
AfterEmit,
OptimizeChunkModules,
FinishModules,
OptimizeModules,
AfterOptimizeModules,
OptimizeTree,
Expand All @@ -23,13 +21,11 @@ pub enum Hook {
impl From<String> for Hook {
fn from(s: String) -> Self {
match s.as_str() {
"finishMake" => Hook::FinishMake,
"afterProcessAssets" => Hook::AfterProcessAssets,
"emit" => Hook::Emit,
"assetEmitted" => Hook::AssetEmitted,
"afterEmit" => Hook::AfterEmit,
"optimizeChunkModules" => Hook::OptimizeChunkModules,
"finishModules" => Hook::FinishModules,
"optimizeModules" => Hook::OptimizeModules,
"afterOptimizeModules" => Hook::AfterOptimizeModules,
"optimizeTree" => Hook::OptimizeTree,
Expand Down
70 changes: 66 additions & 4 deletions crates/node_binding/src/plugins/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ use rspack_binding_values::{
use rspack_core::{
rspack_sources::SourceExt, BeforeResolveArgs, BoxModule, Chunk, ChunkUkey, CodeGenerationResults,
Compilation, CompilationBuildModuleHook, CompilationChunkAssetHook, CompilationExecuteModuleHook,
CompilationParams, CompilationProcessAssetsHook, CompilationRuntimeModuleHook,
CompilationStillValidModuleHook, CompilationSucceedModuleHook, CompilerCompilationHook,
CompilerMakeHook, CompilerShouldEmitHook, CompilerThisCompilationHook, ExecuteModuleId,
MakeParam, ModuleIdentifier, NormalModuleFactoryBeforeResolveHook,
CompilationFinishModulesHook, CompilationParams, CompilationProcessAssetsHook,
CompilationRuntimeModuleHook, CompilationStillValidModuleHook, CompilationSucceedModuleHook,
CompilerCompilationHook, CompilerFinishMakeHook, CompilerMakeHook, CompilerShouldEmitHook,
CompilerThisCompilationHook, ExecuteModuleId, MakeParam, ModuleIdentifier,
NormalModuleFactoryBeforeResolveHook,
};
use rspack_hook::{
AsyncSeries, AsyncSeries2, AsyncSeries3, AsyncSeriesBail, Hook, Interceptor, SyncSeries4,
Expand Down Expand Up @@ -167,6 +168,13 @@ impl<T: 'static + ToNapiValue, R: 'static> RegisterJsTapsInner<T, R> {
}
}

/// define js taps register
/// cache: add cache for register function, used for `before_resolve` or `build_module`
/// which run register function multiple times for every module, cache will ensure
/// it only run once.
/// sync: synchronously/blocking call the register function, most of the register shouldn't
/// be sync since calling a ThreadsafeFunction is async, for now it's only used by
/// execute_module, which strongly required sync call.
macro_rules! define_register {
($name:ident, tap = $tap_name:ident<$arg:ty, $ret:ty> @ $tap_hook:ty, cache = $cache:literal, sync = $sync:tt,) => {
define_register!(@BASE $name, $tap_name<$arg, $ret> @ $tap_hook, $cache, $sync);
Expand Down Expand Up @@ -249,6 +257,10 @@ pub struct RegisterJsTaps {
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => Promise<void>); stage: number; }>"
)]
pub register_compiler_make_taps: RegisterFunction<JsCompilation, Promise<()>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => void); stage: number; }>"
)]
pub register_compiler_finish_make_taps: RegisterFunction<JsCompilation, Promise<()>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => boolean | undefined); stage: number; }>"
)]
Expand All @@ -274,6 +286,10 @@ pub struct RegisterJsTaps {
)]
pub register_compilation_runtime_module_taps:
RegisterFunction<JsRuntimeModuleArg, Option<JsRuntimeModule>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsCompilation) => Promise<void>); stage: number; }>"
)]
pub register_compilation_finish_modules_taps: RegisterFunction<JsCompilation, Promise<()>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsChunkAssetArgs) => void); stage: number; }>"
)]
Expand Down Expand Up @@ -308,6 +324,12 @@ define_register!(
cache = false,
sync = false,
);
define_register!(
RegisterCompilerFinishMakeTaps,
tap = CompilerFinishMakeTap<JsCompilation, Promise<()>> @ CompilerFinishMakeHook,
cache = false,
sync = false,
);
define_register!(
RegisterCompilerShouldEmitTaps,
tap = CompilerShouldEmitTap<JsCompilation, Option<bool>> @ CompilerShouldEmitHook,
Expand Down Expand Up @@ -340,6 +362,12 @@ define_register!(
cache = false,
sync = true,
);
define_register!(
RegisterCompilationFinishModulesTaps,
tap = CompilationFinishModulesTap<JsCompilation, Promise<()>> @ CompilationFinishModulesHook,
cache = false,
sync = false,
);
define_register!(
RegisterCompilationRuntimeModuleTaps,
tap = CompilationRuntimeModuleTap<JsRuntimeModuleArg, Option<JsRuntimeModule>> @ CompilationRuntimeModuleHook,
Expand Down Expand Up @@ -428,6 +456,23 @@ impl AsyncSeries2<Compilation, Vec<MakeParam>> for CompilerMakeTap {
}
}

#[async_trait]
impl AsyncSeries<Compilation> for CompilerFinishMakeTap {
async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> {
// SAFETY:
// 1. `Compiler` is stored on the heap and pinned in binding crate.
// 2. `Compilation` outlives `JsCompilation` and `Compiler` outlives `Compilation`.
// 3. `JsCompilation` was replaced everytime a new `Compilation` was created before getting accessed.
let compilation = unsafe { JsCompilation::from_compilation(compilation) };

self.function.call_with_promise(compilation).await
}

fn stage(&self) -> i32 {
self.stage
}
}

#[async_trait]
impl AsyncSeriesBail<Compilation, bool> for CompilerShouldEmitTap {
async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<Option<bool>> {
Expand Down Expand Up @@ -511,6 +556,23 @@ impl SyncSeries4<ModuleIdentifier, IdentifierSet, CodeGenerationResults, Execute
}
}

#[async_trait]
impl AsyncSeries<Compilation> for CompilationFinishModulesTap {
async fn run(&self, compilation: &mut Compilation) -> rspack_error::Result<()> {
// SAFETY:
// 1. `Compiler` is stored on the heap and pinned in binding crate.
// 2. `Compilation` outlives `JsCompilation` and `Compiler` outlives `Compilation`.
// 3. `JsCompilation` was replaced everytime a new `Compilation` was created before getting accessed.
let compilation = unsafe { JsCompilation::from_compilation(compilation) };

self.function.call_with_promise(compilation).await
}

fn stage(&self) -> i32 {
self.stage
}
}

#[async_trait]
impl AsyncSeries3<Compilation, ModuleIdentifier, ChunkUkey> for CompilationRuntimeModuleTap {
async fn run(
Expand Down
54 changes: 20 additions & 34 deletions crates/node_binding/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ use rspack_hook::Hook as _;

use self::interceptor::RegisterCompilationBuildModuleTaps;
use self::interceptor::RegisterCompilationChunkAssetTaps;
use self::interceptor::RegisterCompilationFinishModulesTaps;
use self::interceptor::RegisterCompilationStillValidModuleTaps;
use self::interceptor::RegisterCompilationSucceedModuleTaps;
use self::interceptor::RegisterCompilerFinishMakeTaps;
use self::interceptor::{
RegisterCompilationExecuteModuleTaps, RegisterCompilationProcessAssetsTaps,
RegisterCompilationRuntimeModuleTaps, RegisterCompilerCompilationTaps, RegisterCompilerMakeTaps,
Expand All @@ -43,11 +45,13 @@ pub struct JsHooksAdapterPlugin {
register_compiler_this_compilation_taps: RegisterCompilerThisCompilationTaps,
register_compiler_compilation_taps: RegisterCompilerCompilationTaps,
register_compiler_make_taps: RegisterCompilerMakeTaps,
register_compiler_finish_make_taps: RegisterCompilerFinishMakeTaps,
register_compiler_should_emit_taps: RegisterCompilerShouldEmitTaps,
register_compilation_build_module_taps: RegisterCompilationBuildModuleTaps,
register_compilation_still_valid_module_taps: RegisterCompilationStillValidModuleTaps,
register_compilation_succeed_module_taps: RegisterCompilationSucceedModuleTaps,
register_compilation_execute_module_taps: RegisterCompilationExecuteModuleTaps,
register_compilation_finish_modules_taps: RegisterCompilationFinishModulesTaps,
register_compilation_runtime_module_taps: RegisterCompilationRuntimeModuleTaps,
register_compilation_chunk_asset_taps: RegisterCompilationChunkAssetTaps,
register_compilation_process_assets_taps: RegisterCompilationProcessAssetsTaps,
Expand Down Expand Up @@ -96,6 +100,11 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
.compiler_hooks
.make
.intercept(self.register_compiler_make_taps.clone());
ctx
.context
.compiler_hooks
.finish_make
.intercept(self.register_compiler_finish_make_taps.clone());
ctx
.context
.compiler_hooks
Expand All @@ -121,6 +130,11 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
.compilation_hooks
.execute_module
.intercept(self.register_compilation_execute_module_taps.clone());
ctx
.context
.compilation_hooks
.finish_modules
.intercept(self.register_compilation_finish_modules_taps.clone());
ctx
.context
.compilation_hooks
Expand Down Expand Up @@ -330,40 +344,6 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
self.hooks.optimize_chunk_modules.call(compilation).await
}

async fn finish_make(
&self,
compilation: &mut rspack_core::Compilation,
) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::FinishMake) {
return Ok(());
}

// SAFETY:
// 1. `Compiler` is stored on the heap and pinned in binding crate.
// 2. `Compilation` outlives `JsCompilation` and `Compiler` outlives `Compilation`.
// 3. `JsCompilation` was replaced everytime a new `Compilation` was created before getting accessed.
let compilation = unsafe { JsCompilation::from_compilation(compilation) };

self.hooks.finish_make.call(compilation).await
}

async fn finish_modules(
&self,
compilation: &mut rspack_core::Compilation,
) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::FinishModules) {
return Ok(());
}

// SAFETY:
// 1. `Compiler` is stored on the heap and pinned in binding crate.
// 2. `Compilation` outlives `JsCompilation` and `Compiler` outlives `Compilation`.
// 3. `JsCompilation` was replaced everytime a new `Compilation` was created before getting accessed.
let compilation = unsafe { JsCompilation::from_compilation(compilation) };

self.hooks.finish_modules.call(compilation).await
}

async fn emit(&self, _: &mut rspack_core::Compilation) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::Emit) {
return Ok(());
Expand Down Expand Up @@ -407,6 +387,9 @@ impl JsHooksAdapterPlugin {
register_compiler_make_taps: RegisterCompilerMakeTaps::new(
register_js_taps.register_compiler_make_taps,
),
register_compiler_finish_make_taps: RegisterCompilerFinishMakeTaps::new(
register_js_taps.register_compiler_finish_make_taps,
),
register_compiler_should_emit_taps: RegisterCompilerShouldEmitTaps::new(
register_js_taps.register_compiler_should_emit_taps,
),
Expand All @@ -422,6 +405,9 @@ impl JsHooksAdapterPlugin {
register_compilation_execute_module_taps: RegisterCompilationExecuteModuleTaps::new(
register_js_taps.register_compilation_execute_module_taps,
),
register_compilation_finish_modules_taps: RegisterCompilationFinishModulesTaps::new(
register_js_taps.register_compilation_finish_modules_taps,
),
register_compilation_runtime_module_taps: RegisterCompilationRuntimeModuleTaps::new(
register_js_taps.register_compilation_runtime_module_taps,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,9 @@ impl BuiltinPlugin {
BuiltinPluginName::FileUriPlugin => plugins.push(FileUriPlugin.boxed()),
BuiltinPluginName::RuntimePlugin => plugins.push(RuntimePlugin.boxed()),
BuiltinPluginName::JsonModulesPlugin => plugins.push(JsonPlugin.boxed()),
BuiltinPluginName::InferAsyncModulesPlugin => plugins.push(InferAsyncModulesPlugin.boxed()),
BuiltinPluginName::InferAsyncModulesPlugin => {
plugins.push(InferAsyncModulesPlugin::default().boxed())
}
BuiltinPluginName::JavascriptModulesPlugin => plugins.push(JsPlugin::default().boxed()),
BuiltinPluginName::AsyncWebAssemblyModulesPlugin => {
plugins.push(AsyncWasmPlugin::default().boxed())
Expand Down
4 changes: 0 additions & 4 deletions crates/rspack_binding_values/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ pub struct JsHooks {
pub optimize_tree: ThreadsafeFunction<(), ()>,
#[napi(ts_type = "(compilation: JsCompilation) => void")]
pub optimize_chunk_modules: ThreadsafeFunction<JsCompilation, ()>,
#[napi(ts_type = "(compilation: JsCompilation) => void")]
pub finish_modules: ThreadsafeFunction<JsCompilation, ()>,
#[napi(ts_type = "(compilation: JsCompilation) => void")]
pub finish_make: ThreadsafeFunction<JsCompilation, ()>,
#[napi(
ts_type = "(data: AfterResolveData) => Promise<(boolean | void | AfterResolveCreateData)[]>"
)]
Expand Down
8 changes: 7 additions & 1 deletion crates/rspack_core/src/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub type CompilationStillValidModuleHook = AsyncSeriesHook<BoxModule>;
pub type CompilationSucceedModuleHook = AsyncSeriesHook<BoxModule>;
pub type CompilationExecuteModuleHook =
SyncSeries4Hook<ModuleIdentifier, IdentifierSet, CodeGenerationResults, ExecuteModuleId>;
pub type CompilationFinishModulesHook = AsyncSeriesHook<Compilation>;
pub type CompilationRuntimeModuleHook = AsyncSeries3Hook<Compilation, ModuleIdentifier, ChunkUkey>;
pub type CompilationChunkAssetHook = AsyncSeries2Hook<Chunk, String>;
pub type CompilationProcessAssetsHook = AsyncSeriesHook<Compilation>;
Expand All @@ -61,6 +62,7 @@ pub struct CompilationHooks {
pub still_valid_module: CompilationStillValidModuleHook,
pub succeed_module: CompilationSucceedModuleHook,
pub execute_module: CompilationExecuteModuleHook,
pub finish_modules: CompilationFinishModulesHook,
pub runtime_module: CompilationRuntimeModuleHook,
pub chunk_asset: CompilationChunkAssetHook,
pub process_assets: CompilationProcessAssetsHook,
Expand Down Expand Up @@ -809,7 +811,11 @@ impl Compilation {
pub async fn finish(&mut self, plugin_driver: SharedPluginDriver) -> Result<()> {
let logger = self.get_logger("rspack.Compilation");
let start = logger.time("finish modules");
plugin_driver.finish_modules(self).await?;
plugin_driver
.compilation_hooks
.finish_modules
.call(self)
.await?;
logger.time_end(start);

Ok(())
Expand Down
8 changes: 6 additions & 2 deletions crates/rspack_core/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::sync::Arc;
use rspack_error::Result;
use rspack_fs::AsyncWritableFileSystem;
use rspack_futures::FuturesResults;
use rspack_hook::{AsyncSeries2Hook, AsyncSeriesBailHook};
use rspack_hook::{AsyncSeries2Hook, AsyncSeriesBailHook, AsyncSeriesHook};
use rspack_identifier::{IdentifierMap, IdentifierSet};
use rustc_hash::FxHashMap as HashMap;
use swc_core::ecma::atoms::Atom;
Expand Down Expand Up @@ -41,6 +41,7 @@ pub type CompilerThisCompilationHook = AsyncSeries2Hook<Compilation, Compilation
pub type CompilerCompilationHook = AsyncSeries2Hook<Compilation, CompilationParams>;
// should be AsyncParallelHook, but rspack need add MakeParam to incremental rebuild
pub type CompilerMakeHook = AsyncSeries2Hook<Compilation, Vec<MakeParam>>;
pub type CompilerFinishMakeHook = AsyncSeriesHook<Compilation>;
// should be SyncBailHook, but rspack need call js hook
pub type CompilerShouldEmitHook = AsyncSeriesBailHook<Compilation, bool>;

Expand All @@ -49,6 +50,7 @@ pub struct CompilerHooks {
pub this_compilation: CompilerThisCompilationHook,
pub compilation: CompilerCompilationHook,
pub make: CompilerMakeHook,
pub finish_make: CompilerFinishMakeHook,
pub should_emit: CompilerShouldEmitHook,
}

Expand Down Expand Up @@ -181,7 +183,9 @@ where
let start = logger.time("finish make hook");
self
.plugin_driver
.finish_make(&mut self.compilation)
.compiler_hooks
.finish_make
.call(&mut self.compilation)
.await?;
logger.time_end(start);

Expand Down
8 changes: 0 additions & 8 deletions crates/rspack_core/src/plugin/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,6 @@ pub trait Plugin: Debug + Send + Sync {
Ok(())
}

async fn finish_make(&self, _compilation: &mut Compilation) -> Result<()> {
Ok(())
}

async fn finish_modules(&self, _modules: &mut Compilation) -> Result<()> {
Ok(())
}

/// Webpack resolves loaders in `NormalModuleFactory`,
/// Rspack resolves it when normalizing configuration.
/// So this hook is used to resolve inline loader (inline loader requests).
Expand Down
Loading

0 comments on commit 923e999

Please sign in to comment.