Skip to content

Commit ee538d6

Browse files
committed
feat: supprot rspack's resolver analysis
1 parent e068194 commit ee538d6

File tree

9 files changed

+144
-237
lines changed

9 files changed

+144
-237
lines changed

examples/modern-minimal/modern.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default defineConfig({
3636
},
3737
},
3838
disableClientServer: !process.env.ENABLE_CLIENT_SERVER,
39-
features: ['bundle', 'plugins', 'loader'],
39+
features: ['bundle', 'plugins', 'loader', 'resolver'],
4040
},
4141
]);
4242
},

examples/rsbuild-minimal/rsbuild.config.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ export default defineConfig({
1010
chain.plugin('Rsdoctor').use(RsdoctorRspackPlugin, [
1111
{
1212
disableClientServer: !process.env.ENABLE_CLIENT_SERVER,
13+
features: ['resolver', 'bundle', 'plugins', 'loader'],
1314
output: {
14-
mode: 'brief',
15-
options: {
16-
type: ['json', 'html'],
17-
},
18-
reportCodeType: {
19-
noCode: true,
20-
},
15+
// mode: 'brief',
16+
// options: {
17+
// type: ['json', 'html'],
18+
// },
19+
// reportCodeType: {
20+
// noCode: true,
21+
// },
2122
},
2223
linter: {
2324
level: 'Error',

packages/core/src/inner-plugins/plugins/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from './bundle';
88
export * from './ensureModulesChunkGraph';
99
export * from './rules';
1010
export * from './bundleTagPlugin';
11+
export * from './resolver';
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { Manifest, Plugin, SDK } from '@rsdoctor/types';
2+
import { Time } from '@rsdoctor/utils/common';
3+
import { InternalBasePlugin } from './base';
4+
import type { Compiler as WebpackCompiler } from 'webpack';
5+
6+
export class InternalResolverPlugin<
7+
T extends Plugin.BaseCompiler,
8+
> extends InternalBasePlugin<T> {
9+
public readonly name = 'resolver';
10+
11+
protected resolveDataMap = new Map<
12+
string,
13+
{ startAt: number; startHRTime: [number, number]; request: string }
14+
>();
15+
16+
public apply(compiler: T) {
17+
// resolver depends on module graph
18+
this.scheduler.ensureModulesChunksGraphApplied(compiler);
19+
compiler.hooks.normalModuleFactory.tap(
20+
this.tapPostOptions,
21+
this.handleNormalModuleFactory,
22+
);
23+
24+
// add resolver page to client
25+
this.sdk.addClientRoutes([
26+
Manifest.RsdoctorManifestClientRoutes.ModuleResolve,
27+
]);
28+
}
29+
30+
protected handleNormalModuleFactory = (
31+
normalModuleFactory:
32+
| Plugin.RspackNormalModuleFactory
33+
| ReturnType<WebpackCompiler['createNormalModuleFactory']>,
34+
) => {
35+
// Hook into beforeResolve to capture the start time
36+
normalModuleFactory.hooks.beforeResolve.tap(
37+
this.tapPostOptions,
38+
(resolveData: any) => {
39+
if (!resolveData) return;
40+
41+
const issuer =
42+
resolveData.contextInfo?.issuer || resolveData.context || '';
43+
const request = resolveData.request;
44+
45+
if (issuer && request) {
46+
const key = `${issuer}::${request}`;
47+
this.resolveDataMap.set(key, {
48+
startAt: Date.now(),
49+
startHRTime: process.hrtime(),
50+
request,
51+
});
52+
}
53+
},
54+
);
55+
56+
// Hook into afterResolve to capture the result and report
57+
normalModuleFactory.hooks.afterResolve.tap(
58+
this.tapPostOptions,
59+
(resolveData: any) => {
60+
if (!resolveData) return;
61+
62+
const issuer =
63+
resolveData.contextInfo?.issuer || resolveData.context || '';
64+
const request = resolveData.request;
65+
const result =
66+
resolveData.createData?.resource ||
67+
resolveData.resourceResolveData?.path;
68+
69+
if (issuer && request) {
70+
const key = `${issuer}::${request}`;
71+
const startData = this.resolveDataMap.get(key);
72+
73+
if (startData) {
74+
const data: SDK.PathResolverSuccessData = {
75+
isEntry: Boolean(issuer),
76+
issuerPath: issuer,
77+
request: startData.request,
78+
startAt: startData.startAt,
79+
endAt: Time.getCurrentTimestamp(
80+
startData.startAt,
81+
startData.startHRTime,
82+
),
83+
result: result || '',
84+
pid: process.pid,
85+
ppid: process.ppid,
86+
};
87+
88+
this.sdk.reportResolver([data]);
89+
this.resolveDataMap.delete(key);
90+
}
91+
}
92+
},
93+
);
94+
};
95+
}

packages/rspack-plugin/src/plugin.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
InternalErrorReporterPlugin,
77
InternalLoaderPlugin,
88
InternalPluginsPlugin,
9+
InternalResolverPlugin,
910
InternalRulesPlugin,
1011
InternalSummaryPlugin,
1112
normalizeRspackUserOptions,
@@ -154,6 +155,12 @@ export class RsdoctorRspackPlugin<Rules extends Linter.ExtendRuleData[]>
154155
).apply(compiler);
155156
}
156157

158+
if (this.options.features.resolver) {
159+
new InternalResolverPlugin<Plugin.BaseCompilerType<'rspack'>>(
160+
this,
161+
).apply(compiler);
162+
}
163+
157164
if (this.options.features.resolver) {
158165
logger.info(
159166
chalk.yellow(

packages/types/src/plugin/rspack.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import type { RsdoctorPluginData } from '@rspack/core';
1+
// biome-ignore assist/source/organizeImports: <explanation>
2+
import type {
3+
RsdoctorPluginData,
4+
NormalModuleFactory,
5+
LoaderDefinitionFunction,
6+
ModuleGraph,
7+
Dependency,
8+
} from '@rspack/core';
9+
export type RspackNormalModuleFactory = NormalModuleFactory;
210

311
export type RspackNativeAsset = RsdoctorPluginData.RsdoctorAsset;
412
export type RspackNativeChunkGraph = RsdoctorPluginData.RsdoctorChunkGraph;
@@ -28,3 +36,21 @@ export type RspackNativeModuleSourcePatch =
2836
import rspack from '@rspack/core';
2937

3038
export type RspackExportsExperiments = typeof rspack.experiments;
39+
40+
export type RspackSourceMapInput = Parameters<LoaderDefinitionFunction>[1];
41+
// export type SourceMap = Exclude<SourceMapInput, string | undefined>;
42+
export type RspackEntryPoint = boolean | 'auto';
43+
export interface RspackExportInfo {
44+
used: boolean;
45+
provideInfo: boolean | null | undefined;
46+
useInfo: boolean | null | undefined;
47+
canMangle: boolean;
48+
}
49+
50+
export type RspackExportsInfo = ReturnType<ModuleGraph['getExportsInfo']>;
51+
52+
export interface RspackHarmonyImportSpecifierDependency extends Dependency {
53+
getIds(graph: ModuleGraph): string[];
54+
name: string;
55+
userRequest: string;
56+
}

packages/types/src/sdk/instance.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { RuntimeContext, RuntimeContextOptions } from './context';
1313
import { Hooks } from './hooks';
1414
import { ChunkGraphInstance } from './chunk';
1515
import { RsdoctorServerInstance } from './server';
16-
import { PlainObject } from '@/common';
17-
import { BriefModeOptions } from '@/config';
18-
import { EmoCheckData } from '@/emo';
16+
import { PlainObject } from '../common';
17+
import { BriefModeOptions } from '../config';
18+
import { EmoCheckData } from '../emo';
1919
import { SummaryData } from './summary';
2020
import { ConfigData } from './config';
2121

packages/webpack-plugin/src/plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
InternalLoaderPlugin,
99
InternalPluginsPlugin,
1010
InternalProgressPlugin,
11+
InternalResolverPlugin,
1112
InternalRulesPlugin,
1213
InternalSummaryPlugin,
1314
normalizeUserConfig,
@@ -23,7 +24,6 @@ import { Loader } from '@rsdoctor/utils/common';
2324
import { logger } from '@rsdoctor/utils/logger';
2425
import type { Compiler } from 'webpack';
2526
import { pluginTapName, pluginTapPostOptions } from './constants';
26-
import { InternalResolverPlugin } from './plugins/resolver';
2727
import path from 'path';
2828

2929
export class RsdoctorWebpackPlugin<Rules extends Linter.ExtendRuleData[]>
@@ -105,7 +105,7 @@ export class RsdoctorWebpackPlugin<Rules extends Linter.ExtendRuleData[]>
105105
}
106106

107107
if (this.options.features.resolver) {
108-
new InternalResolverPlugin(this).apply(compiler);
108+
new InternalResolverPlugin<Compiler>(this).apply(compiler);
109109
}
110110

111111
if (this.options.features.plugins) {

0 commit comments

Comments
 (0)