Repository: serverless-heaven/serverless-webpack (js)

Issue:
Error: spawn E2BIG - ZIP bundling fails due to node_modules
<!--
1. Please check if an issue already exists so there are no duplicates
2. Fill out the whole template so we have a good overview on the issue
3. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the Issue
4. Please follow the template, otherwise we'll have to ask you to update it
-->

# This is a Bug Report

## Description

I originally created this issue in the serverless repo, but they suggested I should move it to serverless-webpack as it is related to a dependency of serverless-webpack. Original issue: https://github.com/serverless/serverless/issues/9415

---

I'm using the aws-nodejs-typescript template. When I deploy the application, it crashes with an **spawn E2BIG** error:

```
 Error ---------------------------------------------------
 
  Error: spawn E2BIG
      at ChildProcess.spawn (node:internal/child_process:403:11)
      at Object.spawn (node:child_process:573:9)
      at /Users/chris/Projects/Nebula/api/node_modules/bestzip/lib/bestzip.js:75:29
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:1802:20
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:248:13
      at wrapper (/Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:268:20)
      at iterateeCallback (/Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:421:28)
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:321:20
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:245:17
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:1792:24
      at /Users/chris/Projects/Nebula/api/node_modules/bestzip/lib/bestzip.js:49:7
      at processTicksAndRejections (node:internal/process/task_queues:75:11)
```

I found out that this error is related to building the .ZIP file which will be uploaded to S3. The spawn command will be invoked by bestzip (`/Users/chris/Projects/Nebula/api/node_modules/bestzip/lib/bestzip.js:75:29`) with too many arguments (more than 4.500 individual .js files). I added a `consle.log`right before the spawn and get the following output:

