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

Issue:
Error with multiple runtimes
<!--
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

If you try to add a second runtime (in my example golang) for a new Lambda, you get following error:
TypeError [ERR_INVALID_ARG_TYPE]: The "to" argument must be of type string. Received undefined
in
node_modules/serverless-webpack/lib/validate.js:199:36
because the plugin tries to use the golang lambda to do webpack stuff.

If you just filter the functions for runtimes starting with node fixes the problem.
```javascript
//  Lookup associated Serverless functions
        const allEntryFunctions = _.map(
          this.serverless.service.getAllFunctions().map(
            funcName =>this.serverless.service.getFunction(funcName) )
            .filter(func => func.runtime.startsWith('node')), func => {
          const handler = func.handler;
          const handlerFile = path.relative('.', getHandlerFile(handler));
          const runtime = func.runtime
          return {
            handlerFile,
            funcName: func.name,
            func,
          };
        });
```

## Additional Data

* ***Serverless-Webpack Version you're using***: 5.3.5
* ***Webpack version you're using***: 4.44.2
* ***Serverless Framework Version you're using***: 2.4.0
* ***Operating System***: Windows 10 WSL, so I guess linux?
* ***Stack Trace (if available)***:
 Type Error ---------------------------------------------
 
  TypeError [ERR_INVALID_ARG_TYPE]: The "to" argument must be of type string. Received undefined
      at validateString (internal/validators.js:120:11)
      at Object.relative (path.js:1054:5)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless-webpack/lib/validate.js:199:36
      at arrayMap (/home/dennis/go/src/sportsplaner/node_modules/lodash/lodash.js:639:23)
      at Function.map (/home/dennis/go/src/sportsplaner/node_modules/lodash/lodash.js:9580:14)
      at processConfig (/home/dennis/go/src/sportsplaner/node_modules/serverless-webpack/lib/validate.js:196:37)
      at ServerlessWebpack.validate (/home/dennis/go/src/sportsplaner/node_modules/serverless-webpack/lib/validate.js:245:14)
  From previous event:
      at Object.webpack:validate:validate [as hook] (/home/dennis/go/src/sportsplaner/node_modules/serverless-webpack/index.js:152:63)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:510:55
  From previous event:
      at PluginManager.invoke (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:510:22)
      at PluginManager.spawn (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:530:17)
      at ServerlessWebpack.<anonymous> (/home/dennis/go/src/sportsplaner/node_modules/serverless-webpack/index.js:93:53)
  From previous event:
      at Object.before:package:createDeploymentArtifacts [as hook] (/home/dennis/go/src/sportsplaner/node_modules/serverless-webpack/index.js:93:12)
  From previous event:
      at PluginManager.invoke (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:510:22)
      at PluginManager.spawn (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:530:17)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless/lib/plugins/deploy/deploy.js:122:50
  From previous event:
      at Object.before:deploy:deploy [as hook] (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/plugins/deploy/deploy.js:102:22)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:510:55
  From previous event:
      at PluginManager.invoke (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:510:22)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:545:24
  From previous event:
      at PluginManager.run (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/classes/PluginManager.js:545:8)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless/lib/Serverless.js:168:33
  From previous event:
      at Serverless.run (/home/dennis/go/src/sportsplaner/node_modules/serverless/lib/Serverless.js:155:74)
      at /home/dennis/go/src/sportsplaner/node_modules/serverless/scripts/serverless.js:50:26
      at processImmediate (internal/timers.js:456:21)
      at process.topLevelDomainCallback (domain.js:137:15)
  From previous event:
      at Object.<anonymous> (/home/dennis/go/src/sportsplaner/node_modules/serverless/scripts/serverless.js:50:4)
      at Module._compile (internal/modules/cjs/loader.js:1138:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
      at Module.load (internal/modules/cjs/loader.js:986:32)
      at Function.Module._load (internal/modules/cjs/loader.js:879:14)
      at Module.require (internal/modules/cjs/loader.js:1026:19)
      at require (internal/modules/cjs/helpers.js:72:18)
      at Object.<anonymous> (/home/dennis/go/src/sportsplaner/node_modules/serverless/bin/serverless.js:47:1)
      at Module._compile (internal/modules/cjs/loader.js:1138:30)
      at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
      at Module.load (internal/modules/cjs/loader.js:986:32)
      at Function.Module._load (internal/modules/cjs/loader.js:879:14)
      at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
      at /home/dennis/.nvm/versions/node/v12.17.0/lib/node_modules/npm/node_modules/libnpx/index.js:268:14
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com
 
  Your Environment Information ---------------------------
     Operating System:          linux
     Node Version:              12.17.0
     Framework Version:         2.4.0 (local)
     Plugin Version:            4.0.4
     SDK Version:               2.3.2
     Components Version:        3.2.1


Pull request:
Don't package non-node functions (fix for #644)
<!--
1. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the PR
2. Please follow the template, otherwise we'll have to ask you to update it and it will take longer until your PR is merged
-->

## What did you implement:

Most of serverless-webpack already deals with not packaging non-node functions. There is only one section that is still problematic. This fix deals with the issue where a runtime may be defined for an individual function or for a provider. It will default to a runtime of "nodejs" if no runtime is specified at either the function or provider level.

Closes #644 

<!--
Briefly describe the feature if no issue exists for this PR. If possible only
submit PRs for existing issues. If the PR is trivial (like doc changes or simple
code fixes) it can be submitted without a related issue, but as soon as it adds
or changes functionality, a related issue should be present.
-->

## How did you implement it:

When processing the async config, implemented an extra step before mapping the functions to filter out functions that don't have a node runtime.

<!--
If this is a nontrivial change please briefly describe your implementation so its easy for us to understand and review your code.
-->

## How can we verify it:

Add a function (in my case it was a Rust function) that uses a non-node runtime and the app should still package correctly.

<!--
Add any applicable config, commands, screenshots or other resources
to make it easy for us to verify this works. The easier you make it for us
to review a PR, the faster we can review and merge it.

Examples:
* Step by step description, how to verify
* Screenshots - Showing the difference between your output and the master
* Other - Anything else that comes to mind to help us evaluate
-->

## Todos:

- [x] Write tests
- [x] Write documentation
- [x] Fix linting errors
- [x] Make sure code coverage hasn't dropped
- [x] Provide verification config / commands / resources
- [x] Enable "Allow edits from maintainers" for this PR
- [x] Update the messages below

***Is this ready for review?:*** YES
***Is it a breaking change?:*** NO


Patch:
diff --git a/lib/validate.js b/lib/validate.js
index 80d8999..393eefe 100644
--- a/lib/validate.js
+++ b/lib/validate.js
@@ -191,7 +191,10 @@ module.exports = {
       if (_.has(this.serverless, 'service.package') && this.serverless.service.package.individually) {
         this.multiCompile = true;
         this.serializedCompile = this.configuration.serializedCompile;
-        this.options.verbose && this.serverless.cli.log(`Using ${this.serializedCompile ? 'serialized' : 'multi'}-compile (individual packaging)`);
+        this.options.verbose &&
+          this.serverless.cli.log(
+            `Using ${this.serializedCompile ? 'serialized' : 'multi'}-compile (individual packaging)`
+          );
 
         if (this.webpackConfig.entry && !_.isEqual(this.webpackConfig.entry, entries)) {
           return BbPromise.reject(
@@ -203,16 +206,23 @@ module.exports = {
         }
 
         // Lookup associated Serverless functions
-        const allEntryFunctions = _.map(this.serverless.service.getAllFunctions(), funcName => {
-          const func = this.serverless.service.getFunction(funcName);
-          const handler = func.handler;
-          const handlerFile = path.relative('.', getHandlerFile(handler));
-          return {
-            handlerFile,
-            funcName,
-            func
-          };
-        });
+        const allEntryFunctions = _.map(
+          _.filter(this.serverless.service.getAllFunctions(), funcName => {
+            const func = this.serverless.service.getFunction(funcName);
+            const runtime = func.runtime || this.serverless.service.provider.runtime || 'nodejs';
+            return runtime.match(/node/);
+          }),
+          funcName => {
+            const func = this.serverless.service.getFunction(funcName);
+            const handler = func.handler;
+            const handlerFile = path.relative('.', getHandlerFile(handler));
+            return {
+              handlerFile,
+              funcName,
+              func
+            };
+          }
+        );
 
         this.entryFunctions = _.flatMap(entries, (value, key) => {
           const entry = path.relative('.', value);


Test patch:
diff --git a/tests/validate.test.js b/tests/validate.test.js
index 24c513a..a99da79 100644
--- a/tests/validate.test.js
+++ b/tests/validate.test.js
@@ -468,6 +468,18 @@ describe('validate', () => {
             }
           ],
           runtime: 'java8'
+        },
+        rustfunc: {
+          handler: 'my-rust-func',
+          runtime: 'rust',
+          events: [
+            {
+              http: {
+                method: 'POST',
+                path: 'rustfuncpath'
+              }
+            }
+          ]
         }
       };
 
@@ -960,7 +972,7 @@ describe('validate', () => {
   });
 
   describe('with skipped builds', () => {
-    it('should set `skipComile` to true if `options.build` is false', () => {
+    it('should set `skipCompile` to true if `options.build` is false', () => {
       const testConfig = {
         entry: 'test',
         output: {}