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
90 changes: 33 additions & 57 deletions scripts/cli-dispatcher/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env node

const fs = require("fs");
const path = require("path");
const readline = require("readline");

Expand Down Expand Up @@ -37,31 +36,21 @@ async function main() {
const [node, dispatcher, ...rest] = argv;
const flags = rest.filter((f) => f.startsWith("--"));
const options = {
dry: flags.includes("--dry"),
help: flags.includes("--help") || rest.length === 0,
confirm: flags.includes("--c"),
};

if (options.help) {
console.info(`
Usage:
b [package query words] - [command query words]
b c s3 c - b t
b c s3 c - b t, b cjs

matches to:
(cd clients/client-s3-control && yarn build:types)
(cd clients/client-s3-control && yarn build:types && yarn build:cjs)

Query words are substrings that match against the package name and npm scripts.
The substrings must appear in order for a match.
Match priority goes to whole-word matching and initial matching.

Options:
--dry
dry run with no command execution.
--help
show this message.
--c
ask for confirmation before executing command.
`);
return 0;
}
Expand All @@ -70,6 +59,10 @@ async function main() {
const separatorIndex = rest.indexOf("-") !== -1 ? rest.indexOf("-") : rest.length;
const query = nonFlags.slice(0, separatorIndex);
const commands = nonFlags.slice(separatorIndex + 1);
const multiCommands = commands
.join(" ")
.split(/,\s?/)
.map((c) => c.split(" "));

const matchedPackages = findFolders(allPackages, ...query);

Expand All @@ -85,59 +78,42 @@ async function main() {
);

const [target] = matchedPackages;

const targetPkgJson = require(path.join(target.location, "package.json"));
const matchedScripts = findScripts(Object.keys(targetPkgJson.scripts || {}), ...commands);
const [script] = matchedScripts;

if (commands.length === 0) {
console.info("No commands entered");
return 0;
}

if (matchedScripts.length === 0) {
console.error("No matching scripts for command query:", commands);
return 0;
}
for (const commands of multiCommands) {
const matchedScripts = findScripts(Object.keys(targetPkgJson.scripts || {}), ...commands);

console.log("commands:", ...commands);
console.log("matched commands:", matchedScripts);
if (commands.length === 0) {
console.info("No commands entered");
return 0;
}

const command = `yarn ${script} in ${target.location}`;
if (matchedScripts.length === 0) {
console.error("No matching scripts for command query:", commands);
return 0;
}

if (options.dry) {
console.log("DRYRUN:", command);
return 0;
console.log("commands:", ...commands);
console.log("matched commands:", matchedScripts);
}

const execute = async () => {
const { spawnProcess } = require("../utils/spawn-process");
console.info("Running:", "yarn", script);
console.info("Location:", target.location);
await spawnProcess("yarn", [script], {
cwd: target.location,
stdio: "inherit",
});
return;
};

if (options.confirm) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

rl.question(`run script "${script}" in ${target.location} (y)/n?:`, async (confirm) => {
if (confirm.toLowerCase().trim() === "y" || confirm === "") {
await execute();
}
rl.close();
});
return 0;
for (const commands of multiCommands) {
const matchedScripts = findScripts(Object.keys(targetPkgJson.scripts || {}), ...commands);
const [script] = matchedScripts;

const execute = async () => {
const { spawnProcess } = require("../utils/spawn-process");
console.info("Running:", "yarn", script);
console.info("Location:", target.location);
await spawnProcess("yarn", [script], {
cwd: target.location,
stdio: "inherit",
});
};

await execute();
}

await execute();

return 0;
}

Expand Down
7 changes: 5 additions & 2 deletions tests/bundlers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ test:

# create bundles
build:
make vite webpack
make vite webpack esbuild

vite:
npx vite build

webpack:
npx webpack
npx webpack

esbuild:
npx esbuild ./source.ts --bundle --outfile=./dist/esbuild-dist.js --format=esm --tree-shaking=true
60 changes: 54 additions & 6 deletions tests/bundlers/test.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,25 @@ const viteDist = {
name: "vite",
content: fs.readFileSync(path.join(__dirname, "dist", "vite-dist.js"), "utf-8"),
};
const esbuildDist = {
name: "esbuild",
content: fs.readFileSync(path.join(__dirname, "dist", "esbuild-dist.js"), "utf-8"),
};

for (const { content: fileContents, name } of [webpackDist, viteDist]) {
console.log(name);
for (const { content: fileContents, name } of [webpackDist, viteDist, esbuildDist]) {
console.log("================", name, "================");

const contentSize = fileContents.replaceAll(/\s+/g, "").length;
const callsToClassBuilder = fileContents.match(/\.classBuilder\(\)/g);
const runtimeConfig = fileContents.match(/runtime: "browser"/);
const callsToClassBuilder = fileContents.match(/\.classBuilder\(\)/g) || [];
const runtimeConfig = fileContents.match(/runtime: "browser"/) || [];

const serializers = fileContents.match(/(var|const) se_/g) || [];
const operationSchemas = fileContents.match(/ op\(/g) || [];
const structSchemas = fileContents.match(/ struct\(/g) || [];

try {
assert(contentSize < 1_000_000);
console.info(`✅ content size is under 1M char.`);
console.info(`✅ content size is under 1M char. ${contentSize.toLocaleString()}`);
} catch (e) {
throw new Error("Content size should be less than 1M characters.");
}
Expand All @@ -33,7 +41,9 @@ for (const { content: fileContents, name } of [webpackDist, viteDist]) {
assert(callsToClassBuilder.length <= 2); // only GetObject and CreateSession should be present.
console.info(`✅ two commands bundled (tree shaken).`);
} catch (e) {
throw new Error("there should only be 2 calls to the Command classBuilder. Tree-shaking failure?");
throw new Error(
`there should only be 2 calls to the Command classBuilder, got ${callsToClassBuilder.length}. Tree-shaking failure?`
);
}

try {
Expand All @@ -42,4 +52,42 @@ for (const { content: fileContents, name } of [webpackDist, viteDist]) {
} catch (e) {
throw new Error("the browser runtimeConfig should be present in the bundle.");
}

console.log("serializers", serializers.length);
console.log("operationSchemas", operationSchemas.length);
console.log("structSchemas", structSchemas.length);
}

// Model-ignorant codegen expected output:
// problems: webpack fails to tree shake serde functions.
/*
================ webpack ================
✅ content size is under 1M char. 628,148
✅ two commands bundled (tree shaken).
✅ runtimeConfig is browser.
serializers 250
operationSchemas 11
================ vite ================
✅ content size is under 1M char. 341,346
✅ two commands bundled (tree shaken).
✅ runtimeConfig is browser.
serializers 2
operationSchemas 10
*/

// Schema serde expected output:
// problems: both bundlers fail to tree-shake schemas (fix WIP).
/*
================ webpack ================
✅ content size is under 1M char. 557,102
✅ two commands bundled (tree shaken).
✅ runtimeConfig is browser.
serializers 0
operationSchemas 116
================ vite ================
✅ content size is under 1M char. 459,392
✅ two commands bundled (tree shaken).
✅ runtimeConfig is browser.
serializers 0
operationSchemas 115
*/
2 changes: 2 additions & 0 deletions tests/bundlers/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default defineConfig({
// Provide global variables to use in the UMD build
// for externalized deps
globals: {},
// to get an easier aggregate accounting of bundle contents
inlineDynamicImports: true,
},
},
minify: false,
Expand Down
8 changes: 8 additions & 0 deletions tests/bundlers/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default {
mode: "production",
entry: "./source.ts",
target: "web",
output: {
path: path.resolve(__dirname, "dist"),
filename: "webpack-dist.js",
library: "dist",
},
optimization: {
minimize: false,
splitChunks: false,
runtimeChunk: false,
sideEffects: true,
usedExports: true,
},
stats: {
optimizationBailout: false,
},
};
Loading