```
Serverless: Packing external modules: source-map-support@^0.5.19, neo4j-driver@^4.2.3, axios@^0.21.1, graphql@^15.5.0, graphql-tag@^2.12.4
command zip [
  '--quiet',
  '--recurse-paths',
  '../nebula-api.zip',
  'node_modules/.package-lock.json',
  'node_modules/@babel/runtime/helpers/applyDecoratedDescriptor.js',
  'node_modules/@babel/runtime/helpers/arrayLikeToArray.js',
  'node_modules/@babel/runtime/helpers/arrayWithHoles.js',
  'node_modules/@babel/runtime/helpers/arrayWithoutHoles.js',
  'node_modules/@babel/runtime/helpers/assertThisInitialized.js',
  'node_modules/@babel/runtime/helpers/AsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/asyncGeneratorDelegate.js',
  'node_modules/@babel/runtime/helpers/asyncIterator.js',
  'node_modules/@babel/runtime/helpers/asyncToGenerator.js',
  'node_modules/@babel/runtime/helpers/awaitAsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/AwaitValue.js',
  'node_modules/@babel/runtime/helpers/classApplyDescriptorDestructureSet.js',
  'node_modules/@babel/runtime/helpers/classApplyDescriptorGet.js',
  'node_modules/@babel/runtime/helpers/classApplyDescriptorSet.js',
  'node_modules/@babel/runtime/helpers/classCallCheck.js',
  'node_modules/@babel/runtime/helpers/classCheckPrivateStaticAccess.js',
  'node_modules/@babel/runtime/helpers/classCheckPrivateStaticFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/classExtractFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/classNameTDZError.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldGet.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldLooseBase.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldLooseKey.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldSet.js',
  'node_modules/@babel/runtime/helpers/classPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/classPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateFieldSpecGet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateFieldSpecSet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/construct.js',
  'node_modules/@babel/runtime/helpers/createClass.js',
  'node_modules/@babel/runtime/helpers/createForOfIteratorHelper.js',
  'node_modules/@babel/runtime/helpers/createForOfIteratorHelperLoose.js',
  'node_modules/@babel/runtime/helpers/createSuper.js',
  'node_modules/@babel/runtime/helpers/decorate.js',
  'node_modules/@babel/runtime/helpers/defaults.js',
  'node_modules/@babel/runtime/helpers/defineEnumerableProperties.js',
  'node_modules/@babel/runtime/helpers/defineProperty.js',
  'node_modules/@babel/runtime/helpers/esm/applyDecoratedDescriptor.js',
  'node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js',
  'node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js',
  'node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js',
  'node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js',
  'node_modules/@babel/runtime/helpers/esm/AsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/esm/asyncGeneratorDelegate.js',
  'node_modules/@babel/runtime/helpers/esm/asyncIterator.js',
  'node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js',
  'node_modules/@babel/runtime/helpers/esm/awaitAsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/esm/AwaitValue.js',
  'node_modules/@babel/runtime/helpers/esm/classApplyDescriptorDestructureSet.js',
  'node_modules/@babel/runtime/helpers/esm/classApplyDescriptorGet.js',
  'node_modules/@babel/runtime/helpers/esm/classApplyDescriptorSet.js',
  'node_modules/@babel/runtime/helpers/esm/classCallCheck.js',
  'node_modules/@babel/runtime/helpers/esm/classCheckPrivateStaticAccess.js',
  'node_modules/@babel/runtime/helpers/esm/classCheckPrivateStaticFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/esm/classExtractFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/esm/classNameTDZError.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldGet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldLooseBase.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldLooseKey.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldSet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldSpecGet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldSpecSet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/esm/construct.js',
  'node_modules/@babel/runtime/helpers/esm/createClass.js',
  'node_modules/@babel/runtime/helpers/esm/createForOfIteratorHelper.js',
  'node_modules/@babel/runtime/helpers/esm/createForOfIteratorHelperLoose.js',
  'node_modules/@babel/runtime/helpers/esm/createSuper.js',
  'node_modules/@babel/runtime/helpers/esm/decorate.js',
  'node_modules/@babel/runtime/helpers/esm/defaults.js',
  'node_modules/@babel/runtime/helpers/esm/defineEnumerableProperties.js',
  'node_modules/@babel/runtime/helpers/esm/defineProperty.js',
  'node_modules/@babel/runtime/helpers/esm/extends.js',
  'node_modules/@babel/runtime/helpers/esm/get.js',
  'node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js',
  'node_modules/@babel/runtime/helpers/esm/inherits.js',
  'node_modules/@babel/runtime/helpers/esm/inheritsLoose.js',
  'node_modules/@babel/runtime/helpers/esm/initializerDefineProperty.js',
  'node_modules/@babel/runtime/helpers/esm/initializerWarningHelper.js',
  'node_modules/@babel/runtime/helpers/esm/instanceof.js',
  'node_modules/@babel/runtime/helpers/esm/interopRequireDefault.js',
  'node_modules/@babel/runtime/helpers/esm/interopRequireWildcard.js',
  'node_modules/@babel/runtime/helpers/esm/isNativeFunction.js',
  'node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js',
  'node_modules/@babel/runtime/helpers/esm/iterableToArray.js',
  'node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js',
  'node_modules/@babel/runtime/helpers/esm/iterableToArrayLimitLoose.js',
  'node_modules/@babel/runtime/helpers/esm/jsx.js',
  **... 4541 more items**
]
```

Interestingly, this only happens when I include the npm package "neo4j-driver", which seems to have a lot of dependencies. However, I'm not sure if it is related to this package itself or I will run into this issue anyway when my application grows. 

<!--
Q2: Provide (in below placeholder) FULL content of serverless.yml, ensuring that:
• It consistently reproduces described issue
• It's as minimal as possible
• There's no plugins involved (plugin related issues need to be reported at plugin repositories)
• Has sensitive parts masked out
-->

<details>
<summary><code>serverless.yml</code></summary>

