question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

lambda-nodejs to support custom Builder implementations

See original GitHub issue

The aws-lambda-nodejs module abstracts the package building into a Builder class. The package should support providing custom implementations for this class so other bundlers than parcel can be used, and more complex use cases are supported.

Use Case

  • The Builder has been converted to use Docker to solve certain issues, however using Docker might create issues in other areas (CI often runs in containers and Docker-in-Docker configurations can be complex)
  • Using other bundlers like zeit/ncc or webpack
  • Easier support for complex parcel configurations/plugins
  • Support for other bundling flows, like zip https://github.com/aws/aws-cdk/issues/6294

Proposed Solution

Keep the original Builder and BuilderOptions interface pre Docker

export interface BuilderOptions {
  readonly entry: string;
  readonly outDir: string;
  readonly global: string;
  readonly minify?: boolean;
  readonly sourceMaps?: boolean;
  readonly cacheDir?: string;
  readonly nodeVersion?: string;
}

Every Builder must implement the interface, but may extend the options and also might choose to discard the optional options for implementation.

Extend NodejsFunctionProps to include

export interface NodejsFunctionProps extends lambda.FunctionOptions {
  readonly builderFactory?: (props: BuilderOptions) => Builder;
  readonly additionalBuilderProps?: object;
}

builderFactory would receive a combination of mandatory and additional builder props:

builderFactory({...additionalBuilderProps, mandatoryBuilderProps})

If no builderFactory is provided, the class would fall back to a default implementation using parcel in docker.

Other

The Builder class interface seems to be stable enough. It survived the migration to Docker with few changes.

I’m not sure about the Design, especially if there’s something similar used in CDK elsewhere or a more suitable implementation.

Further changes to the Builder might make that class more extendable (e.g. the error handling).

Alternatives

The Builder factory could become a static method on the NodejsFunction class so extending the class might provide an alternative option (albeit less first class support).

class MyFunctionBundlerFunction extends lNodejsFunction {
  public static function getBuilder(props: BuilderOptions) {
    return new new Builder({
      ...props,
      someOtherOption: 'a-value',
    });
  }
}
  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change --> Maybe. I think it could be done either way. In order to support a better, future proof design a breaking change might be required.

This is a 🚀 Feature Request

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
jogoldcommented, May 6, 2020

The Builder class interface seems to be stable enough. It survived the migration to Docker with few changes.

We reverted the Docker migration for the moment (#7738) but I’m close to finding a fix for this. PR to come soon. Then we can maybe think about “generalizing” the Docker build concept for a Lambda function (I’ve been looking into this and it’s not easy to cover all cases).

For the moment the Builder is very Parcel specific… are we sure that we can find a good compromise between all these bundlers? If not then the interface could be just this:

export interface IBuilder {
  readonly handler: string;
  readonly outDir: string;
  build(): void;
}

which allows to do something like this for the constructor of the NodejsFunction

export class NodejsFunction extends lambda.Function {
  constructor(scope: cdk.Construct, id: string, props: NodejsFunctionProps) {
    // ...
    builder.build(); // build it

    super(scope, id, {
      ...props,
      code: lambda.Code.fromAsset(builder.outDir), // where did it build it?
      handler: builder.handler, // what did it build?
    });
  }
}

and use static methods (NodejsFunction.fromParcel(...)). The only thing that would be common is the automatic entry finding and some defaults?

2reactions
moltarcommented, Jun 17, 2020

This would be perfect for adding webpack support. I am really not liking the Parcel / Docker solution.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What Node.js Custom Runtime Brings and How We ...
Thundra NodeJS Custom Runtime lets you monitor your AWS Lambda Functions with no code change. Learn how we developed Thundra NodeJS Custom Runtime....
Read more >
Building Lambda functions with Node.js - AWS Documentation
You can run JavaScript code with Node.js in AWS Lambda. Lambda provides runtimes for Node.js that run your code to process events.
Read more >
Creating APIs with Node & AWS Lambda - Coder Society
In this article, you'll learn how to build an API fast and easily using Node.js, AWS Lambda, and AWS CDK. The Serverless Concept....
Read more >
Reviewing the AWS Lambda nodejs10.x runtime - Michael Hart
bootstrap is a shell script that launches node , spawned by /var/rapid/init in the same way that custom runtimes are. It sets up...
Read more >
GraphQL Code Libraries, Tools and Services
A highly customizable and versatile GraphQL client with which you add on features ... Preact, Svelte, and Vue, and is supported by GraphQL...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found