Skip to content

Commit

Permalink
feat: add runtime plugin hooks (#9084)
Browse files Browse the repository at this point in the history
* feat: add runtime plugin hooks

* feat: add runtime plugin hooks

* feat: add runtime plugin hooks

* feat: add runtime plugin hooks
  • Loading branch information
LingyuCoder authored Jan 23, 2025
1 parent fedb661 commit 7075fd2
Show file tree
Hide file tree
Showing 53 changed files with 1,115 additions and 283 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/node_binding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rspack_napi = { workspace = true }
rspack_paths = { workspace = true }
rspack_plugin_html = { workspace = true }
rspack_plugin_javascript = { workspace = true }
rspack_plugin_runtime = { workspace = true }
rspack_util = { workspace = true }

rspack_tracing = { workspace = true }
Expand Down
23 changes: 22 additions & 1 deletion crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,11 @@ export interface JsCreateData {
resource: string
}

export interface JsCreateScriptData {
code: string
chunk: JsChunk
}

export interface JsDefaultObjectRedirectWarnObject {
ignore: boolean
}
Expand Down Expand Up @@ -719,6 +724,16 @@ export interface JsLibraryOptions {
amdContainer?: string
}

export interface JsLinkPrefetchData {
code: string
chunk: JsChunk
}

export interface JsLinkPreloadData {
code: string
chunk: JsChunk
}

export interface JsLoaderContext {
resourceData: Readonly<JsResourceData>
/** Will be deprecated. Use module.module_identifier instead */
Expand Down Expand Up @@ -2117,7 +2132,10 @@ export declare enum RegisterJsTapKind {
HtmlPluginAlterAssetTagGroups = 37,
HtmlPluginAfterTemplateExecution = 38,
HtmlPluginBeforeEmit = 39,
HtmlPluginAfterEmit = 40
HtmlPluginAfterEmit = 40,
RuntimePluginCreateScript = 41,
RuntimePluginLinkPreload = 42,
RuntimePluginLinkPrefetch = 43
}

export interface RegisterJsTaps {
Expand Down Expand Up @@ -2162,6 +2180,9 @@ export interface RegisterJsTaps {
registerHtmlPluginAfterTemplateExecutionTaps: (stages: Array<number>) => Array<{ function: ((arg: JsAfterTemplateExecutionData) => JsAfterTemplateExecutionData); stage: number; }>
registerHtmlPluginBeforeEmitTaps: (stages: Array<number>) => Array<{ function: ((arg: JsBeforeEmitData) => JsBeforeEmitData); stage: number; }>
registerHtmlPluginAfterEmitTaps: (stages: Array<number>) => Array<{ function: ((arg: JsAfterEmitData) => JsAfterEmitData); stage: number; }>
registerRuntimePluginCreateScriptTaps: (stages: Array<number>) => Array<{ function: ((arg: JsCreateScriptData) => String); stage: number; }>
registerRuntimePluginLinkPreloadTaps: (stages: Array<number>) => Array<{ function: ((arg: JsLinkPreloadData) => String); stage: number; }>
registerRuntimePluginLinkPrefetchTaps: (stages: Array<number>) => Array<{ function: ((arg: JsLinkPrefetchData) => String); stage: number; }>
}

export interface ThreadsafeNodeFS {
Expand Down
110 changes: 106 additions & 4 deletions crates/node_binding/src/plugins/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ use rspack_binding_values::{
JsChunkAssetArgs, JsChunkWrapper, JsCompilationWrapper,
JsContextModuleFactoryAfterResolveDataWrapper, JsContextModuleFactoryAfterResolveResult,
JsContextModuleFactoryBeforeResolveDataWrapper, JsContextModuleFactoryBeforeResolveResult,
JsCreateData, JsExecuteModuleArg, JsFactorizeArgs, JsFactorizeOutput, JsModuleWrapper,
JsNormalModuleFactoryCreateModuleArgs, JsResolveArgs, JsResolveForSchemeArgs,
JsResolveForSchemeOutput, JsResolveOutput, JsRuntimeGlobals, JsRuntimeModule, JsRuntimeModuleArg,
JsRuntimeRequirementInTreeArg, JsRuntimeRequirementInTreeResult, ToJsCompatSourceOwned,
JsCreateData, JsCreateScriptData, JsExecuteModuleArg, JsFactorizeArgs, JsFactorizeOutput,
JsLinkPrefetchData, JsLinkPreloadData, JsModuleWrapper, JsNormalModuleFactoryCreateModuleArgs,
JsResolveArgs, JsResolveForSchemeArgs, JsResolveForSchemeOutput, JsResolveOutput,
JsRuntimeGlobals, JsRuntimeModule, JsRuntimeModuleArg, JsRuntimeRequirementInTreeArg,
JsRuntimeRequirementInTreeResult, ToJsCompatSourceOwned,
};
use rspack_collections::IdentifierSet;
use rspack_core::{
Expand Down Expand Up @@ -67,6 +68,11 @@ use rspack_plugin_html::{
HtmlPluginBeforeAssetTagGenerationHook, HtmlPluginBeforeEmit, HtmlPluginBeforeEmitHook,
};
use rspack_plugin_javascript::{JavascriptModulesChunkHash, JavascriptModulesChunkHashHook};
use rspack_plugin_runtime::{
CreateScriptData, LinkPrefetchData, LinkPreloadData, RuntimePluginCreateScript,
RuntimePluginCreateScriptHook, RuntimePluginLinkPrefetch, RuntimePluginLinkPrefetchHook,
RuntimePluginLinkPreload, RuntimePluginLinkPreloadHook,
};

#[napi(object)]
pub struct JsTap<'f> {
Expand Down Expand Up @@ -386,6 +392,9 @@ pub enum RegisterJsTapKind {
HtmlPluginAfterTemplateExecution,
HtmlPluginBeforeEmit,
HtmlPluginAfterEmit,
RuntimePluginCreateScript,
RuntimePluginLinkPreload,
RuntimePluginLinkPrefetch,
}

#[derive(Default, Clone)]
Expand Down Expand Up @@ -589,6 +598,21 @@ pub struct RegisterJsTaps {
)]
pub register_html_plugin_after_emit_taps:
RegisterFunction<JsAfterEmitData, Promise<JsAfterEmitData>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsCreateScriptData) => String); stage: number; }>"
)]
pub register_runtime_plugin_create_script_taps:
RegisterFunction<JsCreateScriptData, Option<String>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsLinkPreloadData) => String); stage: number; }>"
)]
pub register_runtime_plugin_link_preload_taps:
RegisterFunction<JsLinkPreloadData, Option<String>>,
#[napi(
ts_type = "(stages: Array<number>) => Array<{ function: ((arg: JsLinkPrefetchData) => String); stage: number; }>"
)]
pub register_runtime_plugin_link_prefetch_taps:
RegisterFunction<JsLinkPrefetchData, Option<String>>,
}

