ESBuild Bundling not working?

Hello! I’m trying to understand the options Serverless v4 provides, and I’m getting very confused about the esbuild implementation. Our functions that were bundling to ~5MB in v3 are now ~75MB, far over the lambda size limit (and obviously just unnecessarily big). That is with 0 configuration of the build.

If I add ANY options under the new

build:
  esbuild:

heading in serverless.yml, it instead makes the function .zips about 10KB and doesn’t include ANY dependencies whatsoever. I’ve tried just about everything in terms of trying out options like “packages:”, “exclude:”, “external:”, etc. I’m really just looking to replicate the same build results we were getting in v3, and I’ve pored over the docs a ton by now.

You mean you are doing Build Config - Function Build Configuration right ?

But all your code is actually not TypeScript ?

Have you tried this on a greenfield project, starting with TypeScript files and the build option ?

Thanks for the reply!

We are upgrading a number of services to Serverless v4 from v3 - none have ever used TypeScript, and we’re not planning to use it. I didn’t get the impression that was the only or main purpose of the build config. We are simply trying to get bundles for our lambda functions that are roughly the same size as they were using v3. Currently they’re over 10x as large, unless we set any of the build config settings (that you linked), in which case they are extremely tiny and missing package.json and node_modules entirely.

Ah, ha OK, that makes sense.

I wouldn’t set this new build option in that case.

I suspect, and this has happened to us too, that some dependency is pulling in either the whole of Serverless or (parts of) AWS SDK.

Firstly, check dependencies and devDependencies in package.json just to rule out that.

Then you can unzip the deployment zip and have a look for the (largest) sub folders.

If you see it is bundling something it didn’t before, then try something like npm ll or npm ll --all to see what is pulling it in.

  • List item

I unzipped one of the deployed functions (made locally with sls package --package) and analyzed it as you suggested. It’s including all dev dependencies - in fact it simply copy + pasted the entirety of the node_modules folder from the project’s base directory. I have NOT altered the default excludeDevDependencies option, or really added any config at all. My serverless.yml only has

package:
  individually: true

, everything else is just the functions and domain setup, nothing to do with build/packaging. It doesn’t seem like any bundling or building is happening at all, really.

Well, that’s odd. Does removing that line help at all ?

Not really - basically the same behavior without individual function packages. It produces one 75 MB bundle instead of two or more, which I guess is better, but still over deployment limit.

For anyone coming to this topic seeing similar issues, we did find a stopgap solution. We were able to return to our old bundling config while still using Serverless v4 by adding:

build:
esbuild: false

and then putting back in the serverless-esbuild plugin (and esbuild-node-externals package) and the properties under “custom” that made our output ESM instead of CJS. Back down to ~5 MB function bundles. But we definitely would like to see the native esbuild part of Serverless v4 working in the future, as well as things like excluding dev dependencies.

Yeah I’ve struggled to get the built-in Serverless ESBuild to work too and I’ve just resorted to turning it off and using the serverless-esbuild plugin instead. Looks like that feature wasn’t ready for prime time.