Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: NormalModuleFactory and resolveForScheme hook #2356

Merged
merged 9 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,4 @@ npm/**/*.node

# Precompiled config schema
packages/rspack/src/config/schema.check.js
justfile
2 changes: 1 addition & 1 deletion crates/loader_runner/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_hash::FxHashSet as HashSet;

use crate::{Content, LoaderRunnerPlugin};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct ResourceData {
/// Resource with absolute path, query and fragment
pub resource: String,
Expand Down
15 changes: 15 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,27 @@ export interface JsHooks {
afterEmit: (...args: any[]) => any
make: (...args: any[]) => any
optimizeChunkModule: (...args: any[]) => any
normalModuleFactoryResolveForScheme: (...args: any[]) => any
}
export interface JsModule {
originalSource?: JsCompatSource
resource: string
moduleIdentifier: string
}
export interface SchemeAndJsResourceData {
resourceData: JsResourceData
scheme: string
}
export interface JsResourceData {
/** Resource with absolute path, query and fragment */
resource: string
/** Absolute resource path only */
path: string
/** Resource query with `?` prefix */
query?: string
/** Resource fragment with `#` prefix */
fragment?: string
}
export interface JsCompatSource {
/** Whether the underlying data structure is a `RawSource` */
isRaw: boolean
Expand Down
1 change: 1 addition & 0 deletions crates/node_binding/src/js_values/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ pub struct JsHooks {
pub after_emit: JsFunction,
pub make: JsFunction,
pub optimize_chunk_module: JsFunction,
pub normal_module_factory_resolve_for_scheme: JsFunction,
}
2 changes: 2 additions & 0 deletions crates/node_binding/src/js_values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod chunk_group;
mod compilation;
mod hooks;
mod module;
mod normal_module_factory;
mod source;
mod stats;

Expand All @@ -12,5 +13,6 @@ pub use chunk::*;
pub use chunk_group::*;
pub use compilation::*;
pub use hooks::*;
pub use normal_module_factory::*;
pub use source::*;
pub use stats::*;
39 changes: 39 additions & 0 deletions crates/node_binding/src/js_values/normal_module_factory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use rspack_core::{NormalModuleFactoryResolveForSchemeArgs, ResourceData};

#[napi(object)]
pub struct SchemeAndJsResourceData {
pub resource_data: JsResourceData,
pub scheme: String,
}

#[napi(object)]
pub struct JsResourceData {
/// Resource with absolute path, query and fragment
pub resource: String,
/// Absolute resource path only
pub path: String,
/// Resource query with `?` prefix
pub query: Option<String>,
/// Resource fragment with `#` prefix
pub fragment: Option<String>,
}

impl From<ResourceData> for JsResourceData {
fn from(value: ResourceData) -> Self {
Self {
resource: value.resource,
path: value.resource_path.to_string_lossy().to_string(),
query: value.resource_query,
fragment: value.resource_fragment,
}
}
}

impl From<NormalModuleFactoryResolveForSchemeArgs> for SchemeAndJsResourceData {
fn from(value: NormalModuleFactoryResolveForSchemeArgs) -> Self {
Self {
resource_data: value.resource.into(),
scheme: value.scheme,
}
}
}
80 changes: 58 additions & 22 deletions crates/node_binding/src/plugins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use std::fmt::Debug;
use std::path::PathBuf;

use async_trait::async_trait;
use napi::{Env, Result};
use rspack_binding_macros::js_fn_into_theadsafe_fn;
use rspack_core::{
NormalModuleFactoryResolveForSchemeArgs, PluginNormalModuleFactoryResolveForSchemeOutput,
ResourceData,
};
use rspack_error::internal_error;
use rspack_napi_shared::threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode};
use rspack_napi_shared::NapiResultExt;

use crate::js_values::{JsResourceData, SchemeAndJsResourceData};
use crate::{DisabledHooks, Hook, JsCompilation, JsHooks};

pub struct JsHooksAdapter {
Expand All @@ -23,6 +29,8 @@ pub struct JsHooksAdapter {
pub emit_tsfn: ThreadsafeFunction<(), ()>,
pub after_emit_tsfn: ThreadsafeFunction<(), ()>,
pub optimize_chunk_modules_tsfn: ThreadsafeFunction<JsCompilation, ()>,
pub normal_module_factory_resolve_for_scheme:
ThreadsafeFunction<SchemeAndJsResourceData, JsResourceData>,
}

impl Debug for JsHooksAdapter {
Expand Down Expand Up @@ -100,6 +108,27 @@ impl rspack_core::Plugin for JsHooksAdapter {
.map_err(|err| internal_error!("Failed to call make: {err}",))?
}

async fn normal_module_factory_resolve_for_scheme(
&self,
_ctx: rspack_core::PluginContext,
args: &NormalModuleFactoryResolveForSchemeArgs,
) -> PluginNormalModuleFactoryResolveForSchemeOutput {
let res = self
IWANABETHATGUY marked this conversation as resolved.
Show resolved Hide resolved
.normal_module_factory_resolve_for_scheme
.call(args.clone().into(), ThreadsafeFunctionCallMode::NonBlocking)
.into_rspack_result()?
.await
.map_err(|err| internal_error!("Failed to call this_compilation: {err}"))?;
res.map(|res| {
Some(ResourceData {
resource: res.resource,
resource_fragment: res.fragment,
resource_path: PathBuf::from(res.path),
resource_query: res.query,
})
})
}

async fn process_assets_stage_additional(
&mut self,
_ctx: rspack_core::PluginContext,
Expand Down Expand Up @@ -205,6 +234,28 @@ impl rspack_core::Plugin for JsHooksAdapter {
.map_err(|err| internal_error!("Failed to call process assets stage report: {err}",))?
}

async fn optimize_chunk_modules(
&mut self,
args: rspack_core::OptimizeChunksArgs<'_>,
) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::OptimizeChunkModules) {
return Ok(());
}

let compilation = JsCompilation::from_compilation(unsafe {
std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>(
args.compilation,
)
});

self
.optimize_chunk_modules_tsfn
.call(compilation, ThreadsafeFunctionCallMode::NonBlocking)
.into_rspack_result()?
.await
.map_err(|err| internal_error!("Failed to compilation: {err}"))?
}

async fn emit(&mut self, _: &mut rspack_core::Compilation) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::Emit) {
return Ok(());
Expand All @@ -230,28 +281,6 @@ impl rspack_core::Plugin for JsHooksAdapter {
.await
.map_err(|err| internal_error!("Failed to call after emit: {err}",))?
}

async fn optimize_chunk_modules(
&mut self,
args: rspack_core::OptimizeChunksArgs<'_>,
) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::OptimizeChunkModules) {
return Ok(());
}

let compilation = JsCompilation::from_compilation(unsafe {
std::mem::transmute::<&'_ mut rspack_core::Compilation, &'static mut rspack_core::Compilation>(
args.compilation,
)
});

self
.optimize_chunk_modules_tsfn
.call(compilation, ThreadsafeFunctionCallMode::NonBlocking)
.into_rspack_result()?
.await
.map_err(|err| internal_error!("Failed to compilation: {err}"))?
}
}

impl JsHooksAdapter {
Expand All @@ -269,6 +298,7 @@ impl JsHooksAdapter {
emit,
after_emit,
optimize_chunk_module,
normal_module_factory_resolve_for_scheme,
} = js_hooks;

let process_assets_stage_additional_tsfn: ThreadsafeFunction<(), ()> =
Expand All @@ -293,6 +323,11 @@ impl JsHooksAdapter {
let optimize_chunk_modules_tsfn: ThreadsafeFunction<JsCompilation, ()> =
js_fn_into_theadsafe_fn!(optimize_chunk_module, env);

let normal_module_factory_resolve_for_scheme: ThreadsafeFunction<
SchemeAndJsResourceData,
JsResourceData,
> = js_fn_into_theadsafe_fn!(normal_module_factory_resolve_for_scheme, env);

Ok(JsHooksAdapter {
disabled_hooks,
make_tsfn,
Expand All @@ -307,6 +342,7 @@ impl JsHooksAdapter {
emit_tsfn,
after_emit_tsfn,
optimize_chunk_modules_tsfn,
normal_module_factory_resolve_for_scheme,
})
}

Expand Down
Loading