```typescript
import type { AWS } from "@serverless/typescript";

// import hello from "@functions/hello";
import resolver from "@functions/resolver";

const serverlessConfiguration: AWS = {
  service: "nebula-api",
  frameworkVersion: "2",
  custom: {
    webpack: {
      webpackConfig: "./webpack.config.js",
      includeModules: {
        forceExclude: "aws-sdk",
      },
    },
  },
  plugins: ["serverless-webpack"],
  provider: {
    name: "aws",
    runtime: "nodejs14.x",
    region: "eu-west-1",
    stage: "${opt:stage, 'dev'}",
    apiGateway: {
      minimumCompressionSize: 1024,
      shouldStartNameWithService: true,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1",
    },
    lambdaHashingVersion: "20201221",
  },
  // import the function via paths
  functions: {
    // hello,
    resolver,
  },
};

module.exports = serverlessConfiguration;

```

</details>

<details>
<summary><code>webpack.config.js</code></summary>

```typescript
const path = require('path');
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

/*
This line is only required if you are specifying `TS_NODE_PROJECT` for whatever reason.
 */
// delete process.env.TS_NODE_PROJECT;

module.exports = {
  context: __dirname,
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  entry: slsw.lib.entries,
  devtool: slsw.lib.webpack.isLocal ? 'eval-cheap-module-source-map' : 'source-map',
  resolve: {
    extensions: ['.mjs', '.json', '.ts'],
    symlinks: false,
    cacheWithContext: false,
    plugins: [
      new TsconfigPathsPlugin({
        configFile: './tsconfig.paths.json',
      }),
    ],
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  optimization: {
    concatenateModules: false,
  },
  target: 'node',
  externals: [nodeExternals()],
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      {
        test: /\.(tsx?)$/,
        loader: 'ts-loader',
        exclude: [
          [
            path.resolve(__dirname, 'node_modules'),
            path.resolve(__dirname, '.serverless'),
            path.resolve(__dirname, '.webpack'),
          ],
        ],
        options: {
          transpileOnly: true,
          experimentalWatchApi: true,
        },
      },
    ],
  },
  plugins: [],
};

```

</details>

<details>
<summary><code>tsconfig.json</code></summary>

```typescript
{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "lib": ["ESNext"],
    "moduleResolution": "node",
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "removeComments": true,
    "allowJs": true,
    "sourceMap": true,
    "target": "ES2020",
    "outDir": "lib"
  },
  "include": ["src/**/*.ts", "serverless.ts"],
  "exclude": [
    "node_modules/**/*",
    ".serverless/**/*",
    ".webpack/**/*",
    "_warmup/**/*",
    ".vscode/**/*"
  ],
  "ts-node": {
    "require": ["tsconfig-paths/register"]
  }
}

```

</details>

<!--
Q3: Provide (in below placeholder) FULL name and output of the command that exposes the problem.
       Note: Ensure SLS_DEBUG=* env var for verbose debug output
-->

<details>
<summary><b><code>NPX SLS DEPLOY </code> output</b></summary>

