Skip to content

Commit c1e945f

Browse files
authored
feat: chunk graph get module hash (#9242)
1 parent d688f4d commit c1e945f

File tree

11 files changed

+89
-21
lines changed

11 files changed

+89
-21
lines changed

crates/node_binding/binding.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export declare class JsChunkGraph {
7878
getChunkModulesIterableBySourceType(chunk: JsChunk, sourceType: string): JsModule[]
7979
getModuleChunks(module: JsModule): JsChunk[]
8080
getModuleId(jsModule: JsModule): string | null
81+
getModuleHash(module: JsModule, runtime: string | string[] | undefined): string | null
8182
getBlockChunkGroup(jsBlock: JsDependenciesBlock): JsChunkGroup | null
8283
}
8384

crates/rspack_binding_values/src/chunk_graph.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use std::ptr::NonNull;
1+
use std::{ptr::NonNull, sync::Arc};
22

3-
use napi::Result;
3+
use napi::{Either, Result};
44
use napi_derive::napi;
55
use rspack_core::{ChunkGraph, Compilation, SourceType};
66

77
use crate::{
88
JsChunk, JsChunkGroupWrapper, JsChunkWrapper, JsDependenciesBlock, JsModule, JsModuleWrapper,
9+
JsRuntimeSpec,
910
};
1011

1112
#[napi]
@@ -141,6 +142,25 @@ impl JsChunkGraph {
141142
)
142143
}
143144

145+
#[napi(ts_args_type = "module: JsModule, runtime: string | string[] | undefined")]
146+
pub fn get_module_hash(
147+
&self,
148+
js_module: &JsModule,
149+
js_runtime: JsRuntimeSpec,
150+
) -> napi::Result<Option<&str>> {
151+
let compilation = self.as_ref()?;
152+
let Some(runtime) = js_runtime.map(|js_runtime| match js_runtime {
153+
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
154+
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
155+
}) else {
156+
return Ok(None);
157+
};
158+
Ok(
159+
ChunkGraph::get_module_hash(compilation, js_module.identifier, &runtime)
160+
.map(|hash| hash.encoded()),
161+
)
162+
}
163+
144164
#[napi(ts_return_type = "JsChunkGroup | null")]
145165
pub fn get_block_chunk_group(
146166
&self,

crates/rspack_binding_values/src/dependency.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,6 @@ impl ToNapiValue for JsDependencyWrapper {
221221
}
222222
}
223223

