-
Notifications
You must be signed in to change notification settings - Fork 603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Client packages can't be tree-shaken properly #6889
Comments
After a bit more digging, I wrote a custom esbuild plugin that only tries to include the commands we actually need. However, there are still a couple files that don't seem to be necessarily included in full? {
name: 'exclude-aggregated clients',
setup(build) {
build.onLoad({ filter: /@aws-sdk\/client-dynamodb\/dist-es\/DynamoDB\.js$/ }, () => {
return {
contents: 'export default {};',
loader: 'js',
};
});
build.onLoad({ filter: /@aws-sdk\/client-dynamodb\/dist-es\/commands\/index\.js$/ }, () => {
const commands = [
'BatchGetItemCommand',
'BatchWriteItemCommand',
'GetItemCommand',
'PutItemCommand',
'UpdateItemCommand',
'DeleteItemCommand',
'QueryCommand',
];
return {
contents: commands.map((command) => `export * from './${command}';`).join('\n'),
loader: 'js',
};
});
build.onLoad({ filter: /@aws-sdk\/client-s3\/dist-es\/S3\.js$/ }, () => {
return {
contents: 'export default {};',
loader: 'js',
};
});
},
} There's a large AWS_json file that gets included by various commands, but for some reason it's not just pulling in the ones needed (the import sits at 33kb)
|
I also asked over at the |
When I run this I only get one Command in the bundle // index.ts
export { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb"; npx esbuild --bundle index.ts --outfile=dist/bundle.js --format=esm \
--main-fields=module,main --platform=node \
--external:@aws-sdk/client-sts \
--external:@aws-sdk/client-sso* \
--external:@aws-sdk/credential-provider-* \
--external:@aws-sdk/token-providers \
--external:fast-xml-parser esbuild 0.21.4 |
@kuhe Thanks for the test! Your code does work as expected (well, it does pull in one extra command, but that's fine). Is there a reason why you made those specific packages external? From the AWS blogs and such I read that the AWS SDK should be included in the bundle - or are there exceptions for specific packages? I think I have found the culprit of my issue though, and it looks like I caught a weird case: In the lambda code there's an async import, which itself pulls in only one exported function (+ client) from the dynamodb service file I have. As soon as I added that async boundary to my test file, the tree shaking stopped working. Once I import the files like normal, only the necessary bits get included. I'll ask Evan if that's expected behavior. Edit: Here's a test case that pulls everything in: // test.ts
export const migrations = {
'add-users': import('./migrations/20250101-add-users.ts'),
}; // 20250101-add-users.ts
import { QueryCommand } from '@aws-sdk/client-dynamodb';
export default function migrate() {
new QueryCommand();
} |
I externalized some packages because they are part of the AWS SDK default credential provider chain that may be unnecessary in Lambda. That part is optional and shouldn't affect the tree-shaking. |
Checkboxes for prior research
Describe the bug
I noticed that our lambda bundle contains pretty much all S3 and DynamoDB commands, even though I recently refactored to use the smaller, non-aggregated clients instead.
Regression Issue
SDK version number
@aws-sdk/client-s3 3.749.0, @aws-sdk/client-dynamodb 3.749.0
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
v22.2.0
Reproduction Steps
Our setup: esbuild, using the following config:
Observed Behavior
From what I can tell, the tree shaking stops working because the "S3.js" and "DynamoDB.js" files include a list of all commands to support on the clients. Even though we're not importing those files/clients (and use the raw
S3Client
andDynamoDBClient
instead), the file likely still gets evaluated:aws-sdk-js-v3/clients/client-dynamodb/src/DynamoDB.ts
Line 1153 in 5f1be93
aws-sdk-js-v3/clients/client-s3/src/S3.ts
Line 2096 in 5f1be93
There already has been an issue up on StackOverflow about this:
https://stackoverflow.com/q/79169593/1397894
Here is an analysis by esbuild:
Expected Behavior
Only the commands used should be included in the bundle.
Possible Solution
When importing the S3 client directly, via using the path directly, the issue goes away. However, this is impractical for the DynamoDB client, as we'd need to do the same for every command import that we use.
Additional Information/Context
This issue is based on taking the recommendations mentioned in #3542 already into account.
The text was updated successfully, but these errors were encountered: