serverless-webpack
serverless-webpack copied to clipboard
Missing entries in slsw.lib when serverless functions are defined in a separate file
This is a Bug Report
Description
For bug reports:
- What went wrong?
Webpack fails to identify entry point when serverless functions are extracted out into a separate yml file. However, it works when serverless.yml has the functions defined in the same file.
- What did you expect should have happened?
Should have identified the correct entry points in slsw.lib.entries
- What was the config you used?
❗️ This configuration fails
serverless.yml
functions:
- ${file(src/functions/index.yml)}
functions/index.yml
index:
handler: src/handler.handle
events:
- http
This configuration works fine
serverless.yml
functions:
misc:
handler: src/handler.handle
events:
- http
- What stacktrace or error message from your provider did you see?
Serverless: Bundling with Webpack...
Webpack Options Validation Error -----------------------
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should be one of these:
object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function
-> The entry point(s) of the compilation.
Details:
* configuration.entry should not be empty.
-> Multiple entry bundles are created. The key is the chunk name. The value can be a string or an array.
* configuration.entry should be a string.
-> An entry point without name. The string is resolved to a module which is loaded upon startup.
* configuration.entry should be an array:
[non-empty string]
* configuration.entry should be an instance of function
-> A Function returning an entry object, an entry string, an entry array or a promise to these things.
Additional Data
- Serverless-Webpack Version you're using: 5.1.0
- Webpack version you're using: 4.2.0
- Serverless Framework Version you're using: 1.26.1
- Operating System: linux
Hi @sohailalam2 , thanks for reporting.
This behavior looks quite strange, because Serverless should be constructing the complete service in-memory, before the webpack plugin tries to evaluate the function handlers.
There have been a lot of changes done in Serverless recently regarding the variable resolution. Can you try the same setup with the current Serverless master branch (the upcoming 1.27)? Additionally, use --verbose to get some more detailed output.
was this resolved?
@immexerxez Not yet. It needs to be analyzed first, what exactly happens.
For me it fails at the regex check "handlerEntry". in lib -> validate
const getEntryForFunction = (name, serverlessFunction) => {
const handler = serverlessFunction.handler;
// Check if handler is a well-formed path based handler.
const handlerEntry = /(.*)\..*?$/.exec(handler);
if (!handlerEntry) {
_.get(this.serverless, 'service.provider.name') !== 'google' &&
this.serverless.cli.log(`\nWARNING: Entry for ${name}@${handler} could not be retrieved.\nPlease check your service config if you want to use lib.entries.`);
return {};
}
const handlerFile = handlerEntry[1];
const ext = getEntryExtension(handlerFile);
// Create a valid entry key
return {
[handlerFile]: `./${handlerFile}${ext}`
};
};
`
So this issue for me was I was just exporting my functions and the regex would fail trying to find the "." I haven't really been following the development of serverless over the past few months so maybe this is the accepted/expected way of doing things?
// expected
module.exports.some_name = (event, context, callback) => {
callback(null, 'hi');
};
// mine
module.exports = (event, context, callback) => {
callback(null, 'hi');
};
Hi @immexerxez .
The specification is, that you must export the named function, so the regex resembles exactly what Serverless specifies. We should not add a different semantics in the plugin as that what Serverless defines. Serverless' correct way of defining a handler function is: handler: <module>.<handlerFuncExport>. This is a vital assumption in Serverless and is used e.g. in invoke local to determine and load the handler.
Additionally, AWS themselves document their configuration in that way: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
Maybe a proper solution of the issue would be to add a hint to the documentation (README) that shows the right layout and close the PR that introduces a non-spec-conform behavior.
Ah yes I'm behind the times! Thanks for letting me know. I agree pointing that out in the docs is the best solution.
@immexerxez @HyperBrain I think we are missing the point here and not focusing on the reported issue. The problem is that when I place the function declarations in the serverless.yml file, everything works as expected, however, when I extract the function declarations to a separate file and try to include that file in the yaml config, it blows up. NOTE: Serverless does support this pattern
❗️ This configuration fails
serverless.yml
functions:
- ${file(src/functions/index.yml)}
functions/index.yml
index:
handler: src/handler.handle
events:
- http
This configuration works fine
serverless.yml
functions:
misc:
handler: src/handler.handle
events:
- http
Hi @sohailalam2 Agree. @immexerxez 's issue was a "cross-in" and my answer only relates to the issue with not specifying the handler function. Of course the original issue is still valid and has to be analyzed 😃
I'm experiencing the same issue since I split my serverless file.
I am expecting this same issue when I split my resources into separate files. I do not have functions. Any solution or workaround to this yet?
I'm experiencing this same issue. Any solution yet?
@sohailalam2 I believe the issue is with your example, if you change the files to look like the following, it should work:
serverless.yml:
functions:
index: ${file(src/functions/index.yml)}
functions/index.yml:
handler: src/handler.handle
events:
- http
As I understand it, the functions property on serverless.yml should be an object, not an array.
@anupsarode IIRC you need at least one function if you're using serverless-webpack. We should probably improve the DX on this though, its definitely bitten me a few times in the past too.
@hassankhan I just hit this and my setup is as you specified in https://github.com/serverless-heaven/serverless-webpack/issues/372#issuecomment-487191427. Will try and find the time to make a min repo for the issue but pretty confident this is still a bug..
Had the same issue just now. Everything worked (including the separate functions file) until I attempted to add webpack into the project, and got to this error. The solution recommended above does not seem to work. My functions file looks like this though (contains multiple functions):
get:
handler: functions/get.handler
events:
- http:
path: /get
method: get
cors: true
create:
handler: functions/create.handler
events:
- http:
path: /create
method: put
cors: true
and the serverless.yml contains this as the functions reference:
functions:
index: ${file(./functions/functions.yml)}
Would be grateful as to any advice as I*m a bit confused how to proceed further. Thank you.
I had the name problem, but in my case, it had a lost function who doesn't have any handler. I had removed then it worked
functionName:
handler: handler
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should be an non-empty object.
same problem here, I'm clueless about fixing this: webpack.config.js
const path = require('path');
const slsw = require('serverless-webpack');
// var nodeExternals = require('webpack-node-externals')
module.exports = {
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
entry: slsw.lib.entries,
// externals: [nodeExternals()],
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
target: 'node',
module: {
rules: [
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
{ test: /\.tsx?$/, loader: 'ts-loader' },
],
},
};
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema. - configuration.entry should be an non-empty object.same problem here, I'm clueless about fixing this: webpack.config.js
const path = require('path'); const slsw = require('serverless-webpack'); // var nodeExternals = require('webpack-node-externals') module.exports = { mode: slsw.lib.webpack.isLocal ? 'development' : 'production', entry: slsw.lib.entries, // externals: [nodeExternals()], devtool: 'source-map', resolve: { extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'], }, output: { libraryTarget: 'commonjs', path: path.join(__dirname, '.webpack'), filename: '[name].js', }, target: 'node', module: { rules: [ // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader` { test: /\.tsx?$/, loader: 'ts-loader' }, ], }, };
@ggmartins Conseguiu resolver?
@hectorgrecco sorry this was a long time ago. IIRC what I did was to regenerate tsx code from the template and migrate the old files to the latest version.