224-
pub type JsRuntimeSpec = Either<String, Vec<String>>;
225-
226224
#[napi(object)]
227225
pub struct RawDependency {
228226
pub request: String,

crates/rspack_binding_values/src/exports_info.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,20 @@ impl JsExportsInfo {
3737
#[napi]
3838
impl JsExportsInfo {
3939
#[napi(ts_args_type = "runtime: string | string[] | undefined")]
40-
pub fn is_used(&self, js_runtime: Option<JsRuntimeSpec>) -> napi::Result<bool> {
40+
pub fn is_used(&self, js_runtime: JsRuntimeSpec) -> napi::Result<bool> {
4141
let module_graph = self.as_ref()?;
4242
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
43-
Either::A(str) => vec![str].into_iter().map(Arc::from).collect(),
43+
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
4444
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
4545
});
4646
Ok(self.exports_info.is_used(&module_graph, runtime.as_ref()))
4747
}
4848

4949
#[napi(ts_args_type = "runtime: string | string[] | undefined")]
50-
pub fn is_module_used(&self, js_runtime: Option<JsRuntimeSpec>) -> napi::Result<bool> {
50+
pub fn is_module_used(&self, js_runtime: JsRuntimeSpec) -> napi::Result<bool> {
5151
let module_graph = self.as_ref()?;
5252
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
53-
Either::A(str) => vec![str].into_iter().map(Arc::from).collect(),
53+
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
5454
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
5555
});
5656
Ok(
@@ -61,13 +61,10 @@ impl JsExportsInfo {
6161
}
6262

6363
#[napi(ts_args_type = "runtime: string | string[] | undefined")]
64-
pub fn set_used_in_unknown_way(
65-
&mut self,
66-
js_runtime: Option<JsRuntimeSpec>,
67-
) -> napi::Result<bool> {
64+
pub fn set_used_in_unknown_way(&mut self, js_runtime: JsRuntimeSpec) -> napi::Result<bool> {
6865
let mut module_graph = self.as_mut()?;
6966
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
70-
Either::A(str) => vec![str].into_iter().map(Arc::from).collect(),
67+
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
7168
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
7269
});
7370
Ok(
@@ -84,15 +81,15 @@ impl JsExportsInfo {
8481
pub fn get_used(
8582
&self,
8683
js_name: Either<String, Vec<String>>,
87-
js_runtime: Option<JsRuntimeSpec>,
84+
js_runtime: JsRuntimeSpec,
8885
) -> napi::Result<u32> {
8986
let module_graph = self.as_ref()?;
9087
let name = match js_name {
9188
Either::A(s) => UsedName::Str(s.into()),
9289
Either::B(v) => UsedName::Vec(v.into_iter().map(Into::into).collect::<Vec<_>>()),
9390
};
9491
let runtime: Option<RuntimeSpec> = js_runtime.map(|js_rt| match js_rt {
95-
Either::A(str) => vec![str].into_iter().map(Arc::from).collect(),
92+
Either::A(str) => std::iter::once(str).map(Arc::from).collect(),
9693
Either::B(vec) => vec.into_iter().map(Arc::from).collect(),
9794
});
9895
Ok(

crates/rspack_binding_values/src/runtime.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::sync::LazyLock;
22

33
use cow_utils::CowUtils;
44
use heck::{ToLowerCamelCase, ToSnakeCase};
5+
use napi::Either;
56
use napi_derive::napi;
67
use rspack_core::RuntimeGlobals;
78
use rspack_plugin_runtime::{
@@ -235,3 +236,5 @@ impl From<RuntimeModuleChunkWrapper> for JsChunkWrapper {
235236
}
236237
}
237238
}
239+
240+
pub type JsRuntimeSpec = Option<Either<String, Vec<String>>>;

packages/rspack-test-tools/tests/configCases/chunk-graph/get-module-hash/index.js

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Plugin {
2+
apply(compiler) {
3+
compiler.hooks.compilation.tap("Test", compilation => {
4+
compilation.hooks.processAssets.tap("Test", () => {
5+
const module = Array.from(compilation.modules)[0];
6+
const moduleHash = compilation.chunkGraph.getModuleHash(module, "main");
7+
expect(moduleHash).toBeTruthy();
8+
});
9+
});
10+
}
11+
}
12+
13+
/** @type {import("@rspack/core").Configuration} */
14+
module.exports = {
15+
target: "web",
16+
node: false,
17+
entry: {
18+
main: "./index.js"
19+
},
20+
output: {
21+
filename: "[name].js"
22+
},
23+
optimization: {
24+
sideEffects: false
25+
},
26+
plugins: [new Plugin()]
27+
};

packages/rspack/etc/core.api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,8 @@ class ChunkGraph {
547547
// (undocumented)
548548
getModuleChunksIterable(module: Module): Iterable<Chunk>;
549549
// (undocumented)
550+
getModuleHash(module: Module, runtime: RuntimeSpec): string | null;
551+
// (undocumented)
550552
getModuleId(module: Module): string | null;
551553
// (undocumented)
552554
getNumberOfEntryModules(chunk: Chunk): number;
@@ -10081,7 +10083,7 @@ const RuntimePluginImpl: {
1008110083
type RuntimePlugins = string[];
1008210084

1008310085
// @public (undocumented)
10084-
type RuntimeSpec = string | string[] | undefined;
10086+
type RuntimeSpec = string | Set<string> | undefined;
1008510087

1008610088
// @public (undocumented)
1008710089
type SafeParseError<Input> = {

packages/rspack/src/ChunkGraph.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { JsChunkGraph } from "@rspack/binding";
2+
import type { RuntimeSpec } from "./util/runtime";
23

34
import { Chunk } from "./Chunk";
45
import { ChunkGroup } from "./ChunkGroup";
56
import { DependenciesBlock } from "./DependenciesBlock";
67
import { Module } from "./Module";
8+
import { toJsRuntimeSpec } from "./util/runtime";
79

810
export class ChunkGraph {
911
#inner: JsChunkGraph;
@@ -72,6 +74,13 @@ export class ChunkGraph {
7274
return this.#inner.getModuleId(Module.__to_binding(module));
7375
}
7476

77+
getModuleHash(module: Module, runtime: RuntimeSpec): string | null {
78+
return this.#inner.getModuleHash(
79+
Module.__to_binding(module),
80+
toJsRuntimeSpec(runtime)
81+
);
82+
}
83+
7584
getBlockChunkGroup(depBlock: DependenciesBlock): ChunkGroup | null {
7685
const binding = this.#inner.getBlockChunkGroup(
7786
DependenciesBlock.__to_binding(depBlock)

packages/rspack/src/ExportsInfo.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { JsExportsInfo } from "@rspack/binding";
2+
import type { RuntimeSpec } from "./util/runtime";
23

3-
type RuntimeSpec = string | string[] | undefined;
4+
import { toJsRuntimeSpec } from "./util/runtime";
45

56
/**
67
* Unused: 0
@@ -23,18 +24,18 @@ export class ExportsInfo {
2324
}
2425

2526
isUsed(runtime: RuntimeSpec): boolean {
26-
return this.#inner.isUsed(runtime);
27+
return this.#inner.isUsed(toJsRuntimeSpec(runtime));
2728
}
2829

2930
isModuleUsed(runtime: RuntimeSpec): boolean {
30-
return this.#inner.isModuleUsed(runtime);
31+
return this.#inner.isModuleUsed(toJsRuntimeSpec(runtime));
3132
}
3233

3334
setUsedInUnknownWay(runtime: RuntimeSpec): boolean {
34-
return this.#inner.setUsedInUnknownWay(runtime);
35+
return this.#inner.setUsedInUnknownWay(toJsRuntimeSpec(runtime));
3536
}
3637

3738
getUsed(name: string | string[], runtime: RuntimeSpec): UsageStateType {
38-
return this.#inner.getUsed(name, runtime);
39+
return this.#inner.getUsed(name, toJsRuntimeSpec(runtime));
3940
}
4041
}

0 commit comments

Comments
 (0)