
Let's say you get something like this when invoking one of your NodeJS Lambda Function. In this example, the Lambda Function cannot import the nodemailer module.
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'nodemailer' imported from /var/task/index.mjs
To resolve this
- Use npm (NodeJS Package Manager) to install the package and create a zip archive
- Use the aws lambda publish-layer-version command to create a Lambda Layer using the .zip file.
According to https://docs.aws.amazon.com/lambda/latest/dg/packaging-layers.html:
Lambda loads the layer content into the /opt directory of that execution environment.
For each Lambda runtime, the PATH variable already includes specific folder paths within the /opt directory.
To ensure that your layer content gets picked up by the PATH variable, include the content in the following folder paths:
In other words, when you create the .zip file, the base directory in the .zip file must be "nodejs/node_modules/" or "nodejs/node<version>/nodemodules/" (such as nodejs/node20/nodemodules/) so that when the .zip file is extracted the files in the .zip file are extracted to /opt/nodejs/node_modules or /opt/nodejs/node<version>/node_modules/.
On a Linux system, using the same version of NodeJS as is being used by your Lambda Function let's create a directory named "nodejs".
mkdir /tmp/nodejs
And then move into the temporary directory.
cd /tmp/nodejs
And install the packages needed by your Lambda Function (nodemailer in this example).
npm install nodemailer
At this point, the /tmp/nodejs directory should contain the following.
~]$ ls -l /tmp/nodejs
drwxr-xr-x 3 john.doe john.doe 80 Jul 11 20:45 node_modules
-rw-r--r-- 1 john.doe john.doe 56 Jul 11 20:45 package.json
-rw-r--r-- 1 john.doe john.doe 489 Jul 11 20:45 package-lock.json
Now move back into the /tmp directory.
cd /tmp
And use the zip command to create a .zip file. The .zip file can be named anything you want. But it is very important that this is done in the directory below the "nodejs" directory so that the .zip file contains every file and directory at and below the "nodejs" directory.
zip --recurse-path /tmp/nodemailer.zip nodejs
Now you can use the aws lambda publish-layer-version command to create a Lambda Layer using the .zip file.
aws lambda publish-layer-version --layer-name nodejs-nodemailer --zip-file fileb://nodemailer.zip --compatible-runtimes nodejs20.x
Did you find this article helpful?
If so, consider buying me a coffee over at