serverless-esbuild
serverless-esbuild copied to clipboard
Question: support for Lambda Layers in TypeScript?
I could't find any indication in the documentation, but does serverless-esbuild support lambda layers written in Typescript? There's currently an open issue with serverless-webpack (https://github.com/serverless-heaven/serverless-webpack/issues/556) which does not compile the TS into JS before packaging the layer.
I was hoping I could use this package to deploy may layers.
This could be an interesting thing to add. I think there would be a question around how to set entry points.
I think if they specify only a path, we should treat every file in there as an entry point. Though we should encourage people to specify what files they want as entry points.
If they have a nodejs folder we should leave it untouched to preserve the library dependency behaviour of lambda
Yes I agree. I think a convention would make sense here that if a layer points to a folder, then every file should be treated as entry point. If the layer points to a specific file like index.ts/js, then only this should be considered an entry point.
layers:
layerOne:
path: src/layers/one # take every file as entry point
name: layerOne
layerTwo:
path: src/layers/two/index.ts # take this file as entry point
name: layerTwo
Alternatively, the layers
property inside serverless.yml could be extended with an entries
property.
What would be a good starting point here? I found the [rootFileNames](https://github.com/floydspace/serverless-esbuild/blob/d9f9b41df87388dfd4d3f0d79997b4126fe2ecd3/src/index.ts#L190)
as point that must potentially be extended to return functions and layers.
What else needs to be considered?
Sounds like you're keen to contribute this, very nice! Some consideration will definitely need to be taken around packaging patterns + exclude.
A few questions come to mind:
- Should the
external
esbuild functionality affect the packaging of layers? - What if the user wants to pack some static files in the layer? Should they use package patterns? Or should we include them by default when they specify a path? (Some documentation would definitely be needed around this)
Need to also handle ignoring lambda layers which are ARNs.
Might need to check with the big man Floydspace himself. I've been using this for about a couple months only.
Hi @chriszirkel @samchungy what is the common scenario of using layers? So far in my experience, I have used layers to push there some heavy artifacts (chrome binary from puppeteer for instance) or pre-installed node_modules folder. Could you share your use case, do you push there like shared helper functions? then I have a couple of questions: do you need them to be bundled or just transpiled? Are layers one
and two
are managed by separate package.json
s, or the same with the app?
And apparently, lambdas reference the code from layers, so we also somehow have to avoid bundling these files, currently, it's not supported, only packages from node_modules can be marked as external
.
Ah yep that makes sense. I haven't used layers in a while but my usecase was similar. I would pre-install node_modules
too. So I guess we can ignore external
.
I think if we make users manage their own lambda layer nodejs
folder & nodejs/package.json
it would make more sense. Then we don't need to worry about it. I think the logic should be just to copy over the nodejs
folder in the layer path if we see it.
When I used layers before -> I would use it almost like a common lib between lambdas to avoid having to re-upload the same files so yep, a mix of shared functions and heavy artifacts.
I think there could be a usecase for both bundling and/or transpiling layers
I currently use layers to share common code and dependencies between multiple services. Also my serverless service only contains layers and doesn't contain any functions, so I don't have the issue of lambdas referencing the code from the layer.
I agree to @samchungy logic about layer/nodejs
folder. I think the existence of a package.json
file inside that folder could determine the way forward. If package.json
exists, the layer should be bundled and transpiled. If it doesn't exist, just transpiling all files in that folder should be enough. This distinction also affects the way the code is imported in the lambda function. When the layer is attached to a lambda function, its content gets merged with the existing /opt/nodejs
folder (https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html).
If the layer contains a package.json
file, the layer itself should be considered a package and should be imported by its package name. Therefore, the bundled and transpiled files should be outputted into its own layer/nodejs/node_modules/<package_name>
folder. Then the lambda function can require('package_name')
it like a normal package. On the other hand, if the layer only contains source code files, then these files should be transpiled and outputted in the same folder layer/nodejs/<file_name>
. These files are available during runtime in /opt/nodejs
and can be required as require('./file_name.js')
.
What do you think?
Guys, any solution for this? I'm trying to use layers in a serverless project with esbuild but without success. The deploy is done successfully but I have an import error
the layers problem is actually an AWS bug with the ES module. There's a serverless plugin to fix this problem (by creating a symlink from the node_modules folder inside all the lambdas). Follow the link: https://www.npmjs.com/package/serverless-esm-layer
the layers problem is actually an AWS bug with the ES module. There's a serverless plugin to fix this problem (by creating a symlink from the node_modules folder inside all the lambdas). Follow the link: https://www.npmjs.com/package/serverless-esm-layer
That is not an aws issue i guess. The lambda layers are not getting packaged or transpiled