-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Hey! Thank you for awesome tool–it is amazing (yet magical a bit). Here I want to bring some attention to areas (with links to existing issues) where it is hard to use and customize SAM CLI. And, hopefully, start discussion for this topic.
TL;DR: Use Makefile builder to compile typescript to javascript. And I have step-by-step guide for that.
TypeScript has gained a lot of traction and popularity in last years both for frontend and backend usage. It gives us a lot of good things: protection against stupid bugs, code completion in editors, etc.
Unfortunately, AWS SAM CLI out-of-the-box doesn't have support for developing Lambda functions for NodeJS runtime in TypeScript (while Serverless framework does). Moreover, adding TypeScript to existing project is complicated because SAM CLI doesn't allow to add custom steps to default build process.
There are some manuals on how to add TypeScript support, add shared layers, and so on, but usually they tend to bring Webpack and replace sam build with some custom scripts that tries to mimic SAM CLI behavior. I feel that such approach is just isn't right.
In my opinion, this is how proper TypeScript support should look like:
- Keeping the local development experience mostly unchanged: no moving
package.jsonto other places or otherwise changing the directory structure before deployment. - No running
sam buildon every change in function handler code. - Keeping generated JS code as close to TS source as possible, preserving the file layout (don't bundle everything into a single file as webpack does).
- Keeping dependencies in a separate layer shared between related Lambdas. It makes deploys faster as you only need to update function code and not its dependencies. Also, Lambda functions have a size limit which can be easily surpassed with heavy dependencies; shared layers allow us to keep coloring between the lines.
- Keeping deploys unchanged:
sam buildandsam deploy, with no extra CLI magic.
In short, a Lambda with TypeScript and shared layers must behave the same way as a freshly generated Lambda on pure Node.js.
After all, I succeeded to set it up in a way that is not ideal yet, but that I like pretty much using Makefile builder as described in Building layers doc for details.
Basically it is:
build-ExampleFunction:
npm install
tsc
cp -r dist "$(ARTIFACTS_DIR)/"Where TypeScript source code is located in src/ directory, while both local and deployed lambda is instructed to search for handlers in dist/ directory that contains transpiled JavaScript:
# template.yml
Resources:
ExampleFunction:
Type: AWS::Serverless::Function
Metadata:
BuildMethod: makefile
Properties:
Handler: dist/handlers/example.exampleHandlerTo better document my approach, I've done following things:
- Blog post in my company's blog: Serverless TypeScript: A complete setup for AWS SAM Lambdas – Martian Chronicles.
- Example project: github.com/Envek/aws-sam-typescript-layers-example
- Cookiecutter template: github.com/Envek/cookiecutter-aws-sam-typescript-layers
However, there are some inconveniences left:
- It is hard to debug Makefile-based builds: New Makefile Output & Debugging #2006
- It is annoying to remove
.aws-samdirectory after every deploy to makesam local invokeandsam local start-apiuse local code instead of packaged one.
I hope that my research results and these artifacts will be useful to both SAM CLI users and its developers.
Is there any plans to add built-in support for TypeScript?