Lambda layers node_modules
Solution 1
How are you running your lambda? If via sam cli, something like the below has worked for me as my template.yaml
...
example template
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: example of node.js lambda function using layer for dependencies
Resources:
ExampleFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs8.10
CodeUri: nodejs/
Handler: src/event.handler
Layers:
- !Ref NodeModulesLayer
NodeModulesLayer:
Type: AWS::Serverless::LayerVersion
Properties:
Description: full set of function dependencies
ContentUri: ./
CompatibleRuntimes:
- nodejs6.10
- nodejs8.10
LicenseInfo: 'Available under the MIT-0 license.'
RetentionPolicy: Retain
pointing to local layer
The SAM developer guide includes a page on Working with Layers. At the time I'm writing this, they don't really get into how to reference layers at local file paths, and instead focus on references to remotely hosted layers.
The aspect I found tricky is that the directory structure of a node.js layer is expected to be ...
nodejs/
node_modules/
... which means that in order for your locally installed node_modules
directory to work as a layer, your package.json
file must be nested inside a folder named nodejs
.
Note the paths in the above example template.yaml
:
-
ExampleFunction.Properties.CodeUri
is set tonodejs/
-
ExampleFunction.Properties.Handler
should be set to the path to your handler file, relative tonodejs/
. -
NodeModulesLayer.Properties.ContentUri
is set to the folder that contains both thetemplate.yaml
file and thenodejs
dir.
Which means my example is assuming the following structure ...
nodejs/
node_modules/
src/
event.js
package.json
template.yaml
preserve sam build support
One additional gotcha to be wary of ...
With respect to defining your function resource in template.yaml
, there's some "flexibility" in terms of which parts of the path you put in CodeUri
vs Handler
. In some cases, doing ...
Properties:
CodeUri: nodejs/src/
Handler: event.handler
... works just as well as doing ...
Properties:
CodeUri: nodejs/
Handler: src/event.handler
BUT, if you're using the sam build
command, the former will NOT work. That command expects to find package.json
inside of the CodeUri
directory. So, stick with CodeUri: nodejs/
and use the Handler
value to navigate through any additional folder hierarchy necessary to reaching your handler.
Solution 2
Try this, simple example how to set up lambda layer in nodejs:
https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e
Related videos on Youtube
James Gunn
Updated on September 15, 2022Comments
-
James Gunn about 1 year
I am creating a lambda layer, bundling up some dependencies, including node_modules. I am successfully creating a layer but when i try to require a module from my code, the console is telling me that the module cannot be found. Here is the code
var Promise = require('promise'); module.exports.handler = function(event, context, callback) { new Promise(function (resolve, reject) { setTimeout(function() { callback(null, "helloWorld2"); }, 9000); }); };
How can I reference node modules from a layer???
-
James Gunn almost 5 yearsWhat if i'm using an older version of node? I'm well aware that promises are built in to newer versions of node. please keep on topic
-
-
Naphtali Gilead about 4 yearsThis works great when I build, but when I pack it using sam, it packs the node_modules twice. Once into my function code and the other into a layer. @RH Becker, do you have a suggestion on how to resolve this?
-
RH Becker about 4 years@NaphtaliGilead: I don't. My recent work hasn't involved sam. If, when I eventually get back to it, I come across any good approaches, I'll share. Please do the same, if you figure it out.