Cannot read property '1' of null
huysamen opened this issue · comments
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:
-
What went wrong?
As soon as we upgradeserverless-webpack
past version2.0.0
it is unable to compile. -
What did you expect should have happened?
Upgrading from version2.0.0
to2.1.0
(and beyond) should not break the compilation as no breaking changes are noted in the changelog. -
What was the config you used?
# package.json
{
"name": "google-nodejs",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "serverless.com",
"license": "MIT",
"dependencies": {
"serverless-google-cloudfunctions": "^1.1.0"
},
"devDependencies": {
"@types/express": "^4.0.36",
"serverless-webpack": "2.1.0",
"ts-loader": "^2.3.3",
"ts-node": "^3.3.0",
"tslint": "^5.6.0",
"typescript": "^2.4.2",
"webpack": "^3.5.5",
"webpack-node-externals": "^1.6.0"
}
}
# serverless.yml
service: rest
provider:
name: google
runtime: nodejs
project: my-project
credentials: ~/.gcloud/keyfile.json
plugins:
- serverless-webpack
- serverless-google-cloudfunctions
package:
exclude:
- node_modules/**
- .gitignore
- .git/**
functions:
rest:
handler: rest
events:
- http: rest
# webpack.config.js
var path = require("path");
var nodeExternals = require("webpack-node-externals");
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/node_modules/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):
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.
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.
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?
@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?
@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.
@HyperBrain tried changing the entry
to an object, same issue.
Ok. I'll check the template and do some tests.
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.
The fix has to be ported to v3 as soon as the v2 bugfix has been released.
Released with 2.2.1