Skip to content

Commit 24834f0

Browse files
yifancongCopilot
andauthored
fix: module reasons when the module has layer (#1418)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 08d67e7 commit 24834f0

4 files changed

Lines changed: 149 additions & 8 deletions

File tree

packages/core/src/build-utils/build/module-graph/webpack/transform.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ function appendDependency(
9191
const request = rawRequest ?? resolveRequest;
9292

9393
if (!module.getDependencyByRequest(request)) {
94-
const depModule = graph.getModuleByFile(resolveRequest)[0];
94+
const depLayer = resolvedWebpackModule.layer || undefined;
95+
const depModule = graph.getModuleByFile(resolveRequest, depLayer)[0];
9596

9697
if (depModule) {
9798
const dep = module.addDependency(

packages/graph/src/graph/module-graph/graph.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,17 @@ export class ModuleGraph implements SDK.ModuleGraphInstance {
324324
return this._moduleWebpackIdMap.get(id);
325325
}
326326

327-
getModuleByFile(file: string) {
328-
const similarModules = this.getModules().filter(
329-
(item) => item.path === file,
330-
);
331-
return similarModules || [];
327+
getModuleByFile(file: string, layer?: string) {
328+
const similarModules = this.getModules().filter((item) => {
329+
if (item.path !== file) {
330+
return false;
331+
}
332+
if (layer !== undefined) {
333+
return item.layer === layer;
334+
}
335+
return true;
336+
});
337+
return similarModules;
332338
}
333339

334340
addModule(...modules: SDK.ModuleInstance[]) {

packages/graph/tests/module-graph.test.ts

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'path';
22
import { expect, describe, it } from '@rstest/core';
3-
import type { SDK } from '@rsdoctor/types';
3+
import { SDK } from '@rsdoctor/types';
44
import { Module, ModuleGraph, PackageGraph } from '../src/graph';
55
// TODO: simplify the module-graph-basic.json data size.
66
const resolveFixture = (...paths: string[]) => {
@@ -97,4 +97,138 @@ describe('module graph', () => {
9797

9898
expect(_moduleGraph.toCodeData()).toMatchSnapshot();
9999
});
100+
101+
it('getModuleByFile should return modules by file path', async () => {
102+
const moduleGraph = new ModuleGraph();
103+
const filePath = '/path/to/module.js';
104+
105+
// Add module without layer
106+
const module1 = new Module('1', filePath);
107+
moduleGraph.addModule(module1);
108+
109+
// Add module with different file path
110+
const module2 = new Module('2', '/path/to/other.js');
111+
moduleGraph.addModule(module2);
112+
113+
const result = moduleGraph.getModuleByFile(filePath);
114+
expect(result.length).toBe(1);
115+
expect(result[0].id).toBe(module1.id);
116+
expect(result[0].path).toBe(filePath);
117+
});
118+
119+
it('getModuleByFile should return all modules when multiple modules have same path but different layers', async () => {
120+
const moduleGraph = new ModuleGraph();
121+
const filePath = '/path/to/module.js';
122+
123+
// Add module with layer 'legacy'
124+
const moduleLegacy = new Module(
125+
'1',
126+
filePath,
127+
false,
128+
SDK.ModuleKind.Normal,
129+
undefined,
130+
'legacy',
131+
);
132+
moduleGraph.addModule(moduleLegacy);
133+
134+
// Add module with layer 'modern'
135+
const moduleModern = new Module(
136+
'2',
137+
filePath,
138+
false,
139+
SDK.ModuleKind.Normal,
140+
undefined,
141+
'modern',
142+
);
143+
moduleGraph.addModule(moduleModern);
144+
145+
// Add module without layer
146+
const moduleNoLayer = new Module('3', filePath);
147+
moduleGraph.addModule(moduleNoLayer);
148+
149+
// When layer is not specified, should return all matching modules
150+
const result = moduleGraph.getModuleByFile(filePath);
151+
expect(result.length).toBe(3);
152+
expect(result.map((m) => m.id).sort()).toEqual(
153+
[moduleLegacy.id, moduleModern.id, moduleNoLayer.id].sort(),
154+
);
155+
});
156+
157+
it('getModuleByFile should filter by layer when layer parameter is provided', async () => {
158+
const moduleGraph = new ModuleGraph();
159+
const filePath = '/path/to/module.js';
160+
161+
// Add module with layer 'legacy'
162+
const moduleLegacy = new Module(
163+
'1',
164+
filePath,
165+
false,
166+
SDK.ModuleKind.Normal,
167+
undefined,
168+
'legacy',
169+
);
170+
moduleGraph.addModule(moduleLegacy);
171+
172+
// Add module with layer 'modern'
173+
const moduleModern = new Module(
174+
'2',
175+
filePath,
176+
false,
177+
SDK.ModuleKind.Normal,
178+
undefined,
179+
'modern',
180+
);
181+
moduleGraph.addModule(moduleModern);
182+
183+
// Add module without layer
184+
const moduleNoLayer = new Module('3', filePath);
185+
moduleGraph.addModule(moduleNoLayer);
186+
187+
// When layer 'legacy' is specified, should return only legacy module
188+
const resultLegacy = moduleGraph.getModuleByFile(filePath, 'legacy');
189+
expect(resultLegacy.length).toBe(1);
190+
expect(resultLegacy[0].id).toBe(moduleLegacy.id);
191+
expect(resultLegacy[0].layer).toBe('legacy');
192+
193+
// When layer 'modern' is specified, should return only modern module
194+
const resultModern = moduleGraph.getModuleByFile(filePath, 'modern');
195+
expect(resultModern.length).toBe(1);
196+
expect(resultModern[0].id).toBe(moduleModern.id);
197+
expect(resultModern[0].layer).toBe('modern');
198+
199+
// When layer is empty string, should return only module without layer
200+
const resultNoLayer = moduleGraph.getModuleByFile(filePath, '');
201+
expect(resultNoLayer.length).toBe(1);
202+
expect(resultNoLayer[0].id).toBe(moduleNoLayer.id);
203+
expect(resultNoLayer[0].layer).toBe('');
204+
});
205+
206+
it('getModuleByFile should return empty array when no matching modules found', async () => {
207+
const moduleGraph = new ModuleGraph();
208+
const module = new Module('1', '/path/to/module.js');
209+
moduleGraph.addModule(module);
210+
211+
const result = moduleGraph.getModuleByFile('/path/to/nonexistent.js');
212+
expect(result).toEqual([]);
213+
});
214+
215+
it('getModuleByFile should return empty array when layer does not match', async () => {
216+
const moduleGraph = new ModuleGraph();
217+
const filePath = '/path/to/module.js';
218+
219+
// Add module with layer 'legacy'
220+
const moduleLegacy = new Module(
221+
'1',
222+
filePath,
223+
false,
224+
SDK.ModuleKind.Normal,
225+
undefined,
226+
'legacy',
227+
);
228+
moduleGraph.addModule(moduleLegacy);
229+
230+
// Query for 'modern' layer should return empty array
231+
const result = moduleGraph.getModuleByFile(filePath, 'modern');
232+
expect(result).toEqual([]);
233+
});
100234
});

packages/types/src/sdk/module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ export interface ModuleGraphInstance {
311311
getModuleByWebpackId(webpackId: string): ModuleInstance | undefined;
312312

313313
/** Get module by path */
314-
getModuleByFile(file: string): ModuleInstance[] | [];
314+
getModuleByFile(file: string, layer?: string): ModuleInstance[] | [];
315315

316316
/** Add Module */
317317
addModule(module: ModuleInstance): void;

0 commit comments

Comments
 (0)