Skip to content

Commit f65d1ff

Browse files
committed
Make filter-before-parse observable; keep parser diagnostic; harden resolutions fallback
- Inject parse as a jest.fn so a test asserts the node_modules/virtual/out-of-root modules never reach the parser. Deleting the guard now fails a test instead of silently costing a parse per module. - Include the parser's own message in the fail-closed error; an actionable error that hides the syntax error is only half useful. - Branch importedIdResolutions on .length rather than nullishness. Rolldown omits the property entirely so ?? works today, but a bundler reporting it as [] with a populated importedIds would silently yield zero static dependencies.
1 parent c207499 commit f65d1ff

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

packages/plugins/apps/src/vite/backend-module-graph-collector.test.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,27 @@ const getModuleParsedHook = (collector: ReturnType<typeof createBackendModuleGra
2020
throw new Error('Expected "moduleParsed" to be a function hook.');
2121
}
2222

23-
return (moduleInfo: object) => Reflect.apply(hook, { parse: parseAst }, [moduleInfo]);
23+
const parse = jest.fn(parseAst);
24+
const callHook = (moduleInfo: object) => Reflect.apply(hook, { parse }, [moduleInfo]);
25+
26+
return { callHook, parse };
2427
};
2528

2629
const getEmit = (collector: ReturnType<typeof createBackendModuleGraphCollector>) => {
27-
const callHook = getModuleParsedHook(collector);
30+
const { callHook, parse } = getModuleParsedHook(collector);
2831

29-
return (moduleInfo: FakeModuleInfo, importedIds: string[] = []) => {
32+
const emit = (moduleInfo: FakeModuleInfo, importedIds: string[] = []) => {
3033
const importedIdResolutions = importedIds.map((id) => ({ id }));
3134
callHook({ ...moduleInfo, importedIds, importedIdResolutions });
3235
};
36+
37+
return { emit, parse };
3338
};
3439

3540
describe('Backend Functions - backend module graph collector', () => {
3641
test('Should collect parsed local module records from moduleParsed hooks', () => {
3742
const collector = createBackendModuleGraphCollector('/project');
38-
const emit = getEmit(collector);
43+
const { emit, parse } = getEmit(collector);
3944

4045
emit(
4146
{
@@ -67,11 +72,15 @@ describe('Backend Functions - backend module graph collector', () => {
6772
},
6873
],
6974
});
75+
// Filtering happens before the parse, so the skipped modules above never
76+
// reach the parser. Without that ordering every `node_modules` module in
77+
// the backend graph would be parsed just to be discarded.
78+
expect(parse).toHaveBeenCalledTimes(1);
7079
});
7180

7281
test('Should collect records under a bundler that does not support ModuleInfo#ast', () => {
7382
const collector = createBackendModuleGraphCollector('/project');
74-
const callHook = getModuleParsedHook(collector);
83+
const { callHook } = getModuleParsedHook(collector);
7584

7685
// Rolldown, Vite 8's default bundler, keeps `ast` on its Rollup-compat
7786
// object but stubs the getter to throw. Reading the property at all is

packages/plugins/apps/src/vite/backend-module-graph-collector.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,12 @@ export function createBackendModuleGraphCollector(buildRoot: string): BackendMod
5858
let parsed;
5959
try {
6060
parsed = this.parse(moduleInfo.code);
61-
} catch {
62-
throw unsupportedModuleGraphDependency(moduleId, 'unparseable module source');
61+
} catch (error) {
62+
const reason = error instanceof Error ? error.message : String(error);
63+
throw unsupportedModuleGraphDependency(
64+
moduleId,
65+
`unparseable module source (${reason})`,
66+
);
6367
}
6468

6569
const record = createParsedModuleRecord(
@@ -88,7 +92,11 @@ function normalizeViteModuleId(id: string): string {
8892
}
8993

9094
function getStaticDependencyIds(moduleInfo: ModuleInfo): string[] {
91-
return moduleInfo.importedIdResolutions?.map(({ id }) => id) ?? [...moduleInfo.importedIds];
95+
const resolutions = moduleInfo.importedIdResolutions;
96+
if (resolutions?.length) {
97+
return resolutions.map(({ id }) => id);
98+
}
99+
return [...moduleInfo.importedIds];
92100
}
93101

94102
function isViteVirtualModuleId(id: string): boolean {

0 commit comments

Comments
 (0)