dherault / serverless-offline

Emulate AWS λ and API Gateway locally when developing your Serverless project
MIT License
5.19k stars 796 forks source link

Lazy/late bundling possible? #1619

Open vicary opened 1 year ago

vicary commented 1 year ago

Feature Request

I have multiple projects in production with 100 - 300 lambda functions, they are bundled via serverless-webpack and serverless-esbuild.

The initial bundling for serverless-offline in these projects takes 1-2 hours, which is not really practical from the development perspective.

Is it possible to trigger bundling only when an endpoint is visited, or when a lambda is invoked?

I am a maintainer of serverless-webpack, if this requires adaptation from the bundler side I'll see what I can do there.

Sample Code

service: my-service

plugins:
  - serverless-offline

custom:
  serverless-offline:
    lazy: true

Expected behavior/code

A local HTTP server is immediately spun up without the bundling process, individual functions are bundled upon invocation from the local endpoint.

Additional context/Screenshots

N/A

dnalborczyk commented 1 year ago

Is it possible to trigger bundling only when an endpoint is visited, or when a lambda is invoked?

I'm sure it's possible. I would imagine it's an api serverless-offline would need to provide, unless there's some machinery already provided by serverless itself. Currently the plugins run in the order of declaration, bundler or compiler plugins would run before serverless-offline and transform the handler code, and serverless-offline in turn imports the output and runs the handler.

That said, in the long term we would also like to support proper hot reloading. The current implementation with the reloadHandler flag is merely a workaround, as it reloads a handler on each invocation, regardless of any code changes. I think it would share parts if not all of the functionality needed for lazy compilation/bundling.

Let me know if you have any thoughts or ideas.

vicary commented 1 year ago

I would imagine serverless-offline doing something like serverless.pluginManager.spawn('deploy:function:packageFunction') before the following line happens,

https://github.com/dherault/serverless-offline/blob/c588743f1a7ba940e6b2e28ae342b7958a38c41d/src/events/alb/HttpServer.js#L209

This bundles each function on the fly before require/import happens.

Bundlers should then implement a way to skip the first build, but would still do it when individual functions are invoked from the local HTTP server. Incremental builds are also possible to further increase performance.

Does that make sense?