Skip to content

Commit

Permalink
refactor: this compilation hook (#5960)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahabhgk committed Mar 18, 2024
1 parent 74dbde2 commit 7f10666
Show file tree
Hide file tree
Showing 18 changed files with 282 additions and 268 deletions.
2 changes: 1 addition & 1 deletion crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ export interface JsExecuteModuleResult {
}

export interface JsHooks {
thisCompilation: (compilation: JsCompilation) => void
afterProcessAssets: () => void
emit: () => void
assetEmitted: (asset: JsAssetEmittedArgs) => void
Expand Down Expand Up @@ -1283,6 +1282,7 @@ export interface RawTrustedTypes {
export function registerGlobalTrace(filter: string, layer: "chrome" | "logger", output: string): void

export interface RegisterJsTaps {
registerCompilerThisCompilationTaps: (stages: Array<number>) => Array<{ function: ((compilation: JsCompilation) => void); stage: number; }>
registerCompilerCompilationTaps: (stages: Array<number>) => Array<{ function: ((compilation: JsCompilation) => void); stage: number; }>
registerCompilerMakeTaps: (stages: Array<number>) => Array<{ function: ((compilation: JsCompilation) => Promise<void>); stage: number; }>
registerCompilerShouldEmitTaps: (stages: Array<number>) => Array<{ function: ((compilation: JsCompilation) => boolean | undefined); stage: number; }>
Expand Down
2 changes: 0 additions & 2 deletions crates/node_binding/src/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::sync::RwLock;
pub enum Hook {
FinishMake,
BuildModule,
ThisCompilation,
AfterProcessAssets,
Emit,
AssetEmitted,
Expand Down Expand Up @@ -33,7 +32,6 @@ impl From<String> for Hook {
match s.as_str() {
"finishMake" => Hook::FinishMake,
"buildModule" => Hook::BuildModule,
"thisCompilation" => Hook::ThisCompilation,
"afterProcessAssets" => Hook::AfterProcessAssets,
"emit" => Hook::Emit,
"assetEmitted" => Hook::AssetEmitted,
Expand Down
36 changes: 34 additions & 2 deletions crates/node_binding/src/plugins/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use napi::{
use rspack_binding_values::{JsBeforeResolveArgs, JsBeforeResolveOutput, JsCompilation};
use rspack_core::{
BeforeResolveArgs, Compilation, CompilationParams, CompilationProcessAssetsHook,
CompilerCompilationHook, CompilerMakeHook, CompilerShouldEmitHook, MakeParam,
NormalModuleFactoryBeforeResolveHook,
CompilerCompilationHook, CompilerMakeHook, CompilerShouldEmitHook, CompilerThisCompilationHook,
MakeParam, NormalModuleFactoryBeforeResolveHook,
};
use rspack_hook::{AsyncSeries, AsyncSeries2, AsyncSeriesBail, Hook, Interceptor};
use rspack_napi::threadsafe_function::ThreadsafeFunction;
Expand Down Expand Up @@ -180,6 +180,10 @@ macro_rules! define_register {
#[derive(Clone)]
#[napi(object, object_to_js = false)]
pub struct RegisterJsTaps {
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((compilation: JsCompilation) => void); stage: number; }>"
)]
pub register_compiler_this_compilation_taps: RegisterFunction<JsCompilation, ()>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((compilation: JsCompilation) => void); stage: number; }>"
)]
Expand All @@ -203,6 +207,12 @@ pub struct RegisterJsTaps {
RegisterFunction<JsBeforeResolveArgs, Promise<JsBeforeResolveOutput>>,
}

/* Compiler Hooks */
define_register!(
RegisterCompilerThisCompilationTaps,
tap = CompilerThisCompilationTap<JsCompilation, ()> @ CompilerThisCompilationHook,
cache = false,
);
define_register!(
RegisterCompilerCompilationTaps,
tap = CompilerCompilationTap<JsCompilation, ()> @ CompilerCompilationHook,
Expand All @@ -219,18 +229,40 @@ define_register!(
cache = false,
);

/* Compilation Hooks */
define_register!(
RegisterCompilationProcessAssetsTaps,
tap = CompilationProcessAssetsTap<JsCompilation, Promise<()>> @ CompilationProcessAssetsHook,
cache = false,
);

/* NormalModuleFactory Hooks */
define_register!(
RegisterNormalModuleFactoryBeforeResolveTaps,
tap = NormalModuleFactoryBeforeResolveTap<JsBeforeResolveArgs, Promise<JsBeforeResolveOutput>> @ NormalModuleFactoryBeforeResolveHook,
cache = true,
);

#[async_trait]
impl AsyncSeries2<Compilation, CompilationParams> for CompilerThisCompilationTap {
async fn run(
&self,
compilation: &mut Compilation,
_: &mut CompilationParams,
) -> rspack_error::Result<()> {
// SAFETY: `Compiler` will not be moved, as it's stored on the heap.
// The pointer to `Compilation` is valid for the lifetime of `Compiler`.
// `Compiler` is valid through the lifetime before it's closed by calling `Compiler.close()` or gc-ed.
// `JsCompilation` is valid through the entire lifetime of `Compilation`.
let compilation = unsafe { JsCompilation::from_compilation(compilation) };
self.function.call_with_sync(compilation).await
}

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

#[async_trait]
impl AsyncSeries2<Compilation, CompilationParams> for CompilerCompilationTap {
async fn run(
Expand Down
30 changes: 11 additions & 19 deletions crates/node_binding/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use rspack_hook::Hook as _;

use self::interceptor::{
RegisterCompilationProcessAssetsTaps, RegisterCompilerCompilationTaps, RegisterCompilerMakeTaps,
RegisterCompilerShouldEmitTaps, RegisterNormalModuleFactoryBeforeResolveTaps,
RegisterCompilerShouldEmitTaps, RegisterCompilerThisCompilationTaps,
RegisterNormalModuleFactoryBeforeResolveTaps,
};
use crate::{DisabledHooks, Hook, JsCompilation, JsHooks};

Expand All @@ -39,6 +40,7 @@ pub struct JsHooksAdapterInner {
#[derive(Clone)]
pub struct JsHooksAdapterPlugin {
inner: Arc<JsHooksAdapterInner>,
register_compiler_this_compilation_taps: RegisterCompilerThisCompilationTaps,
register_compiler_compilation_taps: RegisterCompilerCompilationTaps,
register_compiler_make_taps: RegisterCompilerMakeTaps,
register_compiler_should_emit_taps: RegisterCompilerShouldEmitTaps,
Expand Down Expand Up @@ -73,6 +75,11 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
ctx: PluginContext<&mut ApplyContext>,
_options: &mut CompilerOptions,
) -> rspack_error::Result<()> {
ctx
.context
.compiler_hooks
.this_compilation
.intercept(self.register_compiler_this_compilation_taps.clone());
ctx
.context
.compiler_hooks
Expand Down Expand Up @@ -105,24 +112,6 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
Ok(())
}

async fn this_compilation(
&self,
args: rspack_core::ThisCompilationArgs<'_>,
_params: &rspack_core::CompilationParams,
) -> rspack_core::PluginThisCompilationHookOutput {
if self.is_hook_disabled(&Hook::ThisCompilation) {
return Ok(());
}

// SAFETY: `Compiler` will not be moved, as it's stored on the heap.
// The pointer to `Compilation` is valid for the lifetime of `Compiler`.
// `Compiler` is valid through the lifetime before it's closed by calling `Compiler.close()` or gc-ed.
// `JsCompilation` is valid through the entire lifetime of `Compilation`.
let compilation = unsafe { JsCompilation::from_compilation(args.this_compilation) };

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

async fn chunk_asset(&self, args: &ChunkAssetArgs) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::ChunkAsset) {
return Ok(());
Expand Down Expand Up @@ -489,6 +478,9 @@ impl JsHooksAdapterPlugin {
register_js_taps: RegisterJsTaps,
) -> Result<Self> {
Ok(JsHooksAdapterPlugin {
register_compiler_this_compilation_taps: RegisterCompilerThisCompilationTaps::new(
register_js_taps.register_compiler_this_compilation_taps,
),
register_compiler_compilation_taps: RegisterCompilerCompilationTaps::new(
register_js_taps.register_compiler_compilation_taps,
),
Expand Down
2 changes: 0 additions & 2 deletions crates/rspack_binding_values/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use crate::{

#[napi(object, object_to_js = false)]
pub struct JsHooks {
#[napi(ts_type = "(compilation: JsCompilation) => void")]
pub this_compilation: ThreadsafeFunction<JsCompilation, ()>,
#[napi(ts_type = "() => void")]
pub after_process_assets: ThreadsafeFunction<(), ()>,
#[napi(ts_type = "() => void")]
Expand Down
7 changes: 6 additions & 1 deletion crates/rspack_core/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ use crate::{
use crate::{BoxPlugin, ExportInfo, UsageState};
use crate::{CompilationParams, ContextModuleFactory, NormalModuleFactory};

// should be SyncHook, but rspack need call js hook
pub type CompilerThisCompilationHook = AsyncSeries2Hook<Compilation, CompilationParams>;
// should be SyncHook, but rspack need call js hook
pub type CompilerCompilationHook = AsyncSeries2Hook<Compilation, CompilationParams>;
// should be AsyncParallelHook, but rspack need add MakeParam to incremental rebuild
Expand All @@ -43,6 +45,7 @@ pub type CompilerShouldEmitHook = AsyncSeriesBailHook<Compilation, bool>;

#[derive(Debug, Default)]
pub struct CompilerHooks {
pub this_compilation: CompilerThisCompilationHook,
pub compilation: CompilerCompilationHook,
pub make: CompilerMakeHook,
pub should_emit: CompilerShouldEmitHook,
Expand Down Expand Up @@ -141,7 +144,9 @@ where
// Fake this compilation as *currently* rebuilding does not create a new compilation
self
.plugin_driver
.this_compilation(&mut self.compilation, &compilation_params)
.compiler_hooks
.this_compilation
.call(&mut self.compilation, &mut compilation_params)
.await?;
self
.plugin_driver
Expand Down
19 changes: 4 additions & 15 deletions crates/rspack_core/src/plugin/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ use tokio::sync::mpsc::UnboundedSender;
use crate::{
AdditionalChunkRuntimeRequirementsArgs, AdditionalModuleRequirementsArgs, AssetEmittedArgs,
AssetInfo, BoxLoader, BoxModule, BuildTimeExecutionOption, Chunk, ChunkAssetArgs, ChunkHashArgs,
CodeGenerationResults, Compilation, CompilationHooks, CompilationParams, CompilerHooks,
CompilerOptions, ContentHashArgs, DependencyId, DoneArgs, FactorizeArgs, JsChunkHashArgs,
LoaderRunnerContext, Module, ModuleFactoryResult, ModuleIdentifier, ModuleType, NormalModule,
CodeGenerationResults, Compilation, CompilationHooks, CompilerHooks, CompilerOptions,
ContentHashArgs, DependencyId, DoneArgs, FactorizeArgs, JsChunkHashArgs, LoaderRunnerContext,
Module, ModuleFactoryResult, ModuleIdentifier, ModuleType, NormalModule,
NormalModuleAfterResolveArgs, NormalModuleCreateData, NormalModuleFactoryHooks,
OptimizeChunksArgs, ParserAndGenerator, PluginContext, ProcessAssetsArgs, RenderArgs,
RenderChunkArgs, RenderManifestArgs, RenderModuleContentArgs, RenderStartupArgs, Resolver,
RuntimeModule, RuntimeRequirementsInTreeArgs, SourceType, ThisCompilationArgs,
RuntimeModule, RuntimeRequirementsInTreeArgs, SourceType,
};

#[derive(Debug, Clone)]
Expand All @@ -26,8 +26,6 @@ pub struct BeforeResolveArgs {
}

pub type PluginCompilationHookOutput = Result<()>;
pub type PluginThisCompilationHookOutput = Result<()>;
pub type PluginMakeHookOutput = Result<()>;
pub type PluginBuildEndHookOutput = Result<()>;
pub type PluginProcessAssetsHookOutput = Result<()>;
pub type PluginReadResourceOutput = Result<Option<Content>>;
Expand All @@ -50,7 +48,6 @@ pub type PluginRenderModuleContentOutput<'a> = Result<RenderModuleContentArgs<'a
pub type PluginRenderStartupHookOutput = Result<Option<BoxSource>>;
pub type PluginRenderHookOutput = Result<Option<BoxSource>>;
pub type PluginJsChunkHashHookOutput = Result<()>;
pub type PluginShouldEmitHookOutput = Result<Option<bool>>;

#[async_trait::async_trait]
pub trait Plugin: Debug + Send + Sync {
Expand All @@ -66,14 +63,6 @@ pub trait Plugin: Debug + Send + Sync {
Ok(())
}

async fn this_compilation(
&self,
_args: ThisCompilationArgs<'_>,
_params: &CompilationParams,
) -> PluginThisCompilationHookOutput {
Ok(())
}

async fn done<'s, 'c>(
&self,
_ctx: PluginContext,
Expand Down
5 changes: 0 additions & 5 deletions crates/rspack_core/src/plugin/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,6 @@ pub struct DoneArgs<'s, 'c: 's> {
pub stats: &'s mut Stats<'c>,
}

#[derive(Debug)]
pub struct ThisCompilationArgs<'c> {
pub this_compilation: &'c mut Compilation,
}

#[derive(Debug)]
pub struct AdditionalChunkRuntimeRequirementsArgs<'a> {
pub compilation: &'a mut Compilation,
Expand Down
50 changes: 14 additions & 36 deletions crates/rspack_core/src/plugin/plugin_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,20 @@ use crate::{
AdditionalChunkRuntimeRequirementsArgs, AdditionalModuleRequirementsArgs, ApplyContext,
AssetEmittedArgs, BeforeResolveArgs, BoxLoader, BoxModule, BoxedParserAndGeneratorBuilder,
BuildTimeExecutionOption, Chunk, ChunkAssetArgs, ChunkContentHash, ChunkHashArgs,
CodeGenerationResults, Compilation, CompilationHooks, CompilationParams, CompilerHooks,
CompilerOptions, Content, ContentHashArgs, DependencyId, DoneArgs, FactorizeArgs,
JsChunkHashArgs, LoaderRunnerContext, Module, ModuleIdentifier, ModuleType, NormalModule,
NormalModuleAfterResolveArgs, NormalModuleCreateData, NormalModuleFactoryHooks,
OptimizeChunksArgs, Plugin, PluginAdditionalChunkRuntimeRequirementsOutput,
PluginAdditionalModuleRequirementsOutput, PluginBuildEndHookOutput, PluginChunkHashHookOutput,
PluginCompilationHookOutput, PluginContext, PluginFactorizeHookOutput,
PluginJsChunkHashHookOutput, PluginNormalModuleFactoryAfterResolveOutput,
PluginNormalModuleFactoryBeforeResolveOutput, PluginNormalModuleFactoryCreateModuleHookOutput,
PluginNormalModuleFactoryModuleHookOutput, PluginRenderChunkHookOutput, PluginRenderHookOutput,
PluginRenderManifestHookOutput, PluginRenderModuleContentOutput, PluginRenderStartupHookOutput,
PluginRuntimeRequirementsInTreeOutput, PluginThisCompilationHookOutput, ProcessAssetsArgs,
RenderArgs, RenderChunkArgs, RenderManifestArgs, RenderModuleContentArgs, RenderStartupArgs,
Resolver, ResolverFactory, RuntimeModule, RuntimeRequirementsInTreeArgs, Stats,
ThisCompilationArgs,
CodeGenerationResults, Compilation, CompilationHooks, CompilerHooks, CompilerOptions, Content,
ContentHashArgs, DependencyId, DoneArgs, FactorizeArgs, JsChunkHashArgs, LoaderRunnerContext,
Module, ModuleIdentifier, ModuleType, NormalModule, NormalModuleAfterResolveArgs,
NormalModuleCreateData, NormalModuleFactoryHooks, OptimizeChunksArgs, Plugin,
PluginAdditionalChunkRuntimeRequirementsOutput, PluginAdditionalModuleRequirementsOutput,
PluginBuildEndHookOutput, PluginChunkHashHookOutput, PluginCompilationHookOutput, PluginContext,
PluginFactorizeHookOutput, PluginJsChunkHashHookOutput,
PluginNormalModuleFactoryAfterResolveOutput, PluginNormalModuleFactoryBeforeResolveOutput,
PluginNormalModuleFactoryCreateModuleHookOutput, PluginNormalModuleFactoryModuleHookOutput,
PluginRenderChunkHookOutput, PluginRenderHookOutput, PluginRenderManifestHookOutput,
PluginRenderModuleContentOutput, PluginRenderStartupHookOutput,
PluginRuntimeRequirementsInTreeOutput, ProcessAssetsArgs, RenderArgs, RenderChunkArgs,
RenderManifestArgs, RenderModuleContentArgs, RenderStartupArgs, Resolver, ResolverFactory,
RuntimeModule, RuntimeRequirementsInTreeArgs, Stats,
};

pub struct PluginDriver {
Expand Down Expand Up @@ -149,27 +148,6 @@ impl PluginDriver {

Ok(())
}
/// Executed while initializing the compilation, right before emitting the compilation event. This hook is not copied to child compilers.
///
/// See: https://webpack.js.org/api/compiler-hooks/#thiscompilation
pub async fn this_compilation(
&self,
compilation: &mut Compilation,
params: &CompilationParams,
) -> PluginThisCompilationHookOutput {
for plugin in &self.plugins {
plugin
.this_compilation(
ThisCompilationArgs {
this_compilation: compilation,
},
params,
)
.await?;
}

Ok(())
}

pub async fn content_hash(&self, args: &ContentHashArgs<'_>) -> Result<ChunkContentHash> {
let mut result = HashMap::default();
Expand Down
Loading

2 comments on commit 7f10666

@rspack-bot
Copy link

Choose a reason for hiding this comment

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

📝 Ran ecosystem CI: Open

suite result
modernjs, self-hosted, Linux, ci, ec2-linux ✅ success
_selftest, ubuntu-latest ✅ success
nx, ubuntu-latest ✅ success
rspress, ubuntu-latest ✅ success
rsbuild, ubuntu-latest ✅ success
compat, ubuntu-latest ✅ success
examples, ubuntu-latest ✅ success

@rspack-bot
Copy link

Choose a reason for hiding this comment

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

📝 Benchmark detail: Open

Name Base (2024-03-18 db37a1b) Current Change
10000_development-mode + exec 1.97 s ± 17 ms 1.91 s ± 20 ms -3.05 %
10000_development-mode_hmr + exec 732 ms ± 2.1 ms 737 ms ± 10 ms +0.66 %
10000_production-mode + exec 2.91 s ± 21 ms 2.92 s ± 48 ms +0.45 %
arco-pro_development-mode + exec 2.51 s ± 38 ms 2.49 s ± 28 ms -0.71 %
arco-pro_development-mode_hmr + exec 513 ms ± 3 ms 513 ms ± 4.4 ms +0.04 %
arco-pro_development-mode_hmr_intercept-plugin + exec 530 ms ± 2.4 ms 529 ms ± 6.8 ms -0.04 %
arco-pro_development-mode_intercept-plugin + exec 3.36 s ± 34 ms 3.34 s ± 27 ms -0.60 %
arco-pro_production-mode + exec 4.1 s ± 24 ms 4.18 s ± 27 ms +2.02 %
arco-pro_production-mode_intercept-plugin + exec 4.92 s ± 23 ms 5.02 s ± 63 ms +2.07 %
threejs_development-mode_10x + exec 1.89 s ± 22 ms 1.9 s ± 29 ms +0.80 %
threejs_development-mode_10x_hmr + exec 731 ms ± 6.3 ms 735 ms ± 5.3 ms +0.51 %
threejs_production-mode_10x + exec 5.86 s ± 80 ms 5.83 s ± 109 ms -0.66 %

Please sign in to comment.