serverless-heaven / serverless-webpack

Serverless plugin to bundle your lambdas with Webpack
MIT License
1.72k stars 417 forks source link

Cannot read property '1' of null #193

Closed huysamen closed 7 years ago

huysamen commented 7 years ago

This is a Bug Report

Description

Unable to upgrade serverless-webpack beyond version 2.0.0. This happens on a basic example, after the template was generated with serverless, and changing from Javascript to Typescript.

For bug reports:

provider: name: google runtime: nodejs project: my-project credentials: ~/.gcloud/keyfile.json

plugins:

package: exclude:

functions: rest: handler: rest events:

module.exports = { entry: "./src/index.ts", target: "node", externals: [nodeExternals()],

module: { loaders: [ { test: /.ts(x?)$/, loader: "ts-loader", exclude: "/node_modules/" } ] },

resolve: { extensions: [".ts", ".js"] },

output: { libraryTarget: "commonjs", path: path.join(__dirname, "dist"), filename: "index.js" } };


* What stacktrace or error message from your provider did you see?

➜ sls webpack Serverless: WARNING: Plugin ServerlessWebpack uses deprecated hook before:deploy:createDeploymentArtifacts, use package:createDeploymentArtifacts hook instead Serverless: WARNING: Plugin ServerlessWebpack uses deprecated hook after:deploy:createDeploymentArtifacts, use package:createDeploymentArtifacts hook instead

Type Error ---------------------------------------------

Cannot read property '1' of null

 For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

Stack Trace --------------------------------------------

TypeError: Cannot read property '1' of null at getEntryForFunction (/Users/user/path/to/service/nodemodules/serverless-webpack/lib/validate.js:11:48) at .forEach.func (/Users/user/path/to/service/node_modules/serverless-webpack/lib/validate.js:36:23) at arrayEach (/Users/user/path/to/service/node_modules/lodash/lodash.js:537:11) at Function.forEach (/Users/user/path/to/service/node_modules/lodash/lodash.js:9359:14) at ServerlessWebpack.validate (/Users/user/path/to/service/node_modules/serverless-webpack/lib/validate.js:35:9) From previous event: at PluginManager.invoke (/Users/user/.config/yarn/global/node_modules/serverless/lib/classes/PluginManager.js:242:22) at PluginManager.run (/Users/user/.config/yarn/global/node_modules/serverless/lib/classes/PluginManager.js:261:17) at variables.populateService.then (/Users/user/.config/yarn/global/node_modules/serverless/lib/Serverless.js:99:33) at runCallback (timers.js:672:20) at tryOnImmediate (timers.js:645:5) at processImmediate [as _immediateCallback] (timers.js:617:5) From previous event: at Serverless.run (/Users/user/.config/yarn/global/node_modules/serverless/lib/Serverless.js:86:74) at serverless.init.then (/Users/user/.config/yarn/global/node_modules/serverless/bin/serverless:39:50)

Get Support -------------------------------------------- Docs: docs.serverless.com Bugs: github.com/serverless/serverless/issues Forums: forum.serverless.com Chat: gitter.im/serverless/serverless

Your Environment Information ----------------------------- OS: darwin Node Version: 6.11.1 Serverless Version: 1.20.2



## Additional Data

* ***Serverless-Webpack Version you're using***:
`2.1.0`

* ***Webpack version you're using***:
`3.5.5`

* ***Serverless Framework Version you're using***:
`1.20.2`

* ***Operating System***:
macOS Sierra 10.12.6

* ***Stack Trace (if available)***:
HyperBrain commented 7 years ago

Your handler name seems not to match your actual handler file in serverless.yml:

functions:
  rest:
    handler: rest
    events:
      - http: rest

The versions 2.1.0 and beyond enforce correct configurations now - it was a bug that the plugin did not do proper checks of the service configuration consistence before, which led to quite unstable runtime behavior of the plugin.

The important thing (especially from a sight of the Serverless framework) is, that the handlers are declared correctly, so your function definition should be:

functions:
  rest:
    handler: src/index.rest  # rest would be the function called within index
    events:
      - http: rest

in your webpack config you then should use the entry resolution mechanism, which makes sure that the webpack config is setup correctly for the service:

const slsw = require('serverless-webpack');
...
entry: slsw.lib.entries,
...
output: {
  ...
  filename: '[name].js'
  ...
}

Alternatively you can build that all manually and make sure that your handlers match:

entry: {
  'src/index': './src/index.ts'
}

output: {
  filename: './src/index.js'
}

BTW: individual packaging of a service will only work with the automatic stuff enabled.

Nevertheless I agree that the error message is wrong. It should emit something that points out that the handler file declared in the serverless.yml could not be found in that case.

huysamen commented 7 years ago

That seems like an AWS way of declaring the handlers. We are using Goole Cloud Functions which does not use the handler: src/index.rest syntax of defining handlers.

If you try to use that syntax with the serverless-google-cloudfunctions plugin, you get:

  The "handler" property for the function "rest" is invalid. Handlers should be plain strings referencing only the exported function name without characters such as "." or "/" (so e.g. "http" instead of "index.http"). Do you want to nest your functions code in a subdirectory? Google solves this by utilizing the "main" config in the projects package.json file. Please check the docs for more info.
HyperBrain commented 7 years ago

Thanks for the info. Hmmm. @pmuens, can you tell me how the handler definitions are meant to be for the Google plugin? I thought handlers in Serverless in general should point to the handler file, regardless of the plugin used. @huysamen , can you tell me what "rest" as handler exactly is supposed to do? Should it call something named "rest" in the Google context? If you'd run this serverless config without the webpack-plugin, how would the handler for the function be located by Serverless?

HyperBrain commented 7 years ago

@huysamen One thing you additionally could try: can you try to change YOUR entry definition just to be an object and leave everything else as is?

entry: {
  "index.ts": "./src/index.ts"
}

Does that solve the crash?

huysamen commented 7 years ago

@HyperBrain the rest endpoint is just a test function. I think the default when generating a template with sls create --template google-nodejs --path my-project the function is called first or something. It's just a test HTTP function. You can call it something else if you like. It is not Google specific at all.

With the serverless-google-cloudfunctions plugin it actually looks for the exported methods in the index.js to deploy from the handler name that you specify.

Let me try the entry object change quick.

huysamen commented 7 years ago

@HyperBrain tried changing the entry to an object, same issue.

HyperBrain commented 7 years ago

Ok. I'll check the template and do some tests.

HyperBrain commented 7 years ago

From the sample template it seems that for Google, the handler definitions in serverless.yml are the names of the exports in the index.js. If that's the general approach for Google and all projects look like that, I might be able to provide a fix that ignores any handler evaluation in case a Google project is packed.

That would make it compile again with projects, that are structured like the sample template. This should end up in 2.2.1 then.

A further thought (that's not directly related to this - obvious - bug) is, that individual packaging and per function optimization would not be possible due to the structure of the projects. I'll investigate that after the bug is fixed and I have gathered more information, why the layout has been chosen in the way it is - if it's a necessary requirement for Google or if it was chosen just on purpose. Opposed to AWS and OpenWhisk, this layout prevents gaining all the benefits from Webpacks TreeShaking and optimization mechanisms, because the functions are not separated physically.

HyperBrain commented 7 years ago

The fix has to be ported to v3 as soon as the v2 bugfix has been released.

HyperBrain commented 7 years ago

Released with 2.2.1