```
Chris-Mac:api chris$ SLS_DEBUG=* npm run deploy

> api@1.0.0 deploy
> npm run deploy:dev


> api@1.0.0 deploy:dev
> npx sls deploy --stage dev

Serverless: Load command interactiveCli
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command config:tabcompletion
Serverless: Load command config:tabcompletion:install
Serverless: Load command config:tabcompletion:uninstall
Serverless: Load command create
Serverless: Load command install
Serverless: Load command package
Serverless: Load command deploy
Serverless: Load command deploy:function
Serverless: Load command deploy:list
Serverless: Load command deploy:list:functions
Serverless: Load command invoke
Serverless: Load command invoke:local
Serverless: Load command info
Serverless: Load command logs
Serverless: Load command metrics
Serverless: Load command print
Serverless: Load command remove
Serverless: Load command rollback
Serverless: Load command rollback:function
Serverless: Load command slstats
Serverless: Load command plugin
Serverless: Load command plugin
Serverless: Load command plugin:install
Serverless: Load command plugin
Serverless: Load command plugin:uninstall
Serverless: Load command plugin
Serverless: Load command plugin:list
Serverless: Load command plugin
Serverless: Load command plugin:search
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command upgrade
Serverless: Load command uninstall
Serverless: Load command webpack
Serverless: Load command login
Serverless: Load command logout
Serverless: Load command generate-event
Serverless: Load command test
Serverless: Load command dashboard
Serverless: Load command output
Serverless: Load command output:get
Serverless: Load command output:list
Serverless: Load command param
Serverless: Load command param:get
Serverless: Load command param:list
Serverless: Load command studio
Serverless: Skipping variables resolution with old resolver (new resolver reported no more variables to resolve)
Serverless: Invoke deploy
Serverless: Invoke package
Serverless: Invoke aws:common:validate
Serverless: Invoke aws:common:cleanupTempDir
Serverless: Invoke webpack:validate
Serverless: Invoke webpack:compile
Serverless: Bundling with Webpack...
asset src/functions/resolver/handler.js 2.56 KiB [emitted] [minimized] (name: src/functions/resolver/handler) 1 related asset
runtime modules 937 bytes 4 modules
built modules 9.43 KiB [built]
  cacheable modules 9.23 KiB
    modules by path ./src/functions/resolver/*.ts 1.18 KiB
      ./src/functions/resolver/handler.ts 606 bytes [built] [code generated]
      ./src/functions/resolver/executePerspective.ts 605 bytes [built] [code generated]
    ./src/libs/graphqlApi.ts 709 bytes [built] [code generated]
    ./src/graphql/queries.ts 6.89 KiB [built] [code generated]
    ./src/aws-exports.js 478 bytes [built] [code generated]
  external "source-map-support/register" 42 bytes [built] [code generated]
  external "neo4j-driver" 42 bytes [built] [code generated]
  external "axios" 42 bytes [built] [code generated]
  external "graphql" 42 bytes [built] [code generated]
  external "graphql-tag" 42 bytes [built] [code generated]
webpack compiled successfully in 1251 ms
Serverless: Invoke webpack:package
Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: source-map-support@^0.5.19, neo4j-driver@^4.2.3, axios@^0.21.1, graphql@^15.5.0, graphql-tag@^2.12.4
command zip [
  '--quiet',
  '--recurse-paths',
  '../nebula-api.zip',
  'node_modules/.package-lock.json',
  'node_modules/@babel/runtime/helpers/applyDecoratedDescriptor.js',
  'node_modules/@babel/runtime/helpers/arrayLikeToArray.js',
  'node_modules/@babel/runtime/helpers/arrayWithHoles.js',
  'node_modules/@babel/runtime/helpers/arrayWithoutHoles.js',
  'node_modules/@babel/runtime/helpers/assertThisInitialized.js',
  'node_modules/@babel/runtime/helpers/AsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/asyncGeneratorDelegate.js',
  'node_modules/@babel/runtime/helpers/asyncIterator.js',
  'node_modules/@babel/runtime/helpers/asyncToGenerator.js',
  'node_modules/@babel/runtime/helpers/awaitAsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/AwaitValue.js',
  'node_modules/@babel/runtime/helpers/classApplyDescriptorDestructureSet.js',
  'node_modules/@babel/runtime/helpers/classApplyDescriptorGet.js',
  'node_modules/@babel/runtime/helpers/classApplyDescriptorSet.js',
  'node_modules/@babel/runtime/helpers/classCallCheck.js',
  'node_modules/@babel/runtime/helpers/classCheckPrivateStaticAccess.js',
  'node_modules/@babel/runtime/helpers/classCheckPrivateStaticFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/classExtractFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/classNameTDZError.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldGet.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldLooseBase.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldLooseKey.js',
  'node_modules/@babel/runtime/helpers/classPrivateFieldSet.js',
  'node_modules/@babel/runtime/helpers/classPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/classPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateFieldSpecGet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateFieldSpecSet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/classStaticPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/construct.js',
  'node_modules/@babel/runtime/helpers/createClass.js',
  'node_modules/@babel/runtime/helpers/createForOfIteratorHelper.js',
  'node_modules/@babel/runtime/helpers/createForOfIteratorHelperLoose.js',
  'node_modules/@babel/runtime/helpers/createSuper.js',
  'node_modules/@babel/runtime/helpers/decorate.js',
  'node_modules/@babel/runtime/helpers/defaults.js',
  'node_modules/@babel/runtime/helpers/defineEnumerableProperties.js',
  'node_modules/@babel/runtime/helpers/defineProperty.js',
  'node_modules/@babel/runtime/helpers/esm/applyDecoratedDescriptor.js',
  'node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js',
  'node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js',
  'node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js',
  'node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js',
  'node_modules/@babel/runtime/helpers/esm/AsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/esm/asyncGeneratorDelegate.js',
  'node_modules/@babel/runtime/helpers/esm/asyncIterator.js',
  'node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js',
  'node_modules/@babel/runtime/helpers/esm/awaitAsyncGenerator.js',
  'node_modules/@babel/runtime/helpers/esm/AwaitValue.js',
  'node_modules/@babel/runtime/helpers/esm/classApplyDescriptorDestructureSet.js',
  'node_modules/@babel/runtime/helpers/esm/classApplyDescriptorGet.js',
  'node_modules/@babel/runtime/helpers/esm/classApplyDescriptorSet.js',
  'node_modules/@babel/runtime/helpers/esm/classCallCheck.js',
  'node_modules/@babel/runtime/helpers/esm/classCheckPrivateStaticAccess.js',
  'node_modules/@babel/runtime/helpers/esm/classCheckPrivateStaticFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/esm/classExtractFieldDescriptor.js',
  'node_modules/@babel/runtime/helpers/esm/classNameTDZError.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldGet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldLooseBase.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldLooseKey.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateFieldSet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/esm/classPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldDestructureSet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldSpecGet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldSpecSet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateMethodGet.js',
  'node_modules/@babel/runtime/helpers/esm/classStaticPrivateMethodSet.js',
  'node_modules/@babel/runtime/helpers/esm/construct.js',
  'node_modules/@babel/runtime/helpers/esm/createClass.js',
  'node_modules/@babel/runtime/helpers/esm/createForOfIteratorHelper.js',
  'node_modules/@babel/runtime/helpers/esm/createForOfIteratorHelperLoose.js',
  'node_modules/@babel/runtime/helpers/esm/createSuper.js',
  'node_modules/@babel/runtime/helpers/esm/decorate.js',
  'node_modules/@babel/runtime/helpers/esm/defaults.js',
  'node_modules/@babel/runtime/helpers/esm/defineEnumerableProperties.js',
  'node_modules/@babel/runtime/helpers/esm/defineProperty.js',
  'node_modules/@babel/runtime/helpers/esm/extends.js',
  'node_modules/@babel/runtime/helpers/esm/get.js',
  'node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js',
  'node_modules/@babel/runtime/helpers/esm/inherits.js',
  'node_modules/@babel/runtime/helpers/esm/inheritsLoose.js',
  'node_modules/@babel/runtime/helpers/esm/initializerDefineProperty.js',
  'node_modules/@babel/runtime/helpers/esm/initializerWarningHelper.js',
  'node_modules/@babel/runtime/helpers/esm/instanceof.js',
  'node_modules/@babel/runtime/helpers/esm/interopRequireDefault.js',
  'node_modules/@babel/runtime/helpers/esm/interopRequireWildcard.js',
  'node_modules/@babel/runtime/helpers/esm/isNativeFunction.js',
  'node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js',
  'node_modules/@babel/runtime/helpers/esm/iterableToArray.js',
  'node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js',
  'node_modules/@babel/runtime/helpers/esm/iterableToArrayLimitLoose.js',
  'node_modules/@babel/runtime/helpers/esm/jsx.js',
  ... 4541 more items
]
 
 Error ---------------------------------------------------
 
  Error: spawn E2BIG
      at ChildProcess.spawn (node:internal/child_process:403:11)
      at Object.spawn (node:child_process:573:9)
      at /Users/chris/Projects/Nebula/api/node_modules/bestzip/lib/bestzip.js:75:29
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:1802:20
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:248:13
      at wrapper (/Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:268:20)
      at iterateeCallback (/Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:421:28)
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:321:20
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:245:17
      at /Users/chris/Projects/Nebula/api/node_modules/async/dist/async.js:1792:24
      at /Users/chris/Projects/Nebula/api/node_modules/bestzip/lib/bestzip.js:49:7
      at processTicksAndRejections (node:internal/process/task_queues:75:11)
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com
 
  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              15.3.0
     Framework Version:         2.39.0 (local)
     Plugin Version:            4.5.3
     SDK Version:               4.2.2
     Components Version:        3.9.1
 
undefined

/Users/chris/Projects/Nebula/api/node_modules/path2/posix/common.js:11
                throw new TypeError('Arguments to path.common must be strings');
        ^
TypeError: Arguments to path.common must be strings
    at normalize (/Users/chris/Projects/Nebula/api/node_modules/path2/posix/common.js:11:9)
    at module.exports (/Users/chris/Projects/Nebula/api/node_modules/path2/posix/common.js:21:9)
    at anonymizeStacktracePaths (/Users/chris/Projects/Nebula/api/node_modules/serverless/lib/utils/telemetry/anonymize-stacktrace-paths.js:7:26)
    at resolveErrorLocation (/Users/chris/Projects/Nebula/api/node_modules/serverless/lib/utils/telemetry/resolve-error-location.js:24:10)
    at module.exports (/Users/chris/Projects/Nebula/api/node_modules/serverless/lib/cli/handle-error.js:152:32)
```

