Correct setup for multiple Lambda Functions using TypeScript/esbuild?
- Dominant language
- Python
- Stars
- 6.7k
- Forks
- 1.2k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 52
Description
This might be a bug report, but I think mainly its just a question: how can you set up a SAM CLI project for multiple Lambda Functions when using TypeScript/esbuild?
- The [original esbuild blog post](https://aws.amazon.com/blogs/compute/building-typescript-projects-with-aws-sam-cli/) and [sam init template for typescript](https://github.com/aws/aws-sam-cli-app-templates/tree/master/nodejs16.x/cookiecutter-aws-sam-hello-typescript-nodejs) show how to set up a project with _one_ Lambda Function.
- This [3rd party article](https://levelup.gitconnected.com/creating-an-aws-sam-cli-project-with-typescript-and-both-types-of-layers-dependencies-and-34da5efdaec8) and the [sam init template for Step Functions](https://github.com/aws/aws-sam-cli-app-templates/tree/master/nodejs16.x/cookiecutter-aws-sam-step-functions-sample-app) show how to set up a project for multiple Lambda Functions using _JavaScript_.
- However, I can not seem to find any resources on how to _combine_ these approaches, to build multiple Lambda Functions with TypeScript, particularly when there is also library code that the Functions must share.
## My Attempt
Folder structure:
```txt
src/
LambdaEntrypoints/
Function1.ts
Function2.ts
SharedLib1/
index.ts
SharedLib2/
index.ts
test/
SharedLib1/
SharedLib2/
package.json
tsconfig.json
samconfig.toml
template.yaml
```
tsconfig.json
```jsonc
{
"extends": "@tsconfig/node16/tsconfig.json",
"include": [
"src/**/*.ts",
"test/**/*.ts",
],
"compilerOptions": {
"outDir": "dist/",
"incremental": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"composite": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"esModuleInterop": true,
}
}
```
template.yaml
```yml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Architectures: [arm64]
Runtime: nodejs16.x
CodeUri: .
Timeout: 3
Tracing: Active
Resources:
Function1:
Type: AWS::Serverless::Function
Metadata:
BuildMethod: esbuild
BuildProperties:
UseNpmCi: true
Minify: true
Sourcemap: true
EntryPoints: [ src/LambdaEntrypoints/Function1.ts ]
Properties:
# FunctionName: Auto-generate
Handler: Function1.handleEvent
Function2:
Type: AWS::Serverless::Function
Metadata:
BuildMethod: esbuild
BuildProperties:
UseNpmCi: true
Minify: true
Sourcemap: true
EntryPoints: [ src/LambdaEntrypoints/Function2.ts ]
Properties:
# FunctionName: Auto-generate
Handler: Function2.handleEvent
```
`src/LambdaEntrypoints/Function1.ts` (or `Function2.ts`)
```ts
import { APIGatewayProxyEventV2, APIGatewayProxyResultV2 } from "aws-lambda";
// Other imports
export async function handleEvent(event: APIGatewayProxyEventV2): Promise {
// Do stuff
}
```
## Expected result
Running `sam build Function1 && sam local invoke Function1` (or equivalent for `Function2`) would successfully build and run my Lambda Function locally.
## Actual result
Build succeeds, generating this `.aws-sam` folder contents
```txt
build/
Function1/
Function1.js
Function1.js.map
Function2/
Function2.js
Function2.js.map
template.yaml
build.toml
```
But `sam local invoke Function1` fails with this output
```log
Invoking Function1.handleEvent (nodejs16.x)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs16.x:rapid-1.61.0-arm64.
Mounting /workspaces/Farmageddon/backend2/.aws-sam/build/Function1as /var/task:ro,delegated inside runtime container
START RequestId: bcc02ecf-4892-4702-ab63-c22fe7698b25 Version: $LATEST
2022-10-29T05:42:00.806Z undefined ERROR Uncaught Exception {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'Function1'\nRequire stack:\n- /var/runtime/index.mjs","stack":["Runtime.ImportModuleError: Error: Cannot find module 'Function1'","Require stack:","- /var/runtime/index.mjs"," at _loadUserApp (file:///var/runtime/index.mjs:1000:17)"," at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)"," at async start (file:///var/runtime/index.mjs:1200:23)"," at async file:///var/runtime/index.mjs:1206:1"]}
29 Oct 2022 05:42:01,072 [ERROR] (rapid) Init failed error=Runtime exited with error: exit status 129 InvokeID=
2022-10-29T05:42:03.102Z undefined ERROR Uncaught Exception {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'Function1'\nRequire stack:\n- /var/runtime/index.mjs","stack":["Runtime.ImportModuleError: Error: Cannot find module 'Function1'","Require stack:","- /var/runtime/index.mjs"," at _loadUserApp (file:///var/runtime/index.mjs:1000:17)"," at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)"," at async start (file:///var/runtime/index.mjs:1200:23)"," at async file:///var/runtime/index.mjs:1206:1"]}
END RequestId: ebb45e29-693a-46e1-ac8b-af1f3008cb4a
REPORT RequestId: ebb45e29-693a-46e1-ac8b-af1f3008cb4a Init Duration: 2.94 ms Duration: 4545.67 ms Billed Duration: 4546 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'Function1'\nRequire stack:\n- /var/runtime/index.mjs","trace":["Runtime.ImportModuleError: Error: Cannot find module 'Function1'","Require stack:","- /var/runtime/index.mjs"," at _loadUserApp (file:///var/runtime/index.mjs:1000:17)"," at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)"," at async start (file:///var/runtime/index.mjs:1200:23)"," at async file:///var/runtime/index.mjs:1206:1"]}vscode
```
Contributor guide
Assessment
This issue has not been assessed yet.