Skip to content

Commit f396850

Browse files
committed
test(benchmark-size): address feedbacks
1 parent d3a8d65 commit f396850

File tree

12 files changed

+146
-135
lines changed

12 files changed

+146
-135
lines changed

benchmark/size/report.md

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
| Package | Version | Publish Size | Publish Files | Webpack | Rollup | EsBuild |
2-
| :------ | :------ | :----------- | :------------ | :------ | :----- | ------- |
3-
|@aws-sdk/abort-controller|3.40.0|41.4 KB|17|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
4-
|@aws-sdk/credential-provider-cognito-identity|3.40.0|116.2 KB|38|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
5-
|@aws-sdk/credential-provider-env|3.40.0|45.9 KB|11|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
6-
|@aws-sdk/credential-provider-imds|3.40.0|76.9 KB|56|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
7-
|@aws-sdk/credential-provider-ini|3.40.0|59.8 KB|11|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
8-
|@aws-sdk/credential-provider-node|3.40.0|59.9 KB|11|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
9-
|@aws-sdk/credential-provider-process|3.40.0|46.9 KB|11|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
10-
|@aws-sdk/credential-provider-sso|3.40.0|34.7 KB|11|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
11-
|@aws-sdk/credential-provider-web-identity|3.40.0|34.1 KB|17|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
12-
|@aws-sdk/credential-providers|3.40.0|77.9 KB|47|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
13-
|@aws-sdk/fetch-http-handler|3.40.0|70.3 KB|20|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
14-
|@aws-sdk/lib-dynamodb|3.40.0|145 KB|65|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
15-
|@aws-sdk/lib-storage|3.40.1|66.5 KB|50|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
16-
|@aws-sdk/node-http-handler|3.40.0|101.9 KB|50|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
17-
|@aws-sdk/polly-request-presigner|3.40.0|36.4 KB|20|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
18-
|@aws-sdk/s3-presigned-post|3.40.1|38.1 KB|20|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
19-
|@aws-sdk/s3-request-presigner|3.40.1|78.8 KB|20|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
20-
|@aws-sdk/signature-v4|3.40.0|177.6 KB|50|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
21-
|@aws-sdk/signature-v4-crt|3.40.0|77.3 KB|23|❌(5.62.1)|❌(2.59.0)|❌(0.13.12)|
22-
|@aws-sdk/smithy-client|3.40.0|115.9 KB|47|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
23-
|@aws-sdk/types|3.40.0|135.2 KB|62|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
1+
| Package | Version | Publish Size | browser:Webpack | browser:Rollup | browser:EsBuild |
2+
| :------ | :------ | :----------- | :------ | :----- | :------- |
3+
|@aws-sdk/abort-controller|3.40.0|41.4 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
4+
|@aws-sdk/client-s3|3.41.0|3.4 MB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
5+
|@aws-sdk/credential-provider-cognito-identity|3.41.0|116.4 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
6+
|@aws-sdk/credential-provider-env|3.40.0|45.9 KB|N/A|N/A|N/A|
7+
|@aws-sdk/credential-provider-imds|3.40.0|76.9 KB|N/A|N/A|N/A|
8+
|@aws-sdk/credential-provider-ini|3.41.0|59.9 KB|N/A|N/A|N/A|
9+
|@aws-sdk/credential-provider-node|3.41.0|60 KB|N/A|N/A|N/A|
10+
|@aws-sdk/credential-provider-process|3.40.0|46.9 KB|N/A|N/A|N/A|
11+
|@aws-sdk/credential-provider-sso|3.41.0|34.9 KB|N/A|N/A|N/A|
12+
|@aws-sdk/credential-provider-web-identity|3.41.0|34.4 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
13+
|@aws-sdk/credential-providers|3.41.0|78.2 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
14+
|@aws-sdk/fetch-http-handler|3.40.0|70.3 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
15+
|@aws-sdk/lib-dynamodb|3.41.0|145.1 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
16+
|@aws-sdk/lib-storage|3.41.0|66.6 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
17+
|@aws-sdk/node-http-handler|3.40.0|101.9 KB|N/A|N/A|N/A|
18+
|@aws-sdk/polly-request-presigner|3.41.0|36.7 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
19+
|@aws-sdk/s3-presigned-post|3.41.0|38.3 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
20+
|@aws-sdk/s3-request-presigner|3.41.0|79 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
21+
|@aws-sdk/signature-v4|3.40.0|177.6 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
22+
|@aws-sdk/signature-v4-crt|3.41.0|77.8 KB|N/A|N/A|N/A|
23+
|@aws-sdk/smithy-client|3.41.0|117.1 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|
24+
|@aws-sdk/types|3.40.0|135.2 KB|✅(5.62.1)|✅(2.59.0)|✅(0.13.12)|

