Skip to content

Commit

Permalink
feat(lambda-nodejs): custom bundling image (aws#10270)
Browse files Browse the repository at this point in the history
Add option to supply a custom bundling image.

Closes aws#10194


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored Sep 14, 2020
1 parent 19638a6 commit a2174a4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
16 changes: 16 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ This file is used as "entry" for [Parcel](https://parceljs.org/). This means tha
automatically transpiled and bundled whether it's written in JavaScript or TypeScript.

Alternatively, an entry file and handler can be specified:

```ts
new lambda.NodejsFunction(this, 'MyFunction', {
entry: '/path/to/my/file.ts', // accepts .js, .jsx, .ts and .tsx files
Expand All @@ -56,6 +57,7 @@ new lambda.NodejsFunction(this, 'my-handler', {
```

Use the `buildArgs` prop to pass build arguments when building the bundling image:

```ts
new lambda.NodejsFunction(this, 'my-handler', {
buildArgs: {
Expand All @@ -64,6 +66,20 @@ new lambda.NodejsFunction(this, 'my-handler', {
});
```

Use the `bundlingDockerImage` prop to use a custom bundling image:

```ts
new lambda.NodejsFunction(this, 'my-handler', {
bundlingDockerImage: dk.BundlingDockerImage.fromAsset('/path/to/Dockerfile'),
});
```

This image should have Parcel installed at `/`. If you plan to use `nodeModules` it
should also have `npm` or `yarn` depending on the lock file you're using.

Use the [default image provided by `@aws-cdk/aws-lambda-nodejs`](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-lambda-nodejs/parcel/Dockerfile)
as a source of inspiration.

### Project root
The `NodejsFunction` tries to automatically determine your project root, that is
the root of your node project. This is usually where the top level `node_modules`
Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/lib/bundlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class LocalBundler implements cdk.ILocalBundling {
}

interface DockerBundlerProps extends BundlerProps {
bundlingDockerImage?: cdk.BundlingDockerImage;
buildImage?: boolean;
buildArgs?: { [key: string]: string };
runtime: Runtime;
Expand All @@ -91,7 +92,7 @@ export class DockerBundler {

constructor(props: DockerBundlerProps) {
const image = props.buildImage
? cdk.BundlingDockerImage.fromAsset(path.join(__dirname, '../parcel'), {
? props.bundlingDockerImage ?? cdk.BundlingDockerImage.fromAsset(path.join(__dirname, '../parcel'), {
buildArgs: {
...props.buildArgs ?? {},
IMAGE: props.runtime.bundlingDockerImage.image,
Expand Down
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ export interface ParcelBaseOptions {
* @default false
*/
readonly forceDockerBundling?: boolean;

/**
* A custom bundling Docker image.
*
* This image should have Parcel installed at `/`. If you plan to use `nodeModules`
* it should also have `npm` or `yarn` depending on the lock file you're using.
*
* See https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-lambda-nodejs/parcel/Dockerfile
* for the default image provided by @aws-cdk/aws-lambda-nodejs.
*
* @default - use the Docker image provided by @aws-cdk/aws-lambda-nodejs
*/
readonly bundlingDockerImage?: cdk.BundlingDockerImage;
}

/**
Expand Down Expand Up @@ -189,6 +202,7 @@ export class Bundling {
relativeEntryPath,
cacheDir: options.cacheDir,
environment: options.parcelEnvironment,
bundlingDockerImage: options.bundlingDockerImage,
buildImage: !LocalBundler.runsLocally || options.forceDockerBundling,
buildArgs: options.buildArgs,
parcelVersion: options.parcelVersion,
Expand Down
29 changes: 23 additions & 6 deletions packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ const writeFileSyncMock = jest.spyOn(fs, 'writeFileSync').mockReturnValue();
const existsSyncOriginal = fs.existsSync;
const existsSyncMock = jest.spyOn(fs, 'existsSync');
const originalFindUp = util.findUp;
const findUpMock = jest.spyOn(util, 'findUp').mockImplementation((name: string, directory) => {
if (name === 'package.json') {
return path.join(__dirname, '..');
}
return originalFindUp(name, directory);
});
const fromAssetMock = jest.spyOn(BundlingDockerImage, 'fromAsset');

let findUpMock: jest.SpyInstance;
beforeEach(() => {
jest.clearAllMocks();
findUpMock = jest.spyOn(util, 'findUp').mockImplementation((name: string, directory) => {
if (name === 'package.json') {
return path.join(__dirname, '..');
}
return originalFindUp(name, directory);
});
});

test('Parcel bundling', () => {
Expand Down Expand Up @@ -317,3 +318,19 @@ test('Project root detection', () => {
expect(findUpMock).toHaveBeenNthCalledWith(3, LockFile.NPM);
expect(findUpMock).toHaveBeenNthCalledWith(4, 'package.json');
});

test('Custom bundling docker image', () => {
Bundling.parcel({
entry: '/project/folder/entry.ts',
projectRoot: '/project',
runtime: Runtime.NODEJS_12_X,
bundlingDockerImage: BundlingDockerImage.fromRegistry('my-custom-image'),
});

expect(Code.fromAsset).toHaveBeenCalledWith('/project', {
assetHashType: AssetHashType.BUNDLE,
bundling: expect.objectContaining({
image: { image: 'my-custom-image' },
}),
});
});

0 comments on commit a2174a4

Please sign in to comment.