Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a Node 14.X program into an AWS Node 12.X Lambda function

My Goal

Take a node program (a command-line server-side program, not a web application) and deploy it as a lambda function in AWS.

Background: my node development environment/approach

  • Node 14.X on my MacBook Pro: version 14.2.0, in which ECMAScript module support is on by default
  • Developing my software as ES6 modules as follows:
    • Putting type: module in my package.json file
    • Using the .js extension rather than .mjs and .cjs extensions (because VS Code intellisense does not play nice with the multi-extension approach )
    • As this is a back-end program, I am not doing any transpiration or bundling (currently no Babel or Webpack)

Creating the lambda function

  • Using latest node env supported by AWS (12.X)
  • From what I can tell in the AWS lambda environment:
    • The entry point is hard-coded in this case (index.js)
      • There’s no way for me to pass command line arguments to node
    • If I try to run my code unchanged (with type: module), it fails as expected, because AWS node is trying to ‘require’ my ES6 module:
      • “Must use import to load ES Module: /var/task/index.js\nrequire() of ES modules is not supported. Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /var/task/package.json.”
    • If I try to change extensions on files to be explicit, AWS gags because it hard-codes the entry point to be ‘index.js’
    • If I naively remove the type:module from package.json, it fails as expected because it wants everything to be CommonJS:
      • “SyntaxError: Cannot use import statement outside a module"

Where I need help

From a couple hours of reading/research I’ve done, it seems like these are my options??:

  1. Rewrite my code to use CommonJS (undesirable, I want to use the modern features/approach)
  2. Set up either babel or a bundler like WebPack to convert my ES6 modules into CommonJS, and dump the converted code into the lambda
  3. Use ‘esm’

My Questions

  1. Am I correct to be going ‘all in’ on modules in my own code?
  2. Which approach above: #1, #2, #3 — or something else — is the easiest path to success here and the ‘proper’ approach?

Thank you!

like image 491
stitus Avatar asked Jul 03 '20 20:07

stitus


People also ask

What version of node does AWS Lambda use?

You can now develop AWS Lambda functions using the Node. js 16 runtime. This version is in active LTS status and considered ready for general use.


Video Answer


1 Answers

Personally, I'd go with the transpile approach. That way you can continue to write the code in the way you want to and output something that lambda is happy with.

I write lambdas in TypeScript and compile to lambda compatible JavaScript (ES2018).

There are various deployment tools - SAM, Serverless amongst others - but take a look at claudiajs, the deployment options make it easy to specify the file that contains your entry point and the name of the function within that file.

Also, in terms of sending data into the lambda as with a command line, that could come from the event that ultimately calls the lambda. This event can contain all the same information as your command line arguments.

like image 74
Ross Coundon Avatar answered Oct 08 '22 09:10

Ross Coundon