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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ smithy-typescript-ssdk-codegen-test-utils/bin/
smithy-typescript-codegen-test/example-weather-customizations/bin/

testbed/bundlers/dist
testbed/bundlers/dist-min
testbed/bundlers/dist-*
**/node_modules/
**/*.tsbuildinfo
**/*.d.ts
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ test-browser:
yarn g:vitest run -c vitest.config.browser.mts

test-bundlers:
(cd ./testbed/bundlers && make build test)
(cd ./testbed/bundlers && make run)

# typecheck for test code.
test-types:
Expand Down
29 changes: 6 additions & 23 deletions testbed/bundlers/Makefile
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
.PHONY: test build vite webpack
.PHONY: run

# asserts that bundles contain expected content.
test:
node bundlers.spec.mjs
du -sh ./dist-min/*

# create bundles
build:
rm -rf ./dist/*
rm -rf ./dist-min/*
make vite webpack

# note: vite deletes files in the build folders and must run first.
vite:
npx vite build --config vite.config.ts
npx vite build --config vite.min.config.ts

webpack:
npx webpack
npx webpack -c webpack.min.config.js

esbuild:
exit 1
run:
mkdir -p dist-vite
mkdir -p dist-esbuild
mkdir -p dist-webpack
node ./runner/run.mjs
1 change: 1 addition & 0 deletions testbed/bundlers/applications/NormalizedSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { NormalizedSchema } from "@smithy/core/schema";
1 change: 1 addition & 0 deletions testbed/bundlers/applications/abstract-protocols.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { HttpBindingProtocol, RpcProtocol } from "@smithy/core/protocols";
1 change: 1 addition & 0 deletions testbed/bundlers/applications/cbor-client-aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RpcV2Protocol } from "@smithy/smithy-rpcv2-cbor-schema";
1 change: 1 addition & 0 deletions testbed/bundlers/applications/cbor-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RpcV2ProtocolClient } from "@smithy/smithy-rpcv2-cbor-schema";
1 change: 1 addition & 0 deletions testbed/bundlers/applications/cbor-protocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SmithyRpcV2CborProtocol } from "@smithy/core/cbor";
Empty file.
31 changes: 0 additions & 31 deletions testbed/bundlers/bundlers.spec.mjs

This file was deleted.

19 changes: 0 additions & 19 deletions testbed/bundlers/esbuild.mjs

This file was deleted.

189 changes: 189 additions & 0 deletions testbed/bundlers/runner/BundlerSizeBenchmarker.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
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", `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.cjs`);

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

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

async rollupNoMinification() {
const inputFile = path.resolve(__dirname, "..", "applications", this.application);
const outfile = path.resolve(__dirname, "..", "dist-rollup", `rollup-${this.application}.umd.cjs`);

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

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

/**
* 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", `esbuild-dist-${this.application}.js`);

await esbuild.build({
entryPoints: [entryPoint],
platform: "browser",
bundle: true,
minify: true,
mainFields: ["browser", "module", "main"],
outfile: outfile,
format: "esm",
target: "es2022",
});

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

async all() {
const stats = await Promise.all([
this.rollup(), //
this.rollupNoMinification(),
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";
}
19 changes: 19 additions & 0 deletions testbed/bundlers/runner/run.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import fs from "node:fs";
import { fileURLToPath } from "node:url";
import path from "node:path";

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

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

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

for (const app of fs.readdirSync(applicationFolder)) {
if (fs.lstatSync(path.join(applicationFolder, app)).isDirectory()) {
continue;
}
const benchmarker = new BundlerSizeBenchmarker({ application: app });

const stat = await benchmarker.all();
console.log(stat);
}
1 change: 0 additions & 1 deletion testbed/bundlers/source.ts

This file was deleted.

30 changes: 0 additions & 30 deletions testbed/bundlers/vite.config.ts

This file was deleted.

30 changes: 0 additions & 30 deletions testbed/bundlers/vite.min.config.ts

This file was deleted.

Loading