/* Compiler Hooks */
Expand Down Expand Up @@ -935,6 +959,30 @@ define_register!(
kind = RegisterJsTapKind::HtmlPluginAfterEmit,
skip = true,
);
define_register!(
RegisterRuntimePluginCreateScriptTaps,
tap = RuntimePluginCreateScriptTap<JsCreateScriptData, Option<String>> @ RuntimePluginCreateScriptHook,
cache = true,
sync = false,
kind = RegisterJsTapKind::RuntimePluginCreateScript,
skip = true,
);
define_register!(
RegisterRuntimePluginLinkPreloadTaps,
tap = RuntimePluginLinkPreloadTap<JsLinkPreloadData, Option<String>> @ RuntimePluginLinkPreloadHook,
cache = true,
sync = false,
kind = RegisterJsTapKind::RuntimePluginLinkPreload,
skip = true,
);
define_register!(
RegisterRuntimePluginLinkPrefetchTaps,
tap = RuntimePluginLinkPrefetchTap<JsLinkPrefetchData, Option<String>> @ RuntimePluginLinkPrefetchHook,
cache = true,
sync = false,
kind = RegisterJsTapKind::RuntimePluginLinkPrefetch,
skip = true,
);

#[async_trait]
impl CompilerThisCompilation for CompilerThisCompilationTap {
Expand Down Expand Up @@ -1768,3 +1816,57 @@ impl HtmlPluginAfterEmit for HtmlPluginAfterEmitTap {
self.stage
}
}

