Skip to content

Bundling for Lambda requires unnecessary dependencies #5516

@perpil

Description

@perpil

Checkboxes for prior research

Describe the bug

For Lambda coldstarts, it is well known creating a minified, tree-shaken bundle measurably improves performance vs. using the V3 JavaScript SDK version bundled with Lambda.

coldstart time (ms) bundled/minified
675 no
241 yes

In a minified bundle, if you use any AWS client, credential-provider-node starts pulling in client-sso and other packages. These packages are unused but add > 32KB to the minified bundle. If you set the credentials parameter for the AWS client, it still pulls in client-sso and can't be tree-shaken out. Since loading credentials from environment variables is what most developers need for Lambda, there should be a way to only bundle the credential-provider-env credentials provider. Arguably this should be the default in the Lambda environment.

SDK version number

@aws-sdk/[email protected]

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v20.9.0

Reproduction Steps

  1. Create a lambda with any AWS client, i.e. STS:
import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';

const stsClient = new STSClient({region: process.env.AWS_REGION});

export async function handler(event, context) {
  const result = await stsClient.send(new GetCallerIdentityCommand({}));
  return {
    statusCode: 200,
    body: JSON.stringify({
      result
    }),
    headers: {
      'Content-Type': 'application/json',
    },
  };
}
  1. Minify, treeshake and create metafile with esbuild. If you use NodeJsFunction in the CDK your bundling looks like:
  bundling: {
        metafile: true, //use https://esbuild.github.io/analyze/ to analyze the bundle
        minify: true,
        treeshake: true,
        target: 'esnext',
        format: 'esm',
        platform: 'node',
        mainFields: ['module', 'main'],
        outputFileExtension: '.mjs',
        externalModules: [],
        banner:
          "const require = (await import('node:module')).createRequire(import.meta.url);const __filename = (await import('node:url')).fileURLToPath(import.meta.url);const __dirname = (await import('node:path')).dirname(__filename);",
  }
  1. Review the metafile using the esbuild analyzer and note it includes packages like client-sso
    I've attached the metafile for the above so you can directly review it: index.meta.json
    Look at it in Flamechart mode and note the inclusion of these packages: client-sso, token-providers, credential-provider-sso
    Screenshot of why token-providers is not tree-shaken: image

Observed Behavior

The packages client-sso, token-providers and credential-provider-sso get bundled unnecessarily and can't be tree-shaken out.

Expected Behavior

Either it uses credential-provider-env, or client config has some way of allowing me to omit credential-provider-node so the unnecessary packages can be tree-shaken out.

Possible Solution

No response

Additional Information/Context

No response

Metadata

Metadata

Assignees

Labels

closed-for-stalenessfeature-requestNew feature or enhancement. May require GitHub community feedback.p2This is a standard priority issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions