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: add buildModule hook #3466

Merged
merged 3 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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 crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ export interface JsHooks {
afterCompile: (...args: any[]) => any
finishModules: (...args: any[]) => any
finishMake: (...args: any[]) => any
buildModule: (...args: any[]) => any
beforeResolve: (...args: any[]) => any
afterResolve: (...args: any[]) => any
contextModuleBeforeResolve: (...args: any[]) => any
Expand Down
2 changes: 2 additions & 0 deletions crates/node_binding/src/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::sync::{Arc, RwLock};
pub enum Hook {
Make,
FinishMake,
BuildModule,
Compilation,
ThisCompilation,
ProcessAssetsStageAdditional,
Expand Down Expand Up @@ -37,6 +38,7 @@ impl From<String> for Hook {
match s.as_str() {
"make" => Hook::Make,
"finishMake" => Hook::FinishMake,
"buildModule" => Hook::BuildModule,
"compilation" => Hook::Compilation,
"thisCompilation" => Hook::ThisCompilation,
"processAssetsStageAdditional" => Hook::ProcessAssetsStageAdditional,
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 @@ -22,6 +22,7 @@ pub struct JsHooks {
pub after_compile: JsFunction,
pub finish_modules: JsFunction,
pub finish_make: JsFunction,
pub build_module: JsFunction,
pub before_resolve: JsFunction,
pub after_resolve: JsFunction,
pub context_module_before_resolve: JsFunction,
Expand Down
21 changes: 21 additions & 0 deletions crates/node_binding/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct JsHooksAdapter {
pub after_compile_tsfn: ThreadsafeFunction<JsCompilation, ()>,
pub finish_modules_tsfn: ThreadsafeFunction<JsCompilation, ()>,
pub finish_make_tsfn: ThreadsafeFunction<JsCompilation, ()>,
pub build_module_tsfn: ThreadsafeFunction<JsModule, ()>, // TODO
pub chunk_asset_tsfn: ThreadsafeFunction<JsChunkAssetArgs, ()>,
pub before_resolve: ThreadsafeFunction<BeforeResolveData, (Option<bool>, BeforeResolveData)>,
pub after_resolve: ThreadsafeFunction<AfterResolveData, Option<bool>>,
Expand Down Expand Up @@ -464,6 +465,22 @@ impl rspack_core::Plugin for JsHooksAdapter {
.map_err(|err| internal_error!("Failed to call finish make: {err}"))?
}

async fn build_module(&self, module: &mut dyn rspack_core::Module) -> rspack_error::Result<()> {
if self.is_hook_disabled(&Hook::BuildModule) {
return Ok(());
}

self
.build_module_tsfn
.call(
module.to_js_module().expect("Convert to js_module failed."),
ThreadsafeFunctionCallMode::NonBlocking,
)
.into_rspack_result()?
.await
.map_err(|err| internal_error!("Failed to call build module: {err}"))?
}

async fn finish_modules(
&self,
compilation: &mut rspack_core::Compilation,
Expand Down Expand Up @@ -586,6 +603,7 @@ impl JsHooksAdapter {
after_compile,
finish_modules,
finish_make,
build_module,
chunk_asset,
succeed_module,
still_valid_module,
Expand Down Expand Up @@ -626,6 +644,8 @@ impl JsHooksAdapter {
js_fn_into_theadsafe_fn!(after_compile, env);
let finish_make_tsfn: ThreadsafeFunction<JsCompilation, ()> =
js_fn_into_theadsafe_fn!(finish_make, env);
let build_module_tsfn: ThreadsafeFunction<JsModule, ()> =
js_fn_into_theadsafe_fn!(build_module, env);
let finish_modules_tsfn: ThreadsafeFunction<JsCompilation, ()> =
js_fn_into_theadsafe_fn!(finish_modules, env);
let context_module_before_resolve: ThreadsafeFunction<BeforeResolveData, Option<bool>> =
Expand Down Expand Up @@ -670,6 +690,7 @@ impl JsHooksAdapter {
normal_module_factory_resolve_for_scheme,
finish_modules_tsfn,
finish_make_tsfn,
build_module_tsfn,
chunk_asset_tsfn,
after_resolve,
succeed_module_tsfn,
Expand Down
1 change: 1 addition & 0 deletions crates/rspack_core/src/plugin/plugin_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ impl PluginDriver {
Ok(())
}

#[instrument(name = "plugin:build_module", skip_all)]
pub async fn build_module(&self, module: &mut dyn Module) -> Result<()> {
for plugin in &self.plugins {
plugin.build_module(module).await?;
Expand Down
12 changes: 5 additions & 7 deletions packages/rspack/src/compilation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
createFakeCompilationDependencies,
createFakeProcessAssetsHook
} from "./util/fake";
import { NormalizedJsModule, normalizeJsModule } from "./util/normalization";
import MergeCaller from "./util/MergeCaller";

export type AssetInfo = Partial<JsAssetInfo> & Record<string, any>;
Expand Down Expand Up @@ -90,6 +91,7 @@ export class Compilation {
processWarnings: tapable.SyncWaterfallHook<[Error[]]>;
succeedModule: tapable.SyncHook<[JsModule], undefined>;
stillValidModule: tapable.SyncHook<[JsModule], undefined>;
buildModule: tapable.SyncHook<[NormalizedJsModule]>;
};
options: RspackOptionsNormalized;
outputOptions: OutputNormalized;
Expand Down Expand Up @@ -125,7 +127,8 @@ export class Compilation {
chunkAsset: new tapable.SyncHook(["chunk", "filename"]),
processWarnings: new tapable.SyncWaterfallHook(["warnings"]),
succeedModule: new tapable.SyncHook(["module"]),
stillValidModule: new tapable.SyncHook(["module"])
stillValidModule: new tapable.SyncHook(["module"]),
buildModule: new tapable.SyncHook(["module"])
};
this.compiler = compiler;
this.resolverFactory = compiler.resolverFactory;
Expand Down Expand Up @@ -608,12 +611,7 @@ export class Compilation {
);

get modules() {
return this.getModules().map(item => {
return {
identifier: () => item.moduleIdentifier,
...item
};
});
return this.getModules().map(item => normalizeJsModule(item));
}

get chunks() {
Expand Down
13 changes: 11 additions & 2 deletions packages/rspack/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { WatchFileSystem } from "./util/fs";
import { getScheme } from "./util/scheme";
import Watching from "./watching";
import { NormalModule } from "./normalModule";
import { normalizeJsModule } from "./util/normalization";

class EntryPlugin {
constructor(
Expand Down Expand Up @@ -343,7 +344,8 @@ class Compiler {
contextModuleBeforeResolve:
this.#contextModuleBeforeResolve.bind(this),
succeedModule: this.#succeedModule.bind(this),
stillValidModule: this.#stillValidModule.bind(this)
stillValidModule: this.#stillValidModule.bind(this),
buildModule: this.#buildModule.bind(this)
},
createThreadsafeNodeFSFromRaw(this.outputFileSystem),
loaderContext => runLoader(loaderContext, this)
Expand Down Expand Up @@ -606,7 +608,8 @@ class Compiler {
beforeResolve: this.compilation.normalModuleFactory?.hooks.beforeResolve,
afterResolve: this.compilation.normalModuleFactory?.hooks.afterResolve,
succeedModule: this.compilation.hooks.succeedModule,
stillValidModule: this.compilation.hooks.stillValidModule
stillValidModule: this.compilation.hooks.stillValidModule,
buildModule: this.compilation.hooks.buildModule
};
for (const [name, hook] of Object.entries(hookMap)) {
if (hook?.taps.length === 0) {
Expand Down Expand Up @@ -637,6 +640,12 @@ class Compiler {
this.#updateDisabledHooks();
}

async #buildModule(module: binding.JsModule) {
const normalized = normalizeJsModule(module);
this.compilation.hooks.buildModule.call(normalized);
this.#updateDisabledHooks();
}

async #processAssets(stage: number) {
await this.compilation
.__internal_getProcessAssetsHookByStage(stage)
Expand Down
12 changes: 12 additions & 0 deletions packages/rspack/src/util/normalization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { JsModule } from "@rspack/binding";

export interface NormalizedJsModule extends JsModule {
identifier: () => string;
}

export function normalizeJsModule(m: JsModule): NormalizedJsModule {
return {
...m,
identifier: () => m.moduleIdentifier
};
}
1 change: 1 addition & 0 deletions packages/rspack/tests/configCases/hooks/build-module/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const a = 3;
5 changes: 5 additions & 0 deletions packages/rspack/tests/configCases/hooks/build-module/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { a } from "./a.js";

it("should compile successfully with build-module", () => {
expect(a).toBe(3);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { strict } = require("assert");
const pluginName = "plugin";

class Plugin {
apply(compiler) {
let identifiers = [];
compiler.hooks.compilation.tap(pluginName, compilation => {
compilation.hooks.buildModule.tap(pluginName, m => {
identifiers.push(m.identifier());
});
});
compiler.hooks.done.tap(pluginName, () => {
strict(identifiers.some(i => i.endsWith("index.js")));
strict(identifiers.some(i => i.endsWith("a.js")));
});
}
}

/**@type {import('@rspack/cli').Configuration}*/
module.exports = {
context: __dirname,
plugins: [new Plugin()]
};