</details>

<!--
Q4: Provide (in below placeholder) output of serverless --version
-->

<b>Installed version</b>

```
Framework Core: 2.39.0 (local)
Plugin: 4.5.3
SDK: 4.2.2
Components: 3.9.1
```


## Additional Data

```
  "devDependencies": {
    "@serverless/typescript": "^2.23.0",
    "@types/aws-lambda": "^8.10.71",
    "@types/node": "^14.14.25",
    "json-schema-to-ts": "^1.5.0",
    "serverless": "^2.39.0",
    "serverless-webpack": "^5.3.5",
    "ts-loader": "^8.0.15",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "tsconfig-paths-webpack-plugin": "^3.3.0",
    "typescript": "^4.1.3",
    "webpack": "^5.20.2",
    "webpack-node-externals": "^2.5.2"
  }
```

Pull request description:
Fix the `spawn E2BIG` error when zipping
Closes #809

When the native method to zip is used, we give it a list of all files to be included in the archive.
Because of `node_modules`, that list can be very huge and then we hit a limit which broke the build with `spawn E2BIG` error.

We list files because we might need to filter them if the `excludeRegex` option is used.
So, the zip method is now forced to node in case of that option is defined.
Otherwise, we are using the method available (which might be the native one in most case) and we don't give it a list of files to be zipped but a folder (we don't use `*` because it'll omit dot files).

