Skip to content
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

Conditional forceExclude of aws-sdk based on runtime version #366

Merged
merged 17 commits into from
Nov 30, 2023
Merged
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
name: CI

on:
workflow_dispatch: {}
push:
branches: [ master ]
pull_request:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ The three options (`externals`, `forceExclude`, and `excludeFiles`) look similar

- `forceExclude`

These packages are available in the Lambda runtime. Either by default (in the case of `aws-sdk`) or through a Lambda layer that you might be using. So these are not included in the Lambda package. And they are also marked as `externals`. Meaning that packages that are in `forceExclude` are automatically added to the `externals` list as well. By default, `aws-sdk` is listed in the `forceExclude`.
These packages are available in the Lambda runtime. Either by default (in the case of `aws-sdk`) or through a Lambda layer that you might be using. So these are not included in the Lambda package. And they are also marked as `externals`. Meaning that packages that are in `forceExclude` are automatically added to the `externals` list as well. By default, `aws-sdk` is listed in the `forceExclude` when `runtime` is lower than `nodejs18.x`.

- `excludeFiles`

Expand Down
13 changes: 10 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ function applyWebpackOptions(custom, config) {
function applyUserConfig(config, userConfig, servicePath, runtime) {
config.servicePath = servicePath;

// Default to Node 12 if no runtime found
const runtimeVersion =
Number.parseInt((runtime || "").replace("nodejs", ""), 10) || 12;

// Force exclude aws-sdk for versions below Node 18
if (runtimeVersion < 18) {
config.options.forceExclude.push("aws-sdk");
}

// Concat forceExclude if provided
if (userConfig.forceExclude) {
userConfig.forceExclude = config.options.forceExclude.concat(
Expand All @@ -66,9 +75,7 @@ function applyUserConfig(config, userConfig, servicePath, runtime) {

Object.assign(config.options, userConfig);

// Default to Node 12 if no runtime found
config.nodeVersion =
Number.parseInt((runtime || "").replace("nodejs", ""), 10) || 12;
config.nodeVersion = runtimeVersion;
}

class ServerlessPlugin extends ServerlessWebpack {
Expand Down
3 changes: 1 addition & 2 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ module.exports = {
packagerOptions: {},
generateStatsFiles: false,
tsConfig: "tsconfig.json",
// Exclude aws-sdk since it's available in the Lambda runtime
forceExclude: ["aws-sdk"],
forceExclude: [],
disableForkTsChecker: false,
// Set non Webpack compatible packages as externals
// Or if we want to exclude all packages in the node_modules:
Expand Down
27 changes: 27 additions & 0 deletions tests/force-exclude/force-exclude.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,30 @@ test("force-exclude", async () => {

expect(result).not.toMatch(errorRegex);
});

test("force-exclude package", async () => {
const result = await runSlsCommand(__dirname, "package -c serverless.yml");

expect(result).not.toMatch(errorRegex);

/*
Ensure that is-sorted and aws-sdk is excluded
*/
expect(result).toMatch(
/Excluding external modules: is-sorted@\^[\d\\.]+, aws-sdk@\^[\d\\.]+\n/
);
});

test("force-exclude package (node18)", async () => {
const result = await runSlsCommand(
__dirname,
"package -c serverless.node18.yml"
);

expect(result).not.toMatch(errorRegex);

/*
Ensure that is-sorted is excluded
*/
expect(result).toMatch(/Excluding external modules: is-sorted@\^[\d\\.]+\n/);
});
7 changes: 6 additions & 1 deletion tests/force-exclude/handler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import sorted from "is-sorted";
import AWS from "aws-sdk";

export const hello = async (event, context) => {
export const hello = async (event) => {
// Include a dummy AWS SDK call to ensure webpack attempts to bundle it
AWS.config.update({
region: "us-east-1",
});
sorted([1, 2, 3]);
return {
statusCode: 200,
Expand Down
1 change: 1 addition & 0 deletions tests/force-exclude/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.1502.0",
"is-sorted": "^1.0.5"
}
}
17 changes: 17 additions & 0 deletions tests/force-exclude/serverless.node18.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
service: my-service

plugins:
- '../../index'

custom:
bundle:
forceExclude:
- "is-sorted"

provider:
name: aws
runtime: nodejs18.x

functions:
hello:
handler: handler.hello
Loading