Skip to content

Commit

Permalink
feat(lambda-nodejs): Expose optional props for advanced usage of esbu…
Browse files Browse the repository at this point in the history
…ild (#12123)

1. Normally the build API automatically discovers tsconfig.json files and reads their contents during a build. However, we can also configure a custom tsconfig.json file to use instead for advanced use cases.
 
2. Added option to generate meta-file.

3. Added option to add comments in the bundled files 

Closes [12122](#12122)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
hassanazharkhan committed Dec 21, 2020
1 parent 23d10df commit ecc98ac
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
4 changes: 4 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/README.md
Expand Up @@ -145,6 +145,10 @@ new lambda.NodejsFunction(this, 'my-handler', {
},
logLevel: LogLevel.SILENT, // defaults to LogLevel.WARNING
keepNames: true, // defaults to false
tsconfig: 'custom-tsconfig.json' // use custom-tsconfig.json instead of default,
metafile: true, // include meta file, defaults to false
banner : '/* comments */', // by default no comments are passed
footer : '/* comments */', // by default no comments are passed
},
});
```
Expand Down
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Expand Up @@ -54,6 +54,7 @@ export class Bundling implements cdk.BundlingOptions {
public readonly local?: cdk.ILocalBundling;

private readonly relativeEntryPath: string;
private readonly relativeTsconfigPath?: string;
private readonly externals: string[];

constructor(private readonly props: BundlingProps) {
Expand All @@ -64,6 +65,10 @@ export class Bundling implements cdk.BundlingOptions {
const projectRoot = path.dirname(props.depsLockFilePath);
this.relativeEntryPath = path.relative(projectRoot, path.resolve(props.entry));

if (props.tsconfig) {
this.relativeTsconfigPath = path.relative(projectRoot, path.resolve(props.tsconfig));
}

this.externals = [
...props.externalModules ?? ['aws-sdk'], // Mark aws-sdk as external by default (available in the runtime)
...props.nodeModules ?? [], // Mark the modules that we are going to install as externals also
Expand Down Expand Up @@ -140,6 +145,10 @@ export class Bundling implements cdk.BundlingOptions {
...loaders.map(([ext, name]) => `--loader:${ext}=${name}`),
...this.props.logLevel ? [`--log-level=${this.props.logLevel}`] : [],
...this.props.keepNames ? ['--keep-names'] : [],
...this.relativeTsconfigPath ? [`--tsconfig=${pathJoin(inputDir, this.relativeTsconfigPath)}`] : [],
...this.props.metafile ? [`--metafile=${pathJoin(outputDir, 'index.meta.json')}`] : [],
...this.props.banner ? [`--banner='${this.props.banner}'`] : [],
...this.props.footer ? [`--footer='${this.props.footer}'`] : [],
].join(' ');

let depsCommand = '';
Expand Down
67 changes: 66 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
Expand Up @@ -66,6 +66,71 @@ export interface BundlingOptions {
*/
readonly keepNames?: boolean;

/**
* Normally the esbuild automatically discovers `tsconfig.json` files and reads their contents during a build.
*
* However, you can also configure a custom `tsconfig.json` file to use instead.
*
* This is similar to entry path, you need to provide path to your custom `tsconfig.json`.
*
* This can be useful if you need to do multiple builds of the same code with different settings.
*
* @example { 'tsconfig': 'path/custom.tsconfig.json' }
*
* @default - automatically discovered by `esbuild`
*/
readonly tsconfig? : string

/**
* This option tells esbuild to write out a JSON file relative to output directory with metadata about the build.
*
* The metadata in this JSON file follows this schema (specified using TypeScript syntax):
*
* ```typescript
* {
* outputs: {
* [path: string]: {
* bytes: number
* inputs: {
* [path: string]: { bytesInOutput: number }
* }
* imports: { path: string }[]
* exports: string[]
* }
* }
* }
* }
* ```
* This data can then be analyzed by other tools. For example,
* bundle buddy can consume esbuild's metadata format and generates a treemap visualization
* of the modules in your bundle and how much space each one takes up.
* @see https://esbuild.github.io/api/#metafile
* @default - false
*/
readonly metafile?: boolean

/**
* Use this to insert an arbitrary string at the beginning of generated JavaScript files.
*
* This is similar to footer which inserts at the end instead of the beginning.
*
* This is commonly used to insert comments:
*
* @default - no comments are passed
*/
readonly banner? : string

/**
* Use this to insert an arbitrary string at the end of generated JavaScript files.
*
* This is similar to banner which inserts at the beginning instead of the end.
*
* This is commonly used to insert comments
*
* @default - no comments are passed
*/
readonly footer? : string

/**
* Environment variables defined when bundling runs.
*
Expand All @@ -83,7 +148,7 @@ export interface BundlingOptions {

/**
* A list of modules that should be installed instead of bundled. Modules are
* installed in a Lambda compatible environnment only when bundling runs in
* installed in a Lambda compatible environment only when bundling runs in
* Docker.
*
* @default - all modules are bundled
Expand Down
8 changes: 7 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
Expand Up @@ -28,6 +28,7 @@ beforeEach(() => {

let depsLockFilePath = '/project/yarn.lock';
let entry = '/project/lib/handler.ts';
let tsconfig = '/project/lib/custom-tsconfig.ts';

test('esbuild bundling in Docker', () => {
Bundling.bundle({
Expand Down Expand Up @@ -161,6 +162,10 @@ test('esbuild bundling with esbuild options', () => {
},
logLevel: LogLevel.SILENT,
keepNames: true,
tsconfig,
metafile: true,
banner: '/* comments */',
footer: '/* comments */',
forceDockerBundling: true,
});

Expand All @@ -174,7 +179,8 @@ test('esbuild bundling with esbuild options', () => {
'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',
'--log-level=silent --keep-names --tsconfig=/asset-input/lib/custom-tsconfig.ts',
'--metafile=/asset-output/index.meta.json --banner=\'/* comments */\' --footer=\'/* comments */\'',
].join(' '),
],
}),
Expand Down

0 comments on commit ecc98ac

Please sign in to comment.