The only downside is if `excludeRegex` is defined, it'll use the node way to zip which is a big longer than the native one. In my tests, it took 2s more (native: 4s, node: 6s)

Patch:
diff --git a/lib/packageModules.js b/lib/packageModules.js
index 0aec043..a28577f 100644
--- a/lib/packageModules.js
+++ b/lib/packageModules.js
@@ -3,7 +3,7 @@
 const BbPromise = require('bluebird');
 const _ = require('lodash');
 const path = require('path');
-const { bestzip, hasNativeZip } = require('bestzip');
+const { nativeZip, nodeZip, hasNativeZip } = require('bestzip');
 const glob = require('glob');
 const semver = require('semver');
 const fs = require('fs');
@@ -27,7 +27,7 @@ function setArtifactPath(funcName, func, artifactPath) {
 
 function zip(directory, name) {
   // Check that files exist to be zipped
-  const globFiles = glob.sync('**', {
+  let files = glob.sync('**', {
     cwd: directory,
     dot: true,
     silent: true,
@@ -35,13 +35,26 @@ function zip(directory, name) {
     nodir: true
   });
 
-  let files = globFiles;
+  let zipMethod = nodeZip;
+  let source = '';
+  if (hasNativeZip()) {
+    zipMethod = nativeZip;
+    source = './';
+  }
+
+  // if excludeRegex option is defined, we'll have to list all files to be zipped
+  // and then force the node way to zip to avoid hitting the arguments limit (ie: E2BIG)
+  // when using the native way (ie: the zip command)
   if (this.configuration.excludeRegex) {
-    files = _.filter(globFiles, f => f.match(this.configuration.excludeRegex) === null);
+    const existingFilesLength = files.length;
+    files = _.filter(files, f => f.match(this.configuration.excludeRegex) === null);
 
     if (this.options.verbose) {
-      this.serverless.cli.log(`Excluded ${globFiles.length - files.length} file(s) based on excludeRegex`);
+      this.serverless.cli.log(`Excluded ${existingFilesLength - files.length} file(s) based on excludeRegex`);
     }
+
+    zipMethod = nodeZip;
+    source = files;
   }
 
   if (_.isEmpty(files)) {
@@ -56,15 +69,19 @@ function zip(directory, name) {
   this.serverless.utils.writeFileDir(artifactFilePath);
 
   const zipArgs = {
-    source: files,
+    source,
     cwd: directory,
     destination: path.relative(directory, artifactFilePath)
   };
 
   return new BbPromise((resolve, reject) => {
-    bestzip(zipArgs)
+    zipMethod(zipArgs)
       .then(() => {
         resolve(artifactFilePath);
+
+        this.options.verbose &&
+          this.serverless.cli.log(`Zip method used: ${zipMethod.name === 'nodeZip' ? 'node' : 'native'}`);
+
         return null;
       })
       .catch(err => {
@@ -123,9 +140,7 @@ module.exports = {
           () =>
             this.options.verbose &&
             this.serverless.cli.log(
-              `Zip ${_.isEmpty(entryFunction) ? 'service' : 'function'} (using ${
-                hasNativeZip() ? 'native' : 'node'
-              } method): ${modulePath} [${_.now() - startZip} ms]`
+              `Zip ${_.isEmpty(entryFunction) ? 'service' : 'function'}: ${modulePath} [${_.now() - startZip} ms]`
             )
         );
     });


Test patch:
diff --git a/tests/mocks/bestzip.mock.js b/tests/mocks/bestzip.mock.js
index eac36ff..16063bc 100644
--- a/tests/mocks/bestzip.mock.js
+++ b/tests/mocks/bestzip.mock.js
@@ -15,7 +15,8 @@ module.exports.create = sandbox => {
   hasNativeZip.returns(false);
 
   return {
-    bestzip: sinon.stub().resolves(BestZipMock(sandbox)),
+    nativeZip: sinon.stub().resolves(BestZipMock(sandbox)),
+    nodeZip: sinon.stub().resolves(BestZipMock(sandbox)),
     hasNativeZip
   };
 };
diff --git a/tests/packageModules.test.js b/tests/packageModules.test.js
index c7904a4..d733bbf 100644
--- a/tests/packageModules.test.js
+++ b/tests/packageModules.test.js
@@ -94,7 +94,7 @@ describe('packageModules', () => {
       module.compileStats = { stats: [] };
       return expect(module.packageModules()).to.be.fulfilled.then(() =>
         BbPromise.all([
-          expect(bestzipMock.bestzip).to.not.have.been.called,
+          expect(bestzipMock.nativeZip).to.not.have.been.called,
           expect(writeFileDirStub).to.not.have.been.called,
           expect(fsMock.createWriteStream).to.not.have.been.called,
           expect(globMock.sync).to.not.have.been.called
@@ -106,7 +106,7 @@ describe('packageModules', () => {
       module.skipCompile = true;
       return expect(module.packageModules()).to.be.fulfilled.then(() =>
         BbPromise.all([
-          expect(bestzipMock.bestzip).to.not.have.been.called,
+          expect(bestzipMock.nativeZip).to.not.have.been.called,
           expect(writeFileDirStub).to.not.have.been.called,
           expect(fsMock.createWriteStream).to.not.have.been.called,
           expect(globMock.sync).to.not.have.been.called