Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lambda-nodejs): expose more esbuild options #12063

Merged
merged 5 commits into from
Dec 15, 2020
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
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +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` and `loader`.
via properties under `bundling`:

```ts
new lambda.NodejsFunction(this, 'my-handler', {
Expand All @@ -143,6 +143,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
},
});
```
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '';
Expand Down
39 changes: 39 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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',
}
34 changes: 34 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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({
Expand Down