Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ package-lock.json
!serviceModels/logs
dist
tests/bundlers/dist-min
tests/bundlers/dist-vite

.idea/
*.iml
Expand Down
14 changes: 14 additions & 0 deletions benchmark/bundlers/report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
| Application | SDK Version | browser:Webpack | browser:Rollup | browser:EsBuild |
| :---------------------------------------- | :---------- | :-------------- | :------------- | :-------------- |
| lib-dynamodb-aggregate.ts | 3.883.0 | 211 kb | 204 kb | 232 kb |
| multiple-sdk-clients.ts | 3.883.0 | 498 kb | 488 kb | 534 kb |
| private-multiple-clients-micg.ts | 3.883.0 | 435 kb | 429 kb | 479 kb |
| private-multiple-clients-schema.ts | 3.883.0 | 376 kb | 378 kb | 423 kb |
| private-restjson-micg-aggregate.ts | 3.883.0 | 228 kb | 223 kb | 248 kb |
| private-restjson-micg-single-command.ts | 3.883.0 | 125 kb | 120 kb | 140 kb |
| private-restjson-schema-aggregate.ts | 3.883.0 | 213 kb | 210 kb | 233 kb |
| private-restjson-schema-single-command.ts | 3.883.0 | 146 kb | 142 kb | 164 kb |
| sdk-ec2-aggregate.ts | 3.883.0 | 1.159 mb | 1.105 mb | 1.152 mb |
| sdk-s3-aggregate.ts | 3.883.0 | 376 kb | 367 kb | 399 kb |
| sdk-s3-single-command.ts | 3.883.0 | 222 kb | 216 kb | 242 kb |
| sdk-sagemaker-aggregate.ts | 3.883.0 | 462 kb | 445 kb | 482 kb |
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"scripts": {
"bootstrap": "yarn",
"bootstrap:ci": "yarn install --frozen-lockfile",
"benchmark:bundlers": "node ./tests/bundlers/runner/run.mjs",
"build:all": "node ./scripts/turbo build",
"build:ci": "node ./scripts/turbo build",
"build:clients:generic": "node ./scripts/turbo build -F=@aws-sdk/aws-echo-service",
Expand Down
2 changes: 2 additions & 0 deletions tests/bundlers/applications/lib-dynamodb-aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";
export { DynamoDB } from "@aws-sdk/client-dynamodb";
3 changes: 3 additions & 0 deletions tests/bundlers/applications/multiple-sdk-clients.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { S3 } from "@aws-sdk/client-s3";
export { DynamoDB } from "@aws-sdk/client-dynamodb";
export { SQS } from "@aws-sdk/client-sqs";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { RestJsonProtocol } from "@aws-sdk/aws-protocoltests-restjson";
export { RestXmlProtocol } from "@aws-sdk/aws-protocoltests-restxml";
export { JsonProtocol } from "@aws-sdk/aws-protocoltests-json";
export { JSONRPC10 } from "@aws-sdk/aws-protocoltests-json-10";
export { RpcV2Protocol } from "@aws-sdk/aws-protocoltests-smithy-rpcv2-cbor";
export { QueryProtocol } from "@aws-sdk/aws-protocoltests-query";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { RestJsonProtocol } from "@aws-sdk/aws-protocoltests-restjson-schema";
export { RestXmlProtocol } from "@aws-sdk/aws-protocoltests-restxml-schema";
export { JsonProtocol } from "@aws-sdk/aws-protocoltests-json-schema";
export { JSONRPC10 } from "@aws-sdk/aws-protocoltests-json-10-schema";
export { RpcV2Protocol } from "@aws-sdk/aws-protocoltests-smithy-rpcv2-cbor-schema";
export { QueryProtocol } from "@aws-sdk/aws-protocoltests-query-schema";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RestJsonProtocol } from "@aws-sdk/aws-protocoltests-restjson";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { HttpStringPayloadCommand, RestJsonProtocolClient } from "@aws-sdk/aws-protocoltests-restjson";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RestJsonProtocol } from "@aws-sdk/aws-protocoltests-restjson-schema";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { HttpStringPayloadCommand, RestJsonProtocolClient } from "@aws-sdk/aws-protocoltests-restjson-schema";
1 change: 1 addition & 0 deletions tests/bundlers/applications/sdk-ec2-aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EC2 } from "@aws-sdk/client-ec2";
1 change: 1 addition & 0 deletions tests/bundlers/applications/sdk-s3-aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { S3 } from "@aws-sdk/client-s3";
1 change: 1 addition & 0 deletions tests/bundlers/applications/sdk-s3-single-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
1 change: 1 addition & 0 deletions tests/bundlers/applications/sdk-sagemaker-aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SageMaker } from "@aws-sdk/client-sagemaker";
148 changes: 148 additions & 0 deletions tests/bundlers/runner/BundlerSizeBenchmarker.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import path from "node:path";
import fs from "node:fs";
import webpack from "webpack";
import { build } from "vite";
import esbuild from "esbuild";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

