cdk-booster 1.0.1 → 1.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -90,56 +90,70 @@ async function bundle(lambdasEsBuildCommands) {
90
90
  const tempFolder = path.resolve(path.join(outputFolder, 'bundle'));
91
91
  let outputs = {};
92
92
  // Create build combinations grouped by identical build options to optimize bundling
93
- const allBuildCombinations = createBuildCombinations(lambdasEsBuildCommands);
94
- // Group by unique build option hashes to bundle functions with identical settings together
95
- const uniqueBuildHashes = new Set(allBuildCombinations.map((b) => b.buildOptionsHash));
93
+ const buildBatches = createBuildCombinations(lambdasEsBuildCommands);
96
94
  // Bundle each group of functions with identical build options
97
- await Promise.all(Array.from(uniqueBuildHashes).map(async (buildHash) => {
98
- const buildCombinations = allBuildCombinations.filter((b) => b.buildOptionsHash === buildHash);
99
- const buildOptions = buildCombinations[0].buildOptions;
100
- const entryPoints = buildCombinations.map((b) => b.entryPoint);
101
- const normalizedEsbuildArgs = normalizeEsbuildArgs(buildOptions.esbuildArgs);
102
- const esBuildOpt = {
103
- entryPoints,
104
- bundle: true,
105
- platform: 'node',
106
- outdir: tempFolder,
107
- target: buildOptions.target,
108
- format: buildOptions.format,
109
- minify: buildOptions.minify,
110
- sourcemap: buildOptions.sourcemap,
111
- sourcesContent: buildOptions.sourcesContent,
112
- external: buildOptions.external,
113
- loader: buildOptions.loader,
114
- define: buildOptions.define,
115
- logLevel: buildOptions.logLevel,
116
- keepNames: buildOptions.keepNames,
117
- tsconfig: buildOptions.tsconfig,
118
- banner: buildOptions.banner,
119
- footer: buildOptions.footer,
120
- mainFields: buildOptions.mainFields,
121
- inject: buildOptions.inject,
122
- alias: normalizedEsbuildArgs?.alias,
123
- drop: normalizedEsbuildArgs?.drop,
124
- pure: normalizedEsbuildArgs?.pure,
125
- logOverride: normalizedEsbuildArgs?.logOverride,
126
- // I need this to properly output bundled files
127
- entryNames: '[dir]/[name]-[hash]/index',
128
- metafile: true,
129
- outExtension: { '.js': '.mjs' },
95
+ const buildPromises = [];
96
+ let parallelCount = 0;
97
+ for (const buildBatch of buildBatches) {
98
+ const build = async () => {
99
+ parallelCount++;
100
+ try {
101
+ const buildOptions = buildBatch.buildOptions;
102
+ const entryPoints = buildBatch.entryPoints;
103
+ const normalizedEsbuildArgs = normalizeEsbuildArgs(buildOptions.esbuildArgs);
104
+ const esBuildOpt = {
105
+ entryPoints,
106
+ bundle: true,
107
+ platform: 'node',
108
+ outdir: tempFolder,
109
+ target: buildOptions.target,
110
+ format: buildOptions.format,
111
+ minify: buildOptions.minify,
112
+ sourcemap: buildOptions.sourcemap,
113
+ sourcesContent: buildOptions.sourcesContent,
114
+ external: buildOptions.external,
115
+ loader: buildOptions.loader,
116
+ define: buildOptions.define,
117
+ logLevel: buildOptions.logLevel,
118
+ keepNames: buildOptions.keepNames,
119
+ tsconfig: buildOptions.tsconfig,
120
+ banner: buildOptions.banner,
121
+ footer: buildOptions.footer,
122
+ mainFields: buildOptions.mainFields,
123
+ inject: buildOptions.inject,
124
+ alias: normalizedEsbuildArgs?.alias,
125
+ drop: normalizedEsbuildArgs?.drop,
126
+ pure: normalizedEsbuildArgs?.pure,
127
+ logOverride: normalizedEsbuildArgs?.logOverride,
128
+ // I need this to properly output bundled files
129
+ entryNames: '[dir]/[name]-[hash]/index',
130
+ metafile: true,
131
+ outExtension: { '.js': '.mjs' },
132
+ };
133
+ if (Logger.isVerbose()) {
134
+ Logger.verbose(`Bundling with options:`, JSON.stringify(esBuildOpt, null, 2), `following functions:\n - ${entryPoints.join('\n - ')}`);
135
+ }
136
+ else {
137
+ Logger.log(`Bundling:\n - ${entryPoints.join('\n - ')}`);
138
+ }
139
+ const buildingResults = await esbuild.build(esBuildOpt);
140
+ outputs = {
141
+ ...outputs,
142
+ ...buildingResults.metafile?.outputs,
143
+ };
144
+ }
145
+ finally {
146
+ parallelCount--;
147
+ }
130
148
  };
131
- if (Logger.isVerbose()) {
132
- Logger.verbose(`Bundling with options:`, JSON.stringify(esBuildOpt, null, 2), `following functions:\n - ${entryPoints.join('\n - ')}`);
133
- }
134
- else {
135
- Logger.log(`Bundling:\n - ${entryPoints.join('\n - ')}`);
149
+ const parallel = Configuration.config.parallel;
150
+ // if parallel is set, limit the number of parallel builds
151
+ if (parallel && parallel > 0 && parallelCount >= parallel) {
152
+ await Promise.race(buildPromises);
136
153
  }
137
- const buildingResults = await esbuild.build(esBuildOpt);
138
- outputs = {
139
- ...outputs,
140
- ...buildingResults.metafile?.outputs,
141
- };
142
- }));
154
+ buildPromises.push(build());
155
+ }
156
+ await Promise.all(buildPromises);
143
157
  Logger.log(`All functions have been bundled.`);
144
158
  return outputs;
145
159
  }
@@ -201,7 +215,7 @@ async function isSecondRun() {
201
215
  * @returns Array of build combinations with hashed build options
202
216
  */
203
217
  function createBuildCombinations(lambdasEsBuildCommands) {
204
- return lambdasEsBuildCommands.map((lambdasEsBuildCommand) => {
218
+ const buildCombinations = lambdasEsBuildCommands.map((lambdasEsBuildCommand) => {
205
219
  // Create a copy of the command without non-build-related properties
206
220
  const copy = {
207
221
  ...lambdasEsBuildCommand,
@@ -226,6 +240,33 @@ function createBuildCombinations(lambdasEsBuildCommands) {
226
240
  buildOptionsHash,
227
241
  };
228
242
  });
243
+ const buildBatches = [];
244
+ const batchSize = Configuration.config.batch;
245
+ // Group by unique build option hashes to bundle functions with identical settings together
246
+ const uniqueBuildHashes = new Set(buildCombinations.map((b) => b.buildOptionsHash));
247
+ for (const buildHash of uniqueBuildHashes) {
248
+ const buildBatch = buildCombinations.filter((b) => b.buildOptionsHash === buildHash);
249
+ let entryPoints = buildBatch.map((b) => b.entryPoint);
250
+ // unique entry points
251
+ entryPoints = Array.from(new Set(entryPoints));
252
+ // if batch size is set and if each buildOptionsHash has more than batchSize entries, split them
253
+ if (batchSize && entryPoints.length > batchSize) {
254
+ for (let i = 0; i < entryPoints.length; i += batchSize) {
255
+ const chunk = entryPoints.slice(i, i + batchSize);
256
+ buildBatches.push({
257
+ entryPoints: chunk,
258
+ buildOptions: buildBatch[0].buildOptions,
259
+ });
260
+ }
261
+ }
262
+ else {
263
+ buildBatches.push({
264
+ entryPoints,
265
+ buildOptions: buildBatch[0].buildOptions,
266
+ });
267
+ }
268
+ }
269
+ return buildBatches;
229
270
  }
230
271
  /**
231
272
  * Convert esbuildArgs with CLI-style keys into esbuild options object.
@@ -1,4 +1,4 @@
1
- import { Command } from 'commander';
1
+ import { Command, InvalidArgumentError } from 'commander';
2
2
  import { getVersion } from './version.mjs';
3
3
  /**
4
4
  * Get configuration from CLI arguments
@@ -10,6 +10,8 @@ export async function getConfigFromCliArgs() {
10
10
  const program = new Command();
11
11
  program.name('cdk-booster').description('CDK Booster').version(version);
12
12
  program.option('-v, --verbose', 'Verbose logging');
13
+ program.option('-b, --batch <number>', 'Number of Lambdas bundled in a batch with ESBuild', parseInteger);
14
+ program.option('-p, --parallel <number>', 'Number of parallel ESBuild processes. You usually do not need to change this.', parseInteger);
13
15
  program.arguments('<string>');
14
16
  program.parse(process.argv);
15
17
  const args = program.opts();
@@ -21,3 +23,10 @@ export async function getConfigFromCliArgs() {
21
23
  args.entryFile = entryFile;
22
24
  return args;
23
25
  }
26
+ function parseInteger(value) {
27
+ const parsedValue = parseInt(value, 10);
28
+ if (isNaN(parsedValue)) {
29
+ throw new InvalidArgumentError('Not a number.');
30
+ }
31
+ return parsedValue;
32
+ }
@@ -4,5 +4,14 @@ export type CbConfig = {
4
4
  * @default false
5
5
  */
6
6
  verbose?: boolean;
7
+ /** Number of Lambdas bundled in a batch with ESBuild
8
+ */
9
+ batch?: number;
10
+ /** Number of parallel ESBuild processes
11
+ */
12
+ parallel?: number;
13
+ /**
14
+ * Entry file
15
+ */
7
16
  entryFile: string;
8
17
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdk-booster",
3
- "version": "1.0.1",
3
+ "version": "1.1.0-alpha.2",
4
4
  "type": "module",
5
5
  "description": "Speed up AWS CDK's bundling of TypeScript/JavaScript Lambda handlers",
6
6
  "homepage": "https://www.cdkbooster.com",