Skip to content

Commit

Permalink
feat: support _module of LoaderContext (#6631)
Browse files Browse the repository at this point in the history
* Support _module for LoaderContext

* Expose request, userRequest, and rawRequest

* Remove originSource in CompilerModuleContext

* Add testcase

* Fix testcase

* Fix testcase

* Fix Module.rawRequest

* Update snapshot

* Fix clippy

* Add fields for Module

* Add comments

* Update api.md

* Keep module_identifier in loader context

* Update api docs
  • Loading branch information
CPunisher authored Jun 3, 2024
1 parent c0f59c1 commit 8750bf4
Show file tree
Hide file tree
Showing 21 changed files with 271 additions and 62 deletions.
4 changes: 4 additions & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,9 @@ export interface JsLoaderContext {
* @internal
*/
diagnosticsExternal: ExternalObject<'Diagnostic[]'>
/** Will be deprecated. Use module.module_identifier instead */
_moduleIdentifier: string
_module: JsModule
hot: boolean
}

Expand All @@ -415,6 +417,8 @@ export interface JsModule {
resource?: string
moduleIdentifier: string
nameForCondition?: string
request?: string
userRequest?: string
rawRequest?: string
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{ops::Deref, path::PathBuf, str::FromStr};

use napi_derive::napi;
use rspack_binding_values::{JsModule, ToJsModule};
use rspack_core::{rspack_sources::SourceMap, Content, ResourceData};
use rspack_error::Diagnostic;
use rspack_loader_runner::AdditionalData;
Expand Down Expand Up @@ -189,8 +190,11 @@ pub struct JsLoaderContext {
#[napi(ts_type = "ExternalObject<'Diagnostic[]'>")]
pub diagnostics_external: External<Vec<Diagnostic>>,

/// Will be deprecated. Use module.module_identifier instead
#[napi(js_name = "_moduleIdentifier")]
pub module_identifier: String,
#[napi(js_name = "_module")]
pub module: JsModule,

pub hot: bool,
}
Expand Down Expand Up @@ -253,7 +257,12 @@ impl TryFrom<&mut rspack_core::LoaderContext<'_, rspack_core::LoaderRunnerContex
additional_data_external: External::new(cx.additional_data.clone()),
context_external: External::new(cx.context.clone()),
diagnostics_external: External::new(cx.__diagnostics.drain(..).collect()),
module_identifier: cx.context.module.to_string(),
module_identifier: cx.context.module.module_identifier.to_string(),
module: cx
.context
.module
.to_js_module()
.expect("CompilerModuleContext::to_js_module should not fail."),
hot: cx.hot,
})
}
Expand Down
31 changes: 30 additions & 1 deletion crates/rspack_binding_values/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use napi_derive::napi;
use rspack_core::Module;
use rspack_core::{CompilerModuleContext, Module};
use rspack_napi::napi::bindgen_prelude::*;

use super::{JsCompatSource, ToJsCompatSource};
Expand All @@ -13,6 +13,8 @@ pub struct JsModule {
pub resource: Option<String>,
pub module_identifier: String,
pub name_for_condition: Option<String>,
pub request: Option<String>,
pub user_request: Option<String>,
pub raw_request: Option<String>,
}

