From 56ef9f43c5d8a298e3a7b565af09008502f3f204 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Mon, 14 Dec 2020 09:48:27 +0100 Subject: [PATCH 1/2] feat(lambda-nodejs): expose more esbuild options Expose [`logLevel`](https://esbuild.github.io/api/#log-level) and [`keepNames`](https://esbuild.github.io/api/#keep-names). Closes #12046 --- packages/@aws-cdk/aws-lambda-nodejs/README.md | 5 ++- .../aws-lambda-nodejs/lib/bundling.ts | 2 + .../@aws-cdk/aws-lambda-nodejs/lib/types.ts | 39 +++++++++++++++++++ .../aws-lambda-nodejs/test/bundling.test.ts | 34 ++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 1a84a58440f6c..628bf21331ad9 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -132,7 +132,8 @@ Docker container even if `esbuild` is available in your environment. This can be ## Configuring `esbuild` The `NodejsFunction` construct exposes some [esbuild options](https://esbuild.github.io/api/#build-api) -via properties under `bundling`: `minify`, `sourceMap`, `target` and `loader`. +via properties under `bundling`: `minify`, `sourceMap`, `target`, `loader`, `logLevel` and +`keepNames`. ```ts new lambda.NodejsFunction(this, 'my-handler', { @@ -143,6 +144,8 @@ new lambda.NodejsFunction(this, 'my-handler', { loader: { // Use the 'dataurl' loader for '.png' files '.png': 'dataurl', }, + logLevel: LogLevel.SILENT, // defaults to LogLevel.WARNING + keepNames: true, // defaults to false }, }); ``` diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 404a29b2fae60..2620a37a81f67 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -138,6 +138,8 @@ export class Bundling implements cdk.BundlingOptions { ...this.props.sourceMap ? ['--sourcemap'] : [], ...this.externals.map(external => `--external:${external}`), ...loaders.map(([ext, name]) => `--loader:${ext}=${name}`), + ...this.props.logLevel ? [`--log-level=${this.props.logLevel}`] : [], + ...this.props.keepNames ? ['--keep-names'] : [], ].join(' '); let depsCommand = ''; diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts index 4f7b6505facfa..e71d6adbfee0c 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts @@ -41,6 +41,31 @@ export interface BundlingOptions { */ readonly loader?: { [ext: string]: string }; + /** + * Log level for esbuild + * + * @default LogLevel.WARNING + */ + readonly logLevel?: LogLevel; + + /** + * Whether to preserve the original `name` values even in minified code. + * + * In JavaScript the `name` property on functions and classes defaults to a + * nearby identifier in the source code. + * + * However, minification renames symbols to reduce code size and bundling + * sometimes need to rename symbols to avoid collisions. That changes value of + * the `name` property for many of these cases. This is usually fine because + * the `name` property is normally only used for debugging. However, some + * frameworks rely on the `name` property for registration and binding purposes. + * If this is the case, you can enable this option to preserve the original + * `name` values even in minified code. + * + * @default false + */ + readonly keepNames?: boolean; + /** * Environment variables defined when bundling runs. * @@ -152,3 +177,17 @@ export interface ICommandHooks { */ afterBundling(inputDir: string, outputDir: string): string[]; } + +/** + * Log level for esbuild + */ +export enum LogLevel { + /** Show everything */ + INFO = 'info', + /** Show warnings and errors */ + WARNING = 'warning', + /** Show errors only */ + ERROR = 'error', + /** Show nothing */ + SILENT = 'silent', +} diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index 741501afd9551..3f999de35c07c 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -5,6 +5,7 @@ import { Code, Runtime } from '@aws-cdk/aws-lambda'; import { AssetHashType, BundlingDockerImage } from '@aws-cdk/core'; import { version as delayVersion } from 'delay/package.json'; import { Bundling } from '../lib/bundling'; +import { LogLevel } from '../lib/types'; import * as util from '../lib/util'; jest.mock('@aws-cdk/aws-lambda'); @@ -147,6 +148,39 @@ test('esbuild bundling with externals and dependencies', () => { }); }); +test('esbuild bundling with esbuild options', () => { + Bundling.bundle({ + entry, + depsLockFilePath, + runtime: Runtime.NODEJS_12_X, + minify: true, + sourceMap: true, + target: 'es2020', + loader: { + '.png': 'dataurl', + }, + logLevel: LogLevel.SILENT, + keepNames: true, + forceDockerBundling: true, + }); + + // Correctly bundles with esbuild + expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), { + assetHashType: AssetHashType.OUTPUT, + bundling: expect.objectContaining({ + command: [ + 'bash', '-c', + [ + 'npx esbuild --bundle /asset-input/lib/handler.ts', + '--target=es2020 --platform=node --outfile=/asset-output/index.js', + '--minify --sourcemap --external:aws-sdk --loader:.png=dataurl', + '--log-level=silent --keep-names', + ].join(' '), + ], + }), + }); +}); + test('Detects yarn.lock', () => { const yarnLock = path.join(__dirname, '..', 'yarn.lock'); Bundling.bundle({ From 50e6b2e8b37edbfbc21eb9419886316d93543044 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Mon, 14 Dec 2020 10:29:35 +0100 Subject: [PATCH 2/2] update README --- packages/@aws-cdk/aws-lambda-nodejs/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 628bf21331ad9..aceb450596bb5 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -132,8 +132,7 @@ Docker container even if `esbuild` is available in your environment. This can be ## Configuring `esbuild` The `NodejsFunction` construct exposes some [esbuild options](https://esbuild.github.io/api/#build-api) -via properties under `bundling`: `minify`, `sourceMap`, `target`, `loader`, `logLevel` and -`keepNames`. +via properties under `bundling`: ```ts new lambda.NodejsFunction(this, 'my-handler', {