/**
* Gives file stats for a selection of bundlers and application types.
*/
export class BundlerSizeBenchmarker {
constructor({ application }) {
this.application = application;
}

/**
* Create a Webpack bundle.
* @returns {Promise<{app:string,size:string,bundler:string}>}
*/
async webpack() {
const outfile = path.resolve(__dirname, "..", "dist", `webpack-dist-${this.application}.js`);

const config = {
mode: "production",
entry: path.resolve(__dirname, "..", "applications", this.application),
target: "web",
output: {
path: path.dirname(outfile),
filename: path.basename(outfile),
library: "dist",
},
optimization: {
minimize: true,
splitChunks: false,
runtimeChunk: false,
sideEffects: true,
usedExports: true,
},
stats: {
optimizationBailout: false,
},
};
return new Promise((resolve) => {
webpack(config, (err, stats) => {
if (err) {
console.error(err);
}
const stat = fs.statSync(outfile);
resolve(this.report(stat, "webpack"));
});
});
}

/**
* Create a Rollup bundle.
* @returns {Promise<{app:string,size:string,bundler:string}>}
*/
async rollup() {
const inputFile = path.resolve(__dirname, "..", "applications", this.application);
const outfile = path.resolve(__dirname, "..", "dist-vite", `vite-${this.application}.umd.js`);

await build({
logLevel: "silent",
build: {
outDir: "./dist-vite",
lib: {
entry: inputFile,
name: "dist",
fileName: `vite-${this.application}`,
},
rollupOptions: {
input: {
input: inputFile,
},
external: [],
output: {
dir: path.dirname(outfile),
inlineDynamicImports: true,
},
},
},
});

const stat = fs.statSync(outfile);
return this.report(stat, "rollup");
}

/**
* Create a Esbuild bundle.
* @returns {Promise<{app:string,size:string,bundler:string}>}
*/
async esbuild() {
const entryPoint = path.resolve(__dirname, "..", "applications", this.application);
const outfile = path.resolve(__dirname, "..", "dist", `esbuild-dist-${this.application}.js`);

await esbuild.build({
entryPoints: [entryPoint],
bundle: true,
minify: true,
outfile: outfile,
format: "esm",
target: "es2015",
});

const stat = fs.statSync(outfile);
return this.report(stat, "esbuild");
}

async all() {
const stats = await Promise.all([this.rollup(), this.webpack(), this.esbuild()]);
const data = {
app: this.application,
};
for (const stat of stats) {
data[stat.bundler] = stat.size;
}
return data;
}

/**
* @param {fs.Stats} stat
* @param {string} bundler
* @returns {{app, size: string}}
*/
report(stat, bundler) {
return {
app: this.application,
size: byteSize(stat.size),
bundler: bundler,
};
}
}

/**
* @param {number} num - of bytes.
* @returns {string} bytes in readable format.
*/
function byteSize(num) {
if (num > 1024 ** 2) {
return ((((num / 1024 ** 2) * 1000) | 0) / 1000).toLocaleString() + " mb";
}
if (num > 1024) {
return ((num / 1024) | 0).toLocaleString() + " kb";
}
return num.toLocaleString() + " b";
}
31 changes: 31 additions & 0 deletions tests/bundlers/runner/ReportMarkdown.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { fileURLToPath } from "url";
import path from "node:path";
import fs from "node:fs";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const lerna = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "..", "lerna.json"), "utf-8"));

/**
* Converts stat objects from {BundlerSizeBenchmarker} to markdown report.
*/
export class ReportMarkdown {
constructor() {
this.rows = [];
}

push(stat) {
this.rows.push(stat);
}

toMarkdown() {
return `| Application | SDK Version | browser:Webpack | browser:Rollup | browser:EsBuild |
| :------ | :------ | :----------- | :------ | :----- |
${this.rows
.map((row) => {
const { app, webpack, rollup, esbuild } = row;
return `|${app}|${lerna.version}|${webpack}|${rollup}|${esbuild}|`;
})
.join("\n")}`;
}
}
28 changes: 28 additions & 0 deletions tests/bundlers/runner/run.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import fs from "node:fs";
import { fileURLToPath } from "node:url";
import path from "node:path";
import prettier from "prettier";

import { ReportMarkdown } from "./ReportMarkdown.mjs";
import { BundlerSizeBenchmarker } from "./BundlerSizeBenchmarker.mjs";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const applicationFolder = path.join(__dirname, "..", "applications");
const report = new ReportMarkdown();

for (const app of fs.readdirSync(applicationFolder)) {
const benchmarker = new BundlerSizeBenchmarker({ application: app });

const stat = await benchmarker.all();
console.log(stat);
report.push(stat);
}

const reportMd = path.join(__dirname, "..", "..", "..", "benchmark", "bundlers", "report.md");

const formatted = prettier.format(report.toMarkdown(), {
filepath: reportMd,
});

fs.writeFileSync(reportMd, formatted);
Loading