I'm starting a CDK lambda project which gets the source code like this:
code: lambda.Code.fromAsset("resources"),
handler: "synthetic_test.main",
There's a single javascript file synthetic_test.js in that folder.
This seems to work but I can't figure out how to make it so that I could do:
const axios = require("axios");
in that file.
For some reason it seems to be able to import:
const AWS = require("aws-sdk");
but nothing else.
I did yarn add axios which added it to the package.json of my CDK project. But that does not really seem to help the lambda a lot.
The AWS Lambda runtime environment includes native language libraries and the relevant language-specific AWS SDK.
It does not contain arbitrary third-party packages. You need to either package those dependencies with your code or create a Lambda Layer that includes the dependencies and configure your Lambda function to use the Lambda Layer.
To package CDK app dependencies, see @aws-cdk/aws-lambda-nodejs and here.
I went with packaging dependencies with my code
My cdk went to
// 👇 define PUT account function
const putAccountLambda = new lambda.Function(this, "put-account-lambda", {
runtime: lambda.Runtime.NODEJS_14_X,
handler: "main.handler",
code: lambda.Code.fromAsset(path.join(__dirname, "/../src/put-account/dist")),
environment: {
REGION,
ADMINS_TABLE,
ADMINS_TABLE_PARTITION_KEY,
HASH_ALG,
}
})
With dist being the folder with a packed main.js file. And this file has a handler entrypoint. I had to update the package.json of these lambdas with packed dependencies.
{
"name": "put-account",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode=production --env env=prod",
"build:dev": "webpack --mode=development --env env=dev"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.66.0",
"webpack-cli": "^4.9.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"aws-sdk": "^2.1058.0",
"crypto": "^1.0.1",
"uuid": "^8.3.2"
}
}
And I updated the package.json of my cdk project to these scripts.
"build": "tsc && npm run build:webpack",
"build:webpack": "for file in ./src/*; do (cd $file && npm i && npm run build) & done",
"build:beta": "tsc && npm run build:webpack:beta",
"build:webpack:beta": "for file in ./src/*; do (cd $file && npm i && npm run build:dev) & done",
Notice that my file structure is as follows:
./
bin
lib
src
package.json
With src holding the source code for my project's lambdas.
I am not sure if you are familiar with webpack, but I have divided my webpack configuration in common, dev, prod.
A dev webpack configuration is specially useful for debugging because otherwise you lose line numbers among other useful information when something goes wrong on runtime.