aws-esm-modules-layer-support icon indicating copy to clipboard operation
aws-esm-modules-layer-support copied to clipboard

Help needed in for lambda layers

Open Raunak-Agrawal opened this issue 3 years ago • 4 comments

I am trying to migrate ES5 Nodejs lambda to ES6. It works fine with normal function but doesn't work with lambda layers. We are not using CDK, but basic SAM template for deploying via scripts. Can you help out with it?

Raunak-Agrawal avatar Mar 31 '22 14:03 Raunak-Agrawal

Is it possible to post your SAM Template and bundle script, or create a repo with a code reference?

The idea is to create/include a symbolic link into your bundled function that points to the node_modules layer path.

For example using *nix commands you can create a symlink like this

cd directory-with-function-code
 ln -s /opt/nodejs/node_modules node_modules
zip --symlinks -r function.zip .

vibe avatar Apr 01 '22 12:04 vibe

I created a reference repo here: Github Currently we are using ES5 and also we are using lambda layers for node_modules as well as common shared utilities as shown in above repo.

We are also using SAM commands to test things locally: For eg. sam local invoke <function-name>

Can you tell me what steps should I follow to test lambda with layers locally as well as additional step during bundling step of the code to deploy it? (Since we don't bundle node_modules in our deployment build, will that symlinking still work?) Currently the code is using ES5, but we need to convert it to ES6.

How does the approach you said above work? For testing purpose, We generally upload a layer to lambda from aws console and then remaining source code (such as main.js in this case) is uploaded inside function code in AWS Lambda.

I believe I am missing something here. Could you please share some steps here? If possible, can you try it out above code on a feature branch and share your inputs?

Raunak-Agrawal avatar Apr 01 '22 18:04 Raunak-Agrawal

Any update on this?

Raunak-Agrawal avatar Apr 03 '22 01:04 Raunak-Agrawal

@Raunak-Agrawal I cloned your repo and attempted to load an ES Module, sadly it looks like the SAM cli does not actually support loading ES Modules the way the production lambda runtime does.

{
    "errorType": "Error",
    "errorMessage": "Must use import to load ES Module: /var/task/getUsers.js\nrequire() of ES modules is not supported.\nrequire() of /var/task/getUsers.js from /var/runtime/UserFunction.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.\nInstead rename getUsers.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/package.json.\n",
    "trace": ["Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /var/task/getUsers.js", "require() of ES modules is not supported.", "require() of /var/task/getUsers.js from /var/runtime/UserFunction.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.", "Instead rename getUsers.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/package.json.", "", "    at new NodeError (internal/errors.js:322:7)", "    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1102:13)", "    at Module.load (internal/modules/cjs/loader.js:950:32)", "    at Function.Module._load (internal/modules/cjs/loader.js:790:12)", "    at Module.require (internal/modules/cjs/loader.js:974:19)", "    at require (internal/modules/cjs/helpers.js:101:18)", "    at _tryRequire (/var/runtime/UserFunction.js:186:10)", "    at _loadUserApp (/var/runtime/UserFunction.js:197:12)", "    at Object.module.exports.load (/var/runtime/UserFunction.js:242:17)", "    at Object.<anonymous> (/var/runtime/index.js:43:30)"]
}

The issue is the images UserFunction.js which is trying to load the ES Module with require().

That being said, I'm sure there's a way to work around it, but been pretty busy atm.

All things aside, as long as the symlink exists in the zip that you upload to the AWS Console, the symlink and esm combo will work as intended.

vibe avatar Apr 03 '22 03:04 vibe