scripts/benchmark-size/limit.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"default": {
3-
"publishSize": { "limit": "1 mb", "hike": "3 %" },
4-
"publishFiles": { "limit": "500", "hike": "3 %" }
3+
"publishSize": { "limit": "1 mb", "hike": "10 %" }
54
},
65
"@aws-sdk/client-ec2": {
76
"publishSize": { "limit": "10 mb" }

scripts/benchmark-size/runner/calculate-size/bundlers-size.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ export const getWebpackSize = async (context: BundlerSizeReportContext): Promise
2121
const webpackInstance = webpack({
2222
entry: context.entryPoint,
2323
output: { path: webpackOutputDir, filename: "index.js" },
24-
resolve: {
25-
alias: {
26-
events: false,
27-
url: false,
28-
},
29-
},
3024
});
3125
const run = promisify(webpackInstance.run);
3226
const webpackStats = await run.call(webpackInstance);
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import exec from "execa";
2+
import { promises as fsPromise } from "fs";
3+
import { join } from "path";
4+
import prettier from "prettier";
5+
6+
import { PackageContext } from "../load-test-scope";
7+
import type { PackageSizeReportOptions } from "./index";
8+
9+
export const generateProject = async (projectDir: string, options: PackageSizeReportOptions) => {
10+
const peerDependencies = await getPeerDependencies(options);
11+
const contextWithPeerDep: PackageContext = {
12+
...options.packageContext,
13+
dependencies: [...peerDependencies, ...(options.packageContext?.dependencies ?? [])],
14+
};
15+
// console.error("CONTEXT||||||||", contextWithPeerDep);
16+
for (const [name, template] of Object.entries(options.templates)) {
17+
const filePath = join(projectDir, name);
18+
const file = prettier.format(template(contextWithPeerDep), {
19+
filepath: filePath,
20+
});
21+
// console.error("FILE|||||||, ", file);
22+
await fsPromise.writeFile(filePath, file);
23+
}
24+
25+
await exec(
26+
"npm",
27+
[
28+
"install",
29+
"--cache",
30+
options.npmCacheDir,
31+
"--no-audit",
32+
"--no-update-notifier",
33+
"--no-package-lock",
34+
"--no-progress",
35+
"--production",
36+
"--silent",
37+
],
38+
{
39+
cwd: projectDir,
40+
env: {
41+
npm_config_registry: options.localRegistry,
42+
},
43+
}
44+
);
45+
};
46+
47+
type PeerDependencies = { name: string; version: string }[];
48+
49+
/**
50+
* Reads the peer dependencies from the package.json. These dependencies will be added to the
51+
* generated project's dependencies.
52+
*/
53+
const getPeerDependencies = async (options: PackageSizeReportOptions): Promise<PeerDependencies> => {
54+
// console.error("||||||||NAME: ", options.packageName);
55+
const packageInfo = options.workspacePackages.find((pkg) => pkg.name === options.packageName);
56+
if (!packageInfo) {
57+
throw new Error(`Cannot find package ${options.packageName} from the workspace`);
58+
}
59+
const packageJsonPath = join(packageInfo.location, "package.json");
60+
let peerDependencies: PeerDependencies;
61+
try {
62+
peerDependencies = JSON.parse(await fsPromise.readFile(packageJsonPath, "utf-8"))["peerDependencies"] ?? {};
63+
} catch (e) {
64+
throw new Error(`Cannot load the package.json file from ${packageJsonPath}`);
65+
}
66+
// Change the peer dependencies' version to "ci", referring to the current local package.
67+
// console.error("|||||PD: ", peerDependencies);
68+
// console.error("|||||PI: ", packageInfo);
69+
return Object.entries(peerDependencies).map(([key]) => ({ name: key, version: "ci" }));
70+
};

scripts/benchmark-size/runner/calculate-size/index.ts

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
1-
import exec from "execa";
2-
import { promises as fsPromise, readFileSync } from "fs";
1+
import { promises as fsPromise } from "fs";
32
import { ListrContext, ListrTaskWrapper } from "listr2";
43
import { join } from "path";
5-
import prettier from "prettier";
64

75
import { SizeReportContext } from "../index";
8-
import { PackageTestScope } from "../load-test-scope";
6+
import { PackageContext } from "../load-test-scope";
97
import { getEsbuildSize, getRollupSize, getWebpackSize } from "./bundlers-size";
8+
import { generateProject } from "./generate-project";
109
import { calculateNpmSize } from "./npm-size";
1110

1211
export interface PackageSizeReportOptions extends SizeReportContext {
1312
packageName: string;
14-
packageScope: PackageTestScope;
13+
packageContext: PackageContext;
1514
}
1615

1716
export interface PackageSizeReportOutput {
1817
name: string;
1918
version: string;
2019
installSize: number;
2120
publishSize: number;
22-
publishFiles: number;
23-
installFiles: number;
2421
webpackSize: number | undefined;
2522
esbuildSize: number | undefined;
2623
rollupSize: number | undefined;
@@ -35,41 +32,13 @@ export const getPackageSizeReportRunner =
3532
const entryPoint = join(projectDir, "index.js");
3633
const bundlersContext = { ...options, entryPoint, projectDir };
3734

38-
task.output = "generating project";
39-
for (const [name, template] of Object.entries(options.templates)) {
40-
const filePath = join(projectDir, name);
41-
const file = prettier.format(template(options.packageScope), {
42-
filepath: filePath,
43-
});
44-
await fsPromise.writeFile(filePath, file);
45-
}
46-
47-
task.output = "installing";
48-
await exec(
49-
"npm",
50-
[
51-
"install",
52-
"--cache",
53-
options.npmCacheDir,
54-
"--no-audit",
55-
"--no-update-notifier",
56-
"--no-package-lock",
57-
"--no-progress",
58-
"--production",
59-
"--silent",
60-
],
61-
{
62-
cwd: projectDir,
63-
env: {
64-
npm_config_registry: options.localRegistry,
65-
},
66-
}
67-
);
35+
task.output = "generating project and installing dependencies";
36+
await generateProject(projectDir, options);
6837

6938
task.output = "calculating npm size";
7039
const npmSizeResult = calculateNpmSize(projectDir, options.packageName);
7140

72-
const skipBundlerTests = bundlersContext.packageScope.skipBundlerTests;
41+
const skipBundlerTests = bundlersContext.packageContext.skipBundlerTests;
7342

7443
task.output = "calculating webpack 5 full bundle size";
7544
const webpackSize = skipBundlerTests ? undefined : await getWebpackSize(bundlersContext);
@@ -82,7 +51,7 @@ export const getPackageSizeReportRunner =
8251

8352
task.output = "output results";
8453
const packageVersion = JSON.parse(
85-
readFileSync(
54+
await fsPromise.readFile(
8655
join(options.workspacePackages.filter((pkg) => pkg.name === options.packageName)[0].location, "package.json"),
8756
"utf8"
8857
)

scripts/benchmark-size/runner/calculate-size/npm-size.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ import { join } from "path";
44
export interface NpmSize {
55
publishSize: number;
66
installSize: number;
7-
publishFiles: number;
8-
installFiles: number;
97
}
108

119
/**
12-
* Replicate the same config of Bundlephobia
10+
* Replicate the same config of PackagePhobia
1311
*/
1412
export const calculateNpmSize = (packageDir: string, packageName: string): NpmSize => {
1513
const nodeModules = join(packageDir, "node_modules");
@@ -20,9 +18,6 @@ export const calculateNpmSize = (packageDir: string, packageName: string): NpmSi
2018
return {
2119
installSize,
2220
publishSize,
23-
publishFiles: publishFiles.size,
24-
// Subtract 1 to exclude `node_modules` root dir
25-
installFiles: installFiles.size - 1,
2621
};
2722
};
2823

scripts/benchmark-size/runner/index.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
PORT,
1414
PROJECT_TEMPLATES_DIR,
1515
} from "./constants";
16-
import { loadTestScope } from "./load-test-scope";
16+
import { loadPackageContext } from "./load-test-scope";
1717
import { localPublishChangedPackages, spawnLocalRegistry } from "./local-registry";
1818
import { updateReport } from "./reporter";
1919
import { sleep, validateRuntime } from "./utils";
@@ -76,28 +76,28 @@ export const sizeReport = async (options: SizeReportOptions) => {
7676
// Preparing the runtime.
7777
await validateRuntime();
7878

79-
const packages = await loadWorkspacePackages({ since: options.since });
79+
const changedPackages = await loadWorkspacePackages({ since: options.since });
8080
console.info("starting generating size report for changed packages");
8181
if (!(options?.skipLocalPublish ?? false)) {
82-
await validatePackagesAlreadyBuilt(packages);
82+
await validatePackagesAlreadyBuilt(changedPackages);
8383
await localPublishChangedPackages();
8484
}
85-
let testScope = await loadTestScope(options?.scopeConfigPath);
86-
const packageNames = packages.map((pkg) => pkg.name);
87-
testScope = testScope.filter((perTestScope) => packageNames.includes(perTestScope.package));
88-
console.info(`Found ${testScope.length} packages in the defined scope have size test scope.`);
85+
const testScope = await loadPackageContext(options?.scopeConfigPath);
86+
const changedPackageNames = changedPackages.map((pkg) => pkg.name);
87+
const packageContextToTest = testScope.filter((perTestScope) => changedPackageNames.includes(perTestScope.package));
88+
console.info(`Found ${packageContextToTest.length} packages in the defined scope have size test scope.`);
8989
const localRegistryProcess = spawnLocalRegistry(PORT);
9090

9191
// Wait for the register to spin up.
9292
await sleep(1000);
9393
const sizeReportContext = await getSizeReportContext({ port: PORT });
9494
const tasks = new Listr(
95-
testScope.map((packageScope) => ({
96-
title: packageScope.package,
95+
packageContextToTest.map((packageContext) => ({
96+
title: packageContext.package,
9797
task: getPackageSizeReportRunner({
9898
...sizeReportContext,
99-
packageName: packageScope.package,
100-
packageScope,
99+
packageName: packageContext.package,
100+
packageContext,
101101
}),
102102
})),
103103
{ concurrent: 10 }

scripts/benchmark-size/runner/load-test-scope.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import { readFileSync } from "fs";
33
import { DEFAULT_TEST_SCOPE } from "./constants";
44
import { loadWorkspacePackages } from "./workspace";
55

6-
export type PackageTestScope = {
6+
export type PackageContext = {
77
package: string;
88
dependencies?: { name: string; version: string }[];
99
skipBundlerTests?: boolean;
1010
};
1111

12-
export const loadTestScope = async (scopeConfigPath: string = DEFAULT_TEST_SCOPE): Promise<PackageTestScope[]> => {
12+
export const loadPackageContext = async (scopeConfigPath: string = DEFAULT_TEST_SCOPE): Promise<PackageContext[]> => {
1313
console.info(`loading test scopes from ${scopeConfigPath}`);
1414
const rawConfig: Array<unknown> = JSON.parse(readFileSync(scopeConfigPath, "utf8"));
1515
if (!Array.isArray(rawConfig)) {
1616
throw new Error(`test scope config is invalid, expect array`);
1717
}
18-
const scope: PackageTestScope[] = [];
19-
for (const pkgScope of rawConfig as Array<Partial<PackageTestScope>>) {
18+
const scope: PackageContext[] = [];
19+
for (const pkgScope of rawConfig as Array<Partial<PackageContext>>) {
2020
if (!pkgScope.package) {
2121
throw new Error("'package' entry is required for each scope configuration entry");
2222
}
@@ -33,7 +33,7 @@ export const loadTestScope = async (scopeConfigPath: string = DEFAULT_TEST_SCOPE
3333
}
3434
// Later config entry should overwrite the previous config entry
3535
const packageNames: Set<string> = new Set();
36-
const deduplicatedScope: PackageTestScope[] = [];
36+
const deduplicatedScope: PackageContext[] = [];
3737
scope.reverse().forEach((scope) => {
3838
if (packageNames.has(scope.package)) {
3939
return;

scripts/benchmark-size/runner/reporter/index.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import { PackageSizeReportOutput } from "../calculate-size";
55
import { prettifySize } from "../utils";
66
import { LimitValidator } from "./limit";
77

8-
const HEADER = `| Package | Version | Publish Size | Publish Files | Webpack | Rollup | EsBuild |
9-
| :------ | :------ | :----------- | :------------ | :------ | :----- | ------- |`;
8+
const HEADER = `| Package | Version | Publish Size | browser:Webpack | browser:Rollup | browser:EsBuild |
9+
| :------ | :------ | :----------- | :------ | :----- | :------- |`;
1010

1111
export type Column =
1212
| "package"
1313
| "version"
1414
| "publishSize"
15-
| "publishFiles"
1615
| "webpackCompatibility"
1716
| "rollupCompatibility"
1817
| "esbuildCompatibility";
@@ -21,7 +20,6 @@ export const columns: Column[] = [
2120
"package",
2221
"version",
2322
"publishSize",
24-
"publishFiles",
2523
"webpackCompatibility",
2624
"rollupCompatibility",
2725
"esbuildCompatibility",
@@ -88,10 +86,9 @@ const populateLineContent = (
8886
package: report.name,
8987
version: report.version,
9088
publishSize: prettifySize(report.publishSize),
91-
publishFiles: report.publishFiles,
92-
webpackCompatibility: `${report.webpackSize ? "✅" : "❌"}(${options.webpackVersion})`,
93-
rollupCompatibility: `${report.rollupSize ? "✅" : "❌"}(${options.rollupVersion})`,
94-
esbuildCompatibility: `${report.esbuildSize ? "✅" : "❌"}(${options.esbuildVersion})`,
89+
webpackCompatibility: `${report.webpackSize ? `✅(${options.webpackVersion})` : "N/A"}`,
90+
rollupCompatibility: `${report.rollupSize ? `✅(${options.rollupVersion})` : "N/A"}`,
91+
esbuildCompatibility: `${report.esbuildSize ? `✅(${options.esbuildVersion})` : "N/A"}`,
9592
});
9693

9794
export const updateReport = (

scripts/benchmark-size/runner/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import exec from "execa";
2+
import { promises as fsPromise, existsSync } from "fs";
23

34
import { PROJECT_ROOT } from "./constants";
45

@@ -58,3 +59,6 @@ export const readSize = (value: string | number): number => {
5859
}
5960
return parseFloat(digits) * (unit ? multiplier[unit] : 1);
6061
};
62+
63+
export const isFile = async (path: string): Promise<boolean> =>
64+
existsSync(path) && (await fsPromise.lstat(path)).isFile();

0 commit comments

Comments
 (0)