-
-
Notifications
You must be signed in to change notification settings - Fork 552
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support dependencies in resolve hook callback (#7949)
* feat: dependencies in context module factory hook * feat: ContextModuleFactoryBeforeResolveData * feat: update test case * fix: cargo lint * chore: update api docs * feat: JsDependency and JsDependencyMut * fix: remove lifecycle * chore: update api * fix: Dependency
- Loading branch information
Showing
12 changed files
with
415 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,108 @@ | ||
use napi_derive::napi; | ||
use rspack_core::{Compilation, Dependency, DependencyId, ModuleDependency, ModuleGraph}; | ||
use rspack_core::{BoxDependency, DependencyId}; | ||
|
||
// JsDependency allows JS-side access to a Dependency instance that has already | ||
// been processed and stored in the Compilation. | ||
#[napi] | ||
pub struct DependencyDTO { | ||
pub(crate) dependency_id: DependencyId, | ||
pub(crate) compilation: &'static Compilation, | ||
pub struct JsDependency(&'static BoxDependency); | ||
|
||
impl JsDependency { | ||
pub(crate) fn new(dependency: &BoxDependency) -> Self { | ||
// SAFETY: | ||
// The lifetime of the &mut BoxDependency reference is extended to 'static. | ||
// Accessing fields and methods on the Rust object from the JS side after the Rust object's | ||
// lifetime has ended is undefined behavior, which we currently disregard. | ||
let dependency = | ||
unsafe { std::mem::transmute::<&BoxDependency, &'static BoxDependency>(dependency) }; | ||
Self(dependency) | ||
} | ||
|
||
pub(crate) fn id(&self) -> &DependencyId { | ||
self.0.id() | ||
} | ||
} | ||
|
||
impl DependencyDTO { | ||
pub(crate) fn new(dependency_id: DependencyId, compilation: &'static Compilation) -> Self { | ||
Self { | ||
dependency_id, | ||
compilation, | ||
#[napi] | ||
impl JsDependency { | ||
#[napi(getter)] | ||
pub fn get_type(&self) -> &str { | ||
self.0.dependency_type().as_str() | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn category(&self) -> &str { | ||
self.0.category().as_str() | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn request(&self) -> napi::Either<&str, ()> { | ||
match self.0.as_module_dependency() { | ||
Some(dep) => napi::Either::A(dep.request()), | ||
None => napi::Either::B(()), | ||
} | ||
} | ||
|
||
fn dependency<'a>(&self, module_graph: &'a ModuleGraph) -> &'a dyn Dependency { | ||
module_graph | ||
.dependency_by_id(&self.dependency_id) | ||
.unwrap_or_else(|| panic!("Failed to get dependency by id = {:?}", &self.dependency_id)) | ||
.as_ref() | ||
#[napi(getter)] | ||
pub fn critical(&self) -> bool { | ||
match self.0.as_context_dependency() { | ||
Some(dep) => dep.critical().is_some(), | ||
None => false, | ||
} | ||
} | ||
} | ||
|
||
fn module_dependency<'a>( | ||
&self, | ||
module_graph: &'a ModuleGraph, | ||
) -> Option<&'a dyn ModuleDependency> { | ||
self.dependency(module_graph).as_module_dependency() | ||
// JsDependency represents a Dependency instance that is currently being processed. | ||
// It is in the make stage and has not yet been added to the Compilation. | ||
#[napi] | ||
pub struct JsDependencyMut(&'static mut BoxDependency); | ||
|
||
impl JsDependencyMut { | ||
pub(crate) fn new(dependency: &mut BoxDependency) -> Self { | ||
// SAFETY: | ||
// The lifetime of the &mut BoxDependency reference is extended to 'static. | ||
// Accessing fields and methods on the Rust object from the JS side after the Rust object's | ||
// lifetime has ended is undefined behavior, which we currently disregard. | ||
let dependency = | ||
unsafe { std::mem::transmute::<&mut BoxDependency, &'static mut BoxDependency>(dependency) }; | ||
Self(dependency) | ||
} | ||
} | ||
|
||
#[napi] | ||
impl DependencyDTO { | ||
impl JsDependencyMut { | ||
#[napi(getter)] | ||
pub fn get_type(&self) -> &str { | ||
let module_graph = self.compilation.get_module_graph(); | ||
let dep = self.dependency(&module_graph); | ||
dep.dependency_type().as_str() | ||
self.0.dependency_type().as_str() | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn category(&self) -> &str { | ||
let module_graph = self.compilation.get_module_graph(); | ||
let dep = self.dependency(&module_graph); | ||
dep.category().as_str() | ||
self.0.category().as_str() | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn request(&self) -> napi::Either<String, ()> { | ||
let module_graph = self.compilation.get_module_graph(); | ||
match self.module_dependency(&module_graph) { | ||
Some(dep) => napi::Either::A(dep.request().to_string()), | ||
pub fn request(&self) -> napi::Either<&str, ()> { | ||
match self.0.as_module_dependency() { | ||
Some(dep) => napi::Either::A(dep.request()), | ||
None => napi::Either::B(()), | ||
} | ||
} | ||
|
||
#[napi(getter)] | ||
pub fn critical(&self) -> bool { | ||
match self.0.as_context_dependency() { | ||
Some(dep) => dep.critical().is_some(), | ||
None => false, | ||
} | ||
} | ||
|
||
#[napi(setter)] | ||
pub fn set_critical(&mut self, val: bool) { | ||
if let Some(dep) = self.0.as_context_dependency_mut() { | ||
let critical = dep.critical_mut(); | ||
if !val { | ||
*critical = None; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
27188f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Benchmark detail: Open
27188f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Ran ecosystem CI: Open