Skip to content

Commit

Permalink
test: lazy create stats in runner (#9469)
Browse files Browse the repository at this point in the history
  • Loading branch information
LingyuCoder authored Feb 26, 2025
1 parent d6958b9 commit 912f2b3
Show file tree
Hide file tree
Showing 35 changed files with 98 additions and 60 deletions.
14 changes: 9 additions & 5 deletions packages/rspack-test-tools/etc/test-tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ export class BasicRunnerFactory<T extends ECompilerType> implements TRunnerFacto
// (undocumented)
create(file: string, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
// (undocumented)
protected createRunner(file: string, stats: TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
protected createRunner(file: string, stats: () => TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
// (undocumented)
protected createStatsGetter(): () => TCompilerStatsCompilation<T>;
// (undocumented)
protected getRunnerKey(file: string): string;
// (undocumented)
Expand Down Expand Up @@ -653,7 +655,7 @@ export interface IBasicRunnerOptions<T extends ECompilerType> {
// (undocumented)
source: string;
// (undocumented)
stats?: TCompilerStatsCompilation<T>;
stats?: () => TCompilerStatsCompilation<T>;
// (undocumented)
testConfig: TTestConfig<T>;
}
Expand Down Expand Up @@ -1172,7 +1174,7 @@ export class JSDOMWebRunner<T extends ECompilerType = ECompilerType.Rspack> exte
// @public (undocumented)
export class MultipleRunnerFactory<T extends ECompilerType> extends BasicRunnerFactory<T> {
// (undocumented)
protected createRunner(file: string, stats: TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
protected createRunner(file: string, stats: () => TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
// (undocumented)
protected getFileIndexHandler(file: string): {
getIndex: () => number[];
Expand Down Expand Up @@ -1217,7 +1219,7 @@ export class NormalRunner<T extends ECompilerType = ECompilerType.Rspack> extend
// @public (undocumented)
export class NormalRunnerFactory<T extends ECompilerType> extends BasicRunnerFactory<T> {
// (undocumented)
protected createRunner(file: string, stats: TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
protected createRunner(file: string, stats: () => TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
}

// @public (undocumented)
Expand Down Expand Up @@ -1636,7 +1638,9 @@ export class WatchRunner<T extends ECompilerType = ECompilerType.Rspack> extends
// @public (undocumented)
export class WatchRunnerFactory<T extends ECompilerType> extends BasicRunnerFactory<T> {
// (undocumented)
protected createRunner(file: string, stats: TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
protected createRunner(file: string, stats: () => TCompilerStatsCompilation<T>, compilerOptions: TCompilerOptions<T>, env: ITestEnv): ITestRunner;
// (undocumented)
protected createStatsGetter(): () => TCompilerStatsCompilation<T>;
// (undocumented)
protected getRunnerKey(file: string): string;
}
Expand Down
30 changes: 24 additions & 6 deletions packages/rspack-test-tools/src/runner/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ export class BasicRunnerFactory<T extends ECompilerType>
protected context: ITestContext
) {}

protected createStatsGetter() {
const compiler = this.context.getCompiler<T>(this.name);
const statsGetter = (() => {
let cached: TCompilerStatsCompilation<T> | null = null;
return () => {
if (cached) {
return cached;
}
cached = compiler.getStats()!.toJson({
errorDetails: true
});
return cached;
};
})();
return statsGetter;
}

create(
file: string,
compilerOptions: TCompilerOptions<T>,
Expand All @@ -29,11 +46,12 @@ export class BasicRunnerFactory<T extends ECompilerType>
if (exists) {
return exists;
}
const compiler = this.context.getCompiler<T>(this.name);
const stats = compiler.getStats()!.toJson({
errorDetails: true
});
const runner = this.createRunner(file, stats, compilerOptions, env);
const runner = this.createRunner(
file,
this.createStatsGetter(),
compilerOptions,
env
);
this.context.setRunner(key, runner);
return runner;
}
Expand All @@ -44,7 +62,7 @@ export class BasicRunnerFactory<T extends ECompilerType>

protected createRunner(
file: string,
stats: TCompilerStatsCompilation<T>,
stats: () => TCompilerStatsCompilation<T>,
compilerOptions: TCompilerOptions<T>,
env: ITestEnv
): ITestRunner {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-test-tools/src/runner/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class CacheRunnerFactory<
this.context.getValue(this.name, "documentType") ||
EDocumentType.JSDOM,
env,
stats,
stats: this.createStatsGetter(),
cachable: false,
name: this.name,
runInNewContext: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-test-tools/src/runner/hot-step.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class HotStepRunnerFactory<
dom:
this.context.getValue(this.name, "documentType") || EDocumentType.JSDOM,
env,
stats,
stats: this.createStatsGetter(),
name: this.name,
runInNewContext: false,
testConfig: {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-test-tools/src/runner/hot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class HotRunnerFactory<
dom:
this.context.getValue(this.name, "documentType") || EDocumentType.JSDOM,
env,
stats,
stats: this.createStatsGetter(),
name: this.name,
runInNewContext: false,
testConfig: {
Expand Down
4 changes: 2 additions & 2 deletions packages/rspack-test-tools/src/runner/multiple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class MultipleRunnerFactory<

protected createRunner(
file: string,
stats: TCompilerStatsCompilation<T>,
stats: () => TCompilerStatsCompilation<T>,
compilerOptions: TCompilerOptions<T>,
env: ITestEnv
): ITestRunner {
Expand All @@ -29,7 +29,7 @@ export class MultipleRunnerFactory<
const [index] = getIndex();
const runner = super.createRunner(
file,
stats.children![index],
() => stats().children![index],
multiCompilerOptions[index],
env
);
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-test-tools/src/runner/normal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class NormalRunnerFactory<
> extends BasicRunnerFactory<T> {
protected createRunner(
file: string,
stats: TCompilerStatsCompilation<T>,
stats: () => TCompilerStatsCompilation<T>,
compilerOptions: TCompilerOptions<T>,
env: ITestEnv
): ITestRunner {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-test-tools/src/runner/runner/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const cached = new Map<string, TBasicRunnerFile>();

export interface IBasicRunnerOptions<T extends ECompilerType> {
env: ITestEnv;
stats?: TCompilerStatsCompilation<T>;
stats?: () => TCompilerStatsCompilation<T>;
name: string;
runInNewContext?: boolean;
testConfig: TTestConfig<T>;
Expand Down
12 changes: 5 additions & 7 deletions packages/rspack-test-tools/src/runner/runner/cjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ export class CommonJsRunner<
},
...this._options.env
};
if (this._options.stats) {
baseModuleScope.__STATS__ = this._options.stats;
}
return baseModuleScope;
}

Expand Down Expand Up @@ -120,15 +117,16 @@ export class CommonJsRunner<
);

if (this._options.testConfig.moduleScope) {
this._options.testConfig.moduleScope(
currentModuleScope,
this._options.stats
);
this._options.testConfig.moduleScope(currentModuleScope);
}

if (!this._options.runInNewContext) {
file.content = `Object.assign(global, _globalAssign);\n ${file.content}`;
}
if (file.content.includes("__STATS__") && this._options.stats) {
currentModuleScope.__STATS__ = this._options.stats();
}

const args = Object.keys(currentModuleScope);
const argValues = args.map(arg => currentModuleScope[arg]);
const code = `(function(${args.join(", ")}) {
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-test-tools/src/runner/runner/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class WatchRunner<
moduleScope.document = this.globalContext!.document;
moduleScope.STATE = this._watchOptions.state;
moduleScope.WATCH_STEP = this._watchOptions.stepName;
moduleScope.STATS_JSON = this._options.stats;
moduleScope.__STATS__ = this._options.stats;
return moduleScope;
}

Expand Down
1 change: 0 additions & 1 deletion packages/rspack-test-tools/src/runner/runner/web/jsdom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ export class JSDOMWebRunner<
}
};
};
moduleScope.STATS = moduleScope.__STATS__;
return moduleScope;
}

Expand Down
21 changes: 20 additions & 1 deletion packages/rspack-test-tools/src/runner/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,28 @@ export class WatchRunnerFactory<
);
return `${this.name}-${stepName}`;
}

protected createStatsGetter() {
const compiler = this.context.getCompiler<T>(this.name);
const stepName: string = this.context.getValue(this.name, "watchStepName")!;
const statsGetter = (() => {
const cached: Record<string, TCompilerStatsCompilation<T>> = {};
return () => {
if (cached[stepName]) {
return cached[stepName];
}
cached[stepName] = compiler.getStats()!.toJson({
errorDetails: true
});
return cached[stepName];
};
})();
return statsGetter;
}

protected createRunner(
file: string,
stats: TCompilerStatsCompilation<T>,
stats: () => TCompilerStatsCompilation<T>,
compilerOptions: TCompilerOptions<T>,
env: ITestEnv
): ITestRunner {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ function checkStats(stats) {

it('should compile', () => {
expect(v).toBe(1)
expect(checkStats(STATS_JSON)).toBe(true)
expect(checkStats(__STATS__)).toBe(true)
})
4 changes: 2 additions & 2 deletions tests/webpack-test/WatchTestCases.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ const describeCases = config => {
options.target === "webworker"
) {
fn = vm.runInNewContext(
"(function(require, module, exports, __dirname, __filename, it, WATCH_STEP, STATS_JSON, STATE, expect, window, self) {" +
"(function(require, module, exports, __dirname, __filename, it, WATCH_STEP, __STATS__, STATE, expect, window, self) {" +
'function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }' +
content +
"\n})",
Expand All @@ -308,7 +308,7 @@ const describeCases = config => {
);
} else {
fn = vm.runInThisContext(
"(function(require, module, exports, __dirname, __filename, it, WATCH_STEP, STATS_JSON, STATE, expect) {" +
"(function(require, module, exports, __dirname, __filename, it, WATCH_STEP, __STATS__, STATE, expect) {" +
"global.expect = expect;" +
'function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }' +
content +
Expand Down
4 changes: 2 additions & 2 deletions tests/webpack-test/watchCases/cache/asset-modules/0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ it("should return a valid url when modified", async () => {
});

it("should not emit undefined files", () => {
expect(STATS_JSON.assets.map(a => a.name)).not.toContain(undefined);
expect(STATS_JSON.assets.map(a => a.name)).not.toContain("undefined");
expect(__STATS__.assets.map(a => a.name)).not.toContain(undefined);
expect(__STATS__.assets.map(a => a.name)).not.toContain("undefined");
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
it("should not emit files", () => {
expect(STATS_JSON.assets.map(a => a.name)).not.toContainEqual(
expect(__STATS__.assets.map(a => a.name)).not.toContainEqual(
expect.stringMatching(/\.txt$/)
);
});
4 changes: 2 additions & 2 deletions tests/webpack-test/watchCases/cache/asset-modules/3/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ it("should return a valid url when modified", async () => {
});

it("should not emit undefined files", () => {
expect(STATS_JSON.assets.map(a => a.name)).not.toContain(undefined);
expect(STATS_JSON.assets.map(a => a.name)).not.toContain("undefined");
expect(__STATS__.assets.map(a => a.name)).not.toContain(undefined);
expect(__STATS__.assets.map(a => a.name)).not.toContain("undefined");
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
it("should not emit files", () => {
expect(STATS_JSON.assets.map(a => a.name)).not.toContainEqual(
expect(__STATS__.assets.map(a => a.name)).not.toContainEqual(
expect.stringMatching(/\.txt$/)
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ it("should return a valid url when modified", async () => {
});

it("should not rewrite files and only compare them", () => {
for (const asset of STATS_JSON.assets) {
for (const asset of __STATS__.assets) {
if (asset.name.endsWith(".txt")) {
expect(asset).toHaveProperty("emitted", true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
it("should not emit files", () => {
expect(STATS_JSON.assets.map(a => a.name)).not.toContainEqual(
expect(__STATS__.assets.map(a => a.name)).not.toContainEqual(
expect.stringMatching(/\.txt$/)
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ it("should return a valid url when modified", async () => {
});

it("should not rewrite files and only compare them", () => {
for (const asset of STATS_JSON.assets) {
for (const asset of __STATS__.assets) {
if (asset.name.endsWith(".txt")) {
expect(asset).toHaveProperty("cached", true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import path from "path";

it("should include the correct split chunk ids in entry", async () => {
await import("./module");
const runtimeId = STATS_JSON.chunks.find(c => c.names.includes("runtime")).id;
const runtimeId = __STATS__.chunks.find(c => c.names.includes("runtime")).id;
const entryCode = fs.readFileSync(
path.resolve(__dirname, "entry.js"),
"utf-8"
);
STATE.allIds = new Set([
...(STATE.allIds || []),
...STATS_JSON.entrypoints.entry.chunks
...__STATS__.entrypoints.entry.chunks
]);
const expectedIds = Array.from(STATE.allIds).filter(
id => STATS_JSON.entrypoints.entry.chunks.includes(id) && id !== runtimeId
id => __STATS__.entrypoints.entry.chunks.includes(id) && id !== runtimeId
);
try {
for (const id of STATE.allIds) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import path from "path";

it("should include the correct split chunk ids in entry", async () => {
if (Math.random() < 0) import("./module");
const runtimeId = STATS_JSON.chunks.find(c => c.names.includes("runtime")).id;
const runtimeId = __STATS__.chunks.find(c => c.names.includes("runtime")).id;
const entryCode = fs.readFileSync(
path.resolve(__dirname, "entry.js"),
"utf-8"
);
STATE.allIds = new Set([
...(STATE.allIds || []),
...STATS_JSON.entrypoints.entry.chunks
...__STATS__.entrypoints.entry.chunks
]);
const expectedIds = Array.from(STATE.allIds).filter(
id => STATS_JSON.entrypoints.entry.chunks.includes(id) && id !== runtimeId
id => __STATS__.entrypoints.entry.chunks.includes(id) && id !== runtimeId
);
try {
for (const id of STATE.allIds) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { foo } from "./shared";

it("should compile fine", () => {
expect(foo).toBe("foo");
STATE.hash = STATS_JSON.assetsByChunkName.async[0];
STATE.hash = __STATS__.assetsByChunkName.async[0];
});

it("should load the async chunk", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { bar } from "./shared";

it("should compile fine", () => {
expect(bar).toBe("bar");
const hash = STATS_JSON.assetsByChunkName.async[0];
const hash = __STATS__.assetsByChunkName.async[0];
expect(hash).toBe(STATE.hash);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { foo } from "./shared";

it("should compile fine", () => {
expect(foo).toBe("foo");
STATE.hash = STATS_JSON.assetsByChunkName.async[0];
STATE.hash = __STATS__.assetsByChunkName.async[0];
});

it("should load the async chunk", () => {
Expand Down
Loading

2 comments on commit 912f2b3

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented on 912f2b3 Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Ecosystem CI detail: Open

suite result
modernjs ❌ failure
rspress ✅ success
rslib ❌ failure
rsbuild ✅ success
rsdoctor ❌ failure
examples ✅ success
devserver ✅ success
nuxt ✅ success

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented on 912f2b3 Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Benchmark detail: Open

Name Base (2025-02-26 50bdb20) Current Change
10000_big_production-mode_disable-minimize + exec 36.8 s ± 476 ms 37.4 s ± 484 ms +1.68 %
10000_development-mode + exec 1.7 s ± 20 ms 1.7 s ± 24 ms +0.24 %
10000_development-mode_hmr + exec 674 ms ± 19 ms 680 ms ± 26 ms +0.99 %
10000_production-mode + exec 2.21 s ± 66 ms 2.16 s ± 39 ms -2.19 %
10000_production-mode_persistent-cold + exec 2.34 s ± 55 ms 2.31 s ± 24 ms -1.25 %
10000_production-mode_persistent-hot + exec 1.62 s ± 60 ms 1.63 s ± 43 ms +0.58 %
arco-pro_development-mode + exec 1.71 s ± 122 ms 1.77 s ± 88 ms +3.29 %
arco-pro_development-mode_hmr + exec 375 ms ± 2.1 ms 376 ms ± 5.9 ms +0.27 %
arco-pro_production-mode + exec 3.55 s ± 173 ms 3.52 s ± 101 ms -0.95 %
arco-pro_production-mode_generate-package-json-webpack-plugin + exec 3.64 s ± 178 ms 3.62 s ± 200 ms -0.68 %
arco-pro_production-mode_persistent-cold + exec 3.66 s ± 57 ms 3.62 s ± 194 ms -1.07 %
arco-pro_production-mode_persistent-hot + exec 2.24 s ± 125 ms 2.29 s ± 81 ms +2.40 %
arco-pro_production-mode_traverse-chunk-modules + exec 3.61 s ± 181 ms 3.51 s ± 230 ms -2.80 %
large-dyn-imports_development-mode + exec 1.96 s ± 22 ms 1.95 s ± 23 ms -0.44 %
large-dyn-imports_production-mode + exec 2.02 s ± 29 ms 2.04 s ± 68 ms +0.64 %
threejs_development-mode_10x + exec 1.45 s ± 43 ms 1.47 s ± 69 ms +1.91 %
threejs_development-mode_10x_hmr + exec 786 ms ± 8.4 ms 814 ms ± 25 ms +3.64 %
threejs_production-mode_10x + exec 5.04 s ± 169 ms 5.07 s ± 41 ms +0.68 %
threejs_production-mode_10x_persistent-cold + exec 5.15 s ± 294 ms 5.15 s ± 139 ms +0.07 %
threejs_production-mode_10x_persistent-hot + exec 4.46 s ± 215 ms 4.48 s ± 224 ms +0.46 %
10000_big_production-mode_disable-minimize + rss memory 8667 MiB ± 41.1 MiB 8697 MiB ± 58.4 MiB +0.35 %
10000_development-mode + rss memory 655 MiB ± 19.2 MiB 671 MiB ± 25.6 MiB +2.43 %
10000_development-mode_hmr + rss memory 1201 MiB ± 64.3 MiB 1329 MiB ± 196 MiB +10.72 %
10000_production-mode + rss memory 617 MiB ± 6.87 MiB 644 MiB ± 15.4 MiB +4.38 %
10000_production-mode_persistent-cold + rss memory 732 MiB ± 6 MiB 745 MiB ± 16.1 MiB +1.80 %
10000_production-mode_persistent-hot + rss memory 699 MiB ± 31.9 MiB 732 MiB ± 19.7 MiB +4.76 %
arco-pro_development-mode + rss memory 571 MiB ± 31 MiB 590 MiB ± 33 MiB +3.32 %
arco-pro_development-mode_hmr + rss memory 650 MiB ± 51.6 MiB 667 MiB ± 59.4 MiB +2.74 %
arco-pro_production-mode + rss memory 709 MiB ± 41.3 MiB 730 MiB ± 25.3 MiB +2.99 %
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory 725 MiB ± 15.4 MiB 745 MiB ± 35.5 MiB +2.78 %
arco-pro_production-mode_persistent-cold + rss memory 804 MiB ± 25.7 MiB 795 MiB ± 54.3 MiB -1.19 %
arco-pro_production-mode_persistent-hot + rss memory 655 MiB ± 23.2 MiB 683 MiB ± 25.7 MiB +4.23 %
arco-pro_production-mode_traverse-chunk-modules + rss memory 731 MiB ± 23.4 MiB 746 MiB ± 56.6 MiB +1.95 %
large-dyn-imports_development-mode + rss memory 650 MiB ± 5.99 MiB 675 MiB ± 7.46 MiB +3.84 %
large-dyn-imports_production-mode + rss memory 529 MiB ± 6.89 MiB 553 MiB ± 11.7 MiB +4.55 %
threejs_development-mode_10x + rss memory 571 MiB ± 14.4 MiB 577 MiB ± 10.8 MiB +1.08 %
threejs_development-mode_10x_hmr + rss memory 1212 MiB ± 166 MiB 1162 MiB ± 165 MiB -4.10 %
threejs_production-mode_10x + rss memory 858 MiB ± 32.6 MiB 844 MiB ± 38.5 MiB -1.62 %
threejs_production-mode_10x_persistent-cold + rss memory 963 MiB ± 58.5 MiB 929 MiB ± 73.1 MiB -3.53 %
threejs_production-mode_10x_persistent-hot + rss memory 815 MiB ± 40.3 MiB 816 MiB ± 31.4 MiB +0.03 %

Please sign in to comment.