Expand Down Expand Up @@ -45,6 +47,8 @@ impl ToJsModule for dyn Module {
),
module_identifier: module_identifier(),
name_for_condition: name_for_condition(),
request: Some(normal_module.request().to_string()),
user_request: Some(normal_module.user_request().to_string()),
raw_request: Some(normal_module.raw_request().to_string()),
})
.or_else(|_| {
Expand All @@ -55,6 +59,8 @@ impl ToJsModule for dyn Module {
module_identifier: module_identifier(),
name_for_condition: name_for_condition(),
raw_request: None,
user_request: None,
request: None,
})
})
.or_else(|_| {
Expand All @@ -65,6 +71,8 @@ impl ToJsModule for dyn Module {
module_identifier: module_identifier(),
name_for_condition: name_for_condition(),
raw_request: None,
user_request: None,
request: None,
})
})
.or_else(|_| {
Expand All @@ -75,6 +83,8 @@ impl ToJsModule for dyn Module {
module_identifier: module_identifier(),
name_for_condition: name_for_condition(),
raw_request: None,
user_request: None,
request: None,
})
})
.or_else(|_| {
Expand All @@ -88,6 +98,25 @@ impl ToJsModule for dyn Module {
}
}

impl ToJsModule for CompilerModuleContext {
fn to_js_module(&self) -> Result<JsModule> {
let module = JsModule {
context: self.context.as_ref().map(|c| c.to_string()),
module_identifier: self.module_identifier.to_string(),
name_for_condition: self.name_for_condition.clone(),
resource: self
.resource
.as_ref()
.map(|r| r.resource_path.to_string_lossy().to_string()),
original_source: None,
request: self.request.clone(),
user_request: self.user_request.clone(),
raw_request: self.raw_request.clone(),
};
Ok(module)
}
}

#[napi(object)]
pub struct JsExecuteModuleArg {
pub entry: String,
Expand Down
6 changes: 3 additions & 3 deletions crates/rspack_core/src/compiler/make/repair/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use super::{process_dependencies::ProcessDependenciesTask, MakeTaskContext};
use crate::{
utils::task_loop::{Task, TaskResult, TaskType},
AsyncDependenciesBlock, BoxDependency, BuildContext, BuildResult, CompilerContext,
CompilerOptions, DependencyParents, Module, ModuleProfile, ResolverFactory, SharedPluginDriver,
CompilerModuleContext, CompilerOptions, DependencyParents, Module, ModuleProfile,
ResolverFactory, SharedPluginDriver,
};

#[derive(Debug)]
Expand Down Expand Up @@ -47,8 +48,7 @@ impl Task<MakeTaskContext> for BuildTask {
compiler_context: CompilerContext {
options: compiler_options.clone(),
resolver_factory: resolver_factory.clone(),
module: module.identifier(),
module_context: module.as_normal_module().and_then(|m| m.get_context()),
module: CompilerModuleContext::from_module(module.as_ref()),
module_source_map_kind: *module.get_source_map_kind(),
plugin_driver: plugin_driver.clone(),
},
Expand Down
34 changes: 31 additions & 3 deletions crates/rspack_core/src/loader/loader_runner.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
use std::sync::Arc;

use rspack_loader_runner::ResourceData;
pub use rspack_loader_runner::{run_loaders, Content, Loader, LoaderContext};
use rspack_util::source_map::SourceMapKind;

use crate::{CompilerOptions, Context, ModuleIdentifier, ResolverFactory, SharedPluginDriver};
use crate::{
CompilerOptions, Context, Module, ModuleIdentifier, ResolverFactory, SharedPluginDriver,
};

#[derive(Debug, Clone)]
pub struct CompilerModuleContext {
pub context: Option<Box<Context>>,
pub resource: Option<ResourceData>,
pub module_identifier: ModuleIdentifier,
pub name_for_condition: Option<String>,
pub request: Option<String>,
pub user_request: Option<String>,
pub raw_request: Option<String>,
}

impl CompilerModuleContext {
pub fn from_module(module: &dyn Module) -> Self {
let normal_module = module.as_normal_module();
Self {
context: module.get_context(),
resource: normal_module.map(|normal_module| normal_module.resource_resolved_data().clone()),
module_identifier: module.identifier(),
name_for_condition: module.name_for_condition().map(|s| s.to_string()),
request: normal_module.map(|normal_module| normal_module.request().to_owned()),
user_request: normal_module.map(|normal_module| normal_module.user_request().to_owned()),
raw_request: normal_module.map(|normal_module| normal_module.raw_request().to_owned()),
}
}
}

#[derive(Debug, Clone)]
pub struct CompilerContext {
pub options: Arc<CompilerOptions>,
pub resolver_factory: Arc<ResolverFactory>,
pub module: ModuleIdentifier, // current module
pub module_context: Option<Box<Context>>, // current module context
pub module: CompilerModuleContext,
pub module_source_map_kind: SourceMapKind,
pub plugin_driver: SharedPluginDriver,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ use rspack_core::concatenated_module::{
};
use rspack_core::{
filter_runtime, merge_runtime, runtime_to_string, ApplyContext, Compilation,
CompilationOptimizeChunkModules, CompilerContext, CompilerOptions, ExportInfoProvided,
ExtendedReferencedExport, LibIdentOptions, Logger, Module, ModuleExt, ModuleGraph,
ModuleGraphModule, ModuleIdentifier, MutableModuleGraph, Plugin, PluginContext, ProvidedExports,
RuntimeCondition, RuntimeSpec, SourceType,
CompilationOptimizeChunkModules, CompilerContext, CompilerModuleContext, CompilerOptions,
ExportInfoProvided, ExtendedReferencedExport, LibIdentOptions, Logger, Module, ModuleExt,
ModuleGraph, ModuleGraphModule, ModuleIdentifier, MutableModuleGraph, Plugin, PluginContext,
ProvidedExports, RuntimeCondition, RuntimeSpec, SourceType,
};
use rspack_error::Result;
use rspack_hook::{plugin, plugin_hook};
Expand Down Expand Up @@ -910,8 +910,7 @@ impl ModuleConcatenationPlugin {
compiler_context: CompilerContext {
options: compilation.options.clone(),
resolver_factory: compilation.resolver_factory.clone(),
module: new_module.id(),
module_context: None,
module: CompilerModuleContext::from_module(&new_module),
module_source_map_kind: rspack_util::source_map::SourceMapKind::empty(),
plugin_driver: compilation.plugin_driver.clone(),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Plugin {
initial = false;

expect(
oldModule.originalSource.source().includes("a = 1")
oldModule.originalSource().source().includes("a = 1")
).toBe(true);

const newModule = await new Promise((res, rej) => {
Expand All @@ -27,7 +27,7 @@ class Plugin {
});

expect(
newModule.originalSource.source().includes("a = 2")
newModule.originalSource().source().includes("a = 2")
).toBe(true);
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = "a";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
it("should exist request, rawRequest, and userRequest", async () => {
const result = require("./a");
const { request, userRequest, rawRequest } = result;
expect(request.endsWith("a.js")).toBe(true);
expect(userRequest.endsWith("a.js")).toBe(true);
expect(rawRequest).toBe("./a");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = function () {
this._module.buildInfo.LOADER_ACCESS = true;
this._module.buildMeta.LOADER_ACCESS = true;
return (
"module.exports = " +
JSON.stringify({
request: this._module.request,
userRequest: this._module.userRequest,
rawRequest: this._module.rawRequest,
})
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const path = require("path");
const assert = require("assert");

/**
* @type {import('@rspack/core').RspackOptions}
*/
module.exports = {
context: __dirname,
module: {
rules: [
{
test: path.join(__dirname, "a.js"),
use: [
{
loader: "./my-loader.js"
}
]
},
]
},
plugins: [
{
apply(compiler) {
compiler.hooks.thisCompilation.tap("MyPlugin", compilation => {
compilation.hooks.processAssets.tap("MyPlugin", () => {
let hasModule = false;
for (const chunk of compilation.chunks) {
const modules = compilation.chunkGraph.getChunkModules(chunk);
for (const module of modules) {
if (module.identifier().endsWith("a.js")) {
hasModule = true;
assert(module.buildInfo.LOADER_ACCESS === true);
assert(module.buildMeta.LOADER_ACCESS === true);
}
}
}
assert(hasModule);
})
})
}
}
]
};
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ERROR in ./logo.svg× Module build failed:╰─▶ × Error: Failed to loadat Object.<anonymous>.module.exports (<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/asset-module-build-failed/my-loader.js:2:8)at LOADER_EXECUTION (<RSPACK_ROOT>/dist/loader-runner/index.js:618:23)at runSyncOrAsync (<RSPACK_ROOT>/dist/loader-runner/index.js:619:11)at <RSPACK_ROOT>/dist/loader-runner/index.js:723:9at handleResult (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:125:5)at loadLoader (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:106:16)at iterateNormalLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:712:5)at <RSPACK_ROOT>/dist/loader-runner/index.js:539:13at new Promise (<anonymous>)at runLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:514:12)help: File was processed with this loader: '<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/asset-module-build-failed/my-loader.js'
ERROR in ./logo.svg× Module build failed:╰─▶ × Error: Failed to loadat Object.<anonymous>.module.exports (<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/asset-module-build-failed/my-loader.js:2:8)at LOADER_EXECUTION (<RSPACK_ROOT>/dist/loader-runner/index.js:620:23)at runSyncOrAsync (<RSPACK_ROOT>/dist/loader-runner/index.js:621:11)at <RSPACK_ROOT>/dist/loader-runner/index.js:725:9at handleResult (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:125:5)at loadLoader (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:106:16)at iterateNormalLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:714:5)at <RSPACK_ROOT>/dist/loader-runner/index.js:541:13at new Promise (<anonymous>)at runLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:516:12)help: File was processed with this loader: '<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/asset-module-build-failed/my-loader.js'
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ERROR in ./lib.js× Module build failed:╰─▶ × Error: Failed to loadat Object.<anonymous>.module.exports (<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/loader-throw-error/my-loader.js:2:9)at LOADER_EXECUTION (<RSPACK_ROOT>/dist/loader-runner/index.js:618:23)at runSyncOrAsync (<RSPACK_ROOT>/dist/loader-runner/index.js:619:11)at <RSPACK_ROOT>/dist/loader-runner/index.js:723:9at handleResult (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:125:5)at loadLoader (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:106:16)at iterateNormalLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:712:5)at <RSPACK_ROOT>/dist/loader-runner/index.js:539:13at new Promise (<anonymous>)at runLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:514:12)help: File was processed with this loader: '<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/loader-throw-error/my-loader.js'
ERROR in ./lib.js× Module build failed:╰─▶ × Error: Failed to loadat Object.<anonymous>.module.exports (<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/loader-throw-error/my-loader.js:2:9)at LOADER_EXECUTION (<RSPACK_ROOT>/dist/loader-runner/index.js:620:23)at runSyncOrAsync (<RSPACK_ROOT>/dist/loader-runner/index.js:621:11)at <RSPACK_ROOT>/dist/loader-runner/index.js:725:9at handleResult (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:125:5)at loadLoader (<RSPACK_ROOT>/dist/loader-runner/loadLoader.js:106:16)at iterateNormalLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:714:5)at <RSPACK_ROOT>/dist/loader-runner/index.js:541:13at new Promise (<anonymous>)at runLoaders (<RSPACK_ROOT>/dist/loader-runner/index.js:516:12)help: File was processed with this loader: '<PROJECT_ROOT>/tests/diagnosticsCases/module-build-failed/loader-throw-error/my-loader.js'
23 changes: 18 additions & 5 deletions packages/rspack/etc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,11 @@ export class Compilation {
// @internal
__internal__getChunks(): Chunk[];
// @internal
__internal__getCustomModule(moduleIdentifier: string): {
buildInfo: Record<string, unknown>;
buildMeta: Record<string, unknown>;
};
// @internal
__internal__getModules(): JsModule[];
// @internal
__internal__hasAsset(name: string): boolean;
Expand Down Expand Up @@ -4668,6 +4673,8 @@ export interface LoaderContext<OptionsType = {}> {
// (undocumented)
mode?: Mode;
// (undocumented)
_module: Module;
// (undocumented)
previousRequest: string;
// (undocumented)
query: string | OptionsType;
Expand Down Expand Up @@ -4900,23 +4907,29 @@ const mode: z.ZodEnum<["development", "production", "none"]>;

// @public (undocumented)
export class Module {
constructor(module: JsModule);
constructor(module: JsModule, compilation?: Compilation);
// (undocumented)
static __from_binding(module: JsModule): Module;
static __from_binding(module: JsModule, compilation?: Compilation): Module;
buildInfo: Record<string, any>;
buildMeta: Record<string, any>;
// (undocumented)
get context(): string | undefined;
context?: string;
// (undocumented)
identifier(): string;
// (undocumented)
nameForCondition(): string | null;
// (undocumented)
get originalSource(): Source | null;
originalSource(): Source | null;
// (undocumented)
_originalSource?: Source;
// (undocumented)
rawRequest?: string;
// (undocumented)
get resource(): string | undefined;
request?: string;
// (undocumented)
resource?: string;
// (undocumented)
userRequest?: string;
}

// @public (undocumented)
Expand Down
Loading

2 comments on commit 8750bf4

@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-06-03 7d5d175) Current Change
10000_development-mode + exec 2.24 s ± 21 ms 2.21 s ± 19 ms -1.07 %
10000_development-mode_hmr + exec 738 ms ± 16 ms 738 ms ± 7.4 ms -0.06 %
10000_production-mode + exec 2.59 s ± 25 ms 2.58 s ± 29 ms -0.57 %
arco-pro_development-mode + exec 1.92 s ± 85 ms 1.93 s ± 94 ms +0.43 %
arco-pro_development-mode_hmr + exec 442 ms ± 1.6 ms 445 ms ± 3.7 ms +0.79 %
arco-pro_production-mode + exec 3.48 s ± 98 ms 3.53 s ± 84 ms +1.43 %
threejs_development-mode_10x + exec 1.38 s ± 16 ms 1.49 s ± 22 ms +8.09 %
threejs_development-mode_10x_hmr + exec 831 ms ± 4.4 ms 851 ms ± 4.3 ms +2.41 %
threejs_production-mode_10x + exec 4.7 s ± 32 ms 5.01 s ± 38 ms +6.51 %

Threshold exceeded: ["threejs_development-mode_10x + exec","threejs_production-mode_10x + exec"]

@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 ✅ success
_selftest ✅ success
nx ✅ success
rspress ✅ success
rsbuild ✅ success
compat ✅ success
examples ✅ success

Please sign in to comment.