#[async_trait]
impl RuntimePluginCreateScript for RuntimePluginCreateScriptTap {
async fn run(&self, mut data: CreateScriptData) -> rspack_error::Result<CreateScriptData> {
if let Some(code) = self
.function
.call_with_sync(JsCreateScriptData::from(data.clone()))
.await?
{
data.code = code;
}
Ok(data)
}

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

#[async_trait]
impl RuntimePluginLinkPreload for RuntimePluginLinkPreloadTap {
async fn run(&self, mut data: LinkPreloadData) -> rspack_error::Result<LinkPreloadData> {
if let Some(code) = self
.function
.call_with_sync(JsLinkPreloadData::from(data.clone()))
.await?
{
data.code = code;
}
Ok(data)
}

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

#[async_trait]
impl RuntimePluginLinkPrefetch for RuntimePluginLinkPrefetchTap {
async fn run(&self, mut data: LinkPrefetchData) -> rspack_error::Result<LinkPrefetchData> {
if let Some(code) = self
.function
.call_with_sync(JsLinkPrefetchData::from(data.clone()))
.await?
{
data.code = code;
}
Ok(data)
}

fn stage(&self) -> i32 {
self.stage
}
}
48 changes: 48 additions & 0 deletions crates/node_binding/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rspack_hook::plugin_hook;
use rspack_hook::Hook as _;
use rspack_plugin_html::HtmlRspackPlugin;
use rspack_plugin_javascript::JsPlugin;
use rspack_plugin_runtime::RuntimePlugin;

use self::interceptor::*;

Expand Down Expand Up @@ -67,6 +68,9 @@ pub struct JsHooksAdapterPlugin {
register_html_plugin_after_template_execution_taps: RegisterHtmlPluginAfterTemplateExecutionTaps,
register_html_plugin_before_emit_taps: RegisterHtmlPluginBeforeEmitTaps,
register_html_plugin_after_emit_taps: RegisterHtmlPluginAfterEmitTaps,
register_runtime_plugin_create_script_taps: RegisterRuntimePluginCreateScriptTaps,
register_runtime_plugin_link_preload_taps: RegisterRuntimePluginLinkPreloadTaps,
register_runtime_plugin_link_prefetch_taps: RegisterRuntimePluginLinkPrefetchTaps,
}

impl fmt::Debug for JsHooksAdapterPlugin {
Expand Down Expand Up @@ -311,6 +315,12 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
.compilation
.tap(html_hooks_adapter_compilation::new(self));

ctx
.context
.compiler_hooks
.compilation
.tap(runtime_hooks_adapter_compilation::new(self));

Ok(())
}

Expand Down Expand Up @@ -396,6 +406,13 @@ impl rspack_core::Plugin for JsHooksAdapterPlugin {
.clear_cache();
self.register_html_plugin_before_emit_taps.clear_cache();
self.register_html_plugin_after_emit_taps.clear_cache();
self
.register_runtime_plugin_create_script_taps
.clear_cache();
self.register_runtime_plugin_link_preload_taps.clear_cache();
self
.register_runtime_plugin_link_prefetch_taps
.clear_cache();
}
}

Expand Down Expand Up @@ -448,6 +465,25 @@ async fn html_hooks_adapter_compilation(
Ok(())
}

#[plugin_hook(CompilerCompilation for JsHooksAdapterPlugin)]
async fn runtime_hooks_adapter_compilation(
&self,
compilation: &mut Compilation,
_params: &mut CompilationParams,
) -> rspack_error::Result<()> {
let mut hooks = RuntimePlugin::get_compilation_hooks_mut(compilation);
hooks
.create_script
.intercept(self.register_runtime_plugin_create_script_taps.clone());
hooks
.link_preload
.intercept(self.register_runtime_plugin_link_preload_taps.clone());
hooks
.link_prefetch
.intercept(self.register_runtime_plugin_link_prefetch_taps.clone());
Ok(())
}

impl JsHooksAdapterPlugin {
pub fn from_js_hooks(_env: Env, register_js_taps: RegisterJsTaps) -> Result<Self> {
let non_skippable_registers = NonSkippableRegisters::default();
Expand Down Expand Up @@ -632,6 +668,18 @@ impl JsHooksAdapterPlugin {
register_js_taps.register_html_plugin_after_emit_taps,
non_skippable_registers.clone(),
),
register_runtime_plugin_create_script_taps: RegisterRuntimePluginCreateScriptTaps::new(
register_js_taps.register_runtime_plugin_create_script_taps,
non_skippable_registers.clone(),
),
register_runtime_plugin_link_preload_taps: RegisterRuntimePluginLinkPreloadTaps::new(
register_js_taps.register_runtime_plugin_link_preload_taps,
non_skippable_registers.clone(),
),
register_runtime_plugin_link_prefetch_taps: RegisterRuntimePluginLinkPrefetchTaps::new(
register_js_taps.register_runtime_plugin_link_prefetch_taps,
non_skippable_registers.clone(),
),
non_skippable_registers,
}
.into(),
Expand Down
6 changes: 3 additions & 3 deletions crates/rspack_binding_values/src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ thread_local! {
}

pub struct JsChunkWrapper {
chunk_ukey: ChunkUkey,
compilation_id: CompilationId,
compilation: NonNull<Compilation>,
pub chunk_ukey: ChunkUkey,
pub compilation_id: CompilationId,
pub compilation: NonNull<Compilation>,
}

unsafe impl Send for JsChunkWrapper {}
Expand Down
Loading

2 comments on commit 7075fd2

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented on 7075fd2 Jan 23, 2025

Choose a reason for hiding this comment

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

📝 Ecosystem CI detail: Open

suite result
modernjs ❌ failure
rspress ✅ success
rslib ✅ success
rsbuild ✅ success
rsdoctor ✅ success
examples ✅ success
devserver ❌ failure
nuxt ✅ success

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented on 7075fd2 Jan 23, 2025

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 (2025-01-21 c06787b) Current Change
10000_big_production-mode_disable-minimize + exec 36.7 s ± 515 ms 38.6 s ± 1.23 s +5.18 %
10000_development-mode + exec 1.86 s ± 52 ms 1.84 s ± 45 ms -1.25 %
10000_development-mode_hmr + exec 681 ms ± 9.8 ms 684 ms ± 13 ms +0.50 %
10000_production-mode + exec 2.45 s ± 138 ms 2.43 s ± 149 ms -0.65 %
10000_production-mode_persistent-cold + exec 2.61 s ± 155 ms 2.54 s ± 61 ms -2.62 %
10000_production-mode_persistent-hot + exec 1.77 s ± 116 ms 1.78 s ± 151 ms +0.58 %
arco-pro_development-mode + exec 1.76 s ± 98 ms 1.72 s ± 74 ms -2.05 %
arco-pro_development-mode_hmr + exec 388 ms ± 2.3 ms 389 ms ± 1.5 ms +0.23 %
arco-pro_production-mode + exec 3.64 s ± 257 ms 3.75 s ± 191 ms +3.01 %
arco-pro_production-mode_generate-package-json-webpack-plugin + exec 3.75 s ± 314 ms 3.8 s ± 151 ms +1.19 %
arco-pro_production-mode_persistent-cold + exec 3.8 s ± 165 ms 3.95 s ± 62 ms +4.03 %
arco-pro_production-mode_persistent-hot + exec 2.34 s ± 79 ms 2.57 s ± 214 ms +10.16 %
arco-pro_production-mode_traverse-chunk-modules + exec 3.67 s ± 99 ms 3.73 s ± 95 ms +1.78 %
large-dyn-imports_development-mode + exec 2.11 s ± 29 ms 2.1 s ± 70 ms -0.34 %
large-dyn-imports_production-mode + exec 2.16 s ± 40 ms 2.14 s ± 28 ms -0.85 %
threejs_development-mode_10x + exec 1.53 s ± 22 ms 1.53 s ± 19 ms +0.04 %
threejs_development-mode_10x_hmr + exec 788 ms ± 39 ms 790 ms ± 12 ms +0.23 %
threejs_production-mode_10x + exec 5.25 s ± 61 ms 5.46 s ± 193 ms +4.05 %
threejs_production-mode_10x_persistent-cold + exec 5.35 s ± 65 ms 5.54 s ± 149 ms +3.65 %
threejs_production-mode_10x_persistent-hot + exec 4.5 s ± 44 ms 4.83 s ± 303 ms +7.21 %
10000_big_production-mode_disable-minimize + rss memory 8680 MiB ± 34.2 MiB 8745 MiB ± 266 MiB +0.74 %
10000_development-mode + rss memory 656 MiB ± 19.6 MiB 658 MiB ± 21.3 MiB +0.34 %
10000_development-mode_hmr + rss memory 1264 MiB ± 163 MiB 1269 MiB ± 253 MiB +0.41 %
10000_production-mode + rss memory 639 MiB ± 31 MiB 632 MiB ± 29.8 MiB -1.08 %
10000_production-mode_persistent-cold + rss memory 744 MiB ± 15.6 MiB 740 MiB ± 19.4 MiB -0.58 %
10000_production-mode_persistent-hot + rss memory 723 MiB ± 37.7 MiB 723 MiB ± 21.4 MiB -0.04 %
arco-pro_development-mode + rss memory 553 MiB ± 38.1 MiB 565 MiB ± 32.7 MiB +2.22 %
arco-pro_development-mode_hmr + rss memory 631 MiB ± 36 MiB 669 MiB ± 64.8 MiB +5.95 %
arco-pro_production-mode + rss memory 738 MiB ± 66.3 MiB 723 MiB ± 37.1 MiB -2.08 %
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory 730 MiB ± 23.1 MiB 736 MiB ± 13.5 MiB +0.85 %
arco-pro_production-mode_persistent-cold + rss memory 844 MiB ± 36.6 MiB 861 MiB ± 60.9 MiB +2.09 %
arco-pro_production-mode_persistent-hot + rss memory 695 MiB ± 19.9 MiB 719 MiB ± 39.7 MiB +3.53 %
arco-pro_production-mode_traverse-chunk-modules + rss memory 727 MiB ± 32.5 MiB 732 MiB ± 38.8 MiB +0.74 %
large-dyn-imports_development-mode + rss memory 642 MiB ± 4.5 MiB 647 MiB ± 6.13 MiB +0.83 %
large-dyn-imports_production-mode + rss memory 523 MiB ± 4.79 MiB 530 MiB ± 7 MiB +1.19 %
threejs_development-mode_10x + rss memory 551 MiB ± 32.9 MiB 550 MiB ± 19.2 MiB -0.15 %
threejs_development-mode_10x_hmr + rss memory 1145 MiB ± 125 MiB 1143 MiB ± 94.2 MiB -0.13 %
threejs_production-mode_10x + rss memory 865 MiB ± 36.9 MiB 833 MiB ± 42.7 MiB -3.69 %
threejs_production-mode_10x_persistent-cold + rss memory 968 MiB ± 136 MiB 935 MiB ± 42.4 MiB -3.41 %
threejs_production-mode_10x_persistent-hot + rss memory 870 MiB ± 25.8 MiB 856 MiB ± 43.1 MiB -1.65 %

Threshold exceeded: ["10000_big_production-mode_disable-minimize + exec","arco-pro_production-mode_persistent-hot + exec","threejs_production-mode_10x_persistent-hot + exec"]

Please sign in to comment.