Search code examples
amazon-web-servicesaws-lambdaaws-cdk

ES6 imports from CDK-constructed NodeJs 20.x AWS Lambda with inline code


For e.g. quick and dirty listeners I've used lambdas on the Node.js 18.x. Now with Node.js 20.x I tried to ES6 imports etc but I can't get it to work since I've understood that I would have to

a) include a package.json with type=module and multiple files doesn't work with inline code or b) have the handler be index.mjs but it becomes index.js automatically

Have I understood the restrictions wrong or if I have not, is there some workaround that would allow for the quick, single-file inline-code-lambda to be marked as ES6?

I'm using the method Code.fromInline in CDK to create the lambda.


Solution

  • Is there some workaround that would allow for the quick, single-file inline-code-lambda to be marked as ES6?

    This code works perfectly with Node.js 20.x, when saved to the single file index.mjs in the root folder, and the handler set to index.handler:

    import { readdir } from 'node:fs/promises';
    
    export const handler = async () => {
      const files = await readdir("/");
      console.log(files);
    }
    

    This lines up with what the documentation says:

    By default, Lambda treats files with the .js suffix as CommonJS modules. Optionally, you can designate your code as an ES module. You can do this in two ways: specifying the type as module in the function's package.json file, or by using the .mjs file name extension. In the first approach, your function code treats all .js files as ES modules, while in the second scenario, only the file you specify with .mjs is an ES module. You can mix ES modules and CommonJS modules by naming them .mjs and .cjs respectively, as .mjs files are always ES modules and .cjs files are always CommonJS modules.


    As for creating the function from CDK, it seems you're hitting a platform limitation. CDK works by transforming your code into a CloudFormation stack, and in CloudFormation, there is no way to specify the name or the extension of the handler file, if you're using inline code:

    ZipFile

    (Node.js and Python) The source code of your Lambda function. If you include your function source inline with this parameter, AWS CloudFormation places it in a file named index and zips it to create a deployment package. This zip file cannot exceed 4MB. For the Handler property, the first part of the handler identifier must be index. For example, index.handler.

    There's an open issue on CDK about this.