-
Notifications
You must be signed in to change notification settings - Fork 417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not add .js extension to entries values #167
Conversation
lib/validate.js
Outdated
@@ -8,7 +8,7 @@ const _ = require('lodash'); | |||
|
|||
function getEntryForFunction(serverlessFunction) { | |||
const handler = serverlessFunction.handler; | |||
const handlerFile = /(.*)\..*?$/.exec(handler)[1] + '.js'; | |||
const handlerFile = /(.*)\..*?$/.exec(handler)[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should actually retrieve the correct file extension here and set it in the value of the key, so that there's no need to use custom code in the webpack configuration to get the plugin running.
function getHandlerFileExtension(baseName) {
// Use fs/fs-extra/path or any other appropriate mechanism to determine the actual file extension of the handler
// Maybe we can search for known and supported endings in a predefined order
// So that the standard extension 'js' is preferred if, by accident, there are multiple copies
// of the handler with different extensions - or throw an error in that case.
const allowedExtensions = [
'js', 'ts', 'jsx'
];
const handlerExtension = ...;
...
return handlerExtension;
}
...
const handlerFileBaseName = /(.*)\..*?$/.exec(handler)[1];
const handerFile = `${handlerFileBaseName}.${getHandlerFileExtension(handlerFileBaseName)}`;
...
return {
[handlerFileBaseName]: `./${handlerFile}`
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we assume all the function files are in the servicePath folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least somewhere under the servicePath. The handlerBaseName contains the path elements relative to the handler. So, for example, it could be handlers/shop/order/handler
and handlers/shop/fulfill/handler
, but we can assume that handler files are never outside the service folder (of course the user can use symlinks to access files outside the service directory, but checking if the baseName + extension exists, will automatically reveil the correct results in this case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better rename the handlerFileBaseName
variable to handlerFilePathWithBaseName
as it actually contains the path + the basename.
tests/validate.test.js
Outdated
'module2.js': './module2.js', | ||
'handlers/func3/module2.js': './handlers/func3/module2.js', | ||
'handlers/module2/func3/module2.js': './handlers/module2/func3/module2.js', | ||
'module1': './module1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests have to be adapted AFTER the changes above, because the used external functions to determine the extension have to be stubbed with sinon.
Determining the extension will also support the case where single functions in a project are updated and the used extension changes. E.g. if you change a function from js to jsx or from js to ts. Then the next deploy will just work out of the box because your config file does not need to know anything about the specific function configurations. |
Latest commit should do the job. Problem is that all tests fail cause we don't actually have files to check |
lib/validate.js
Outdated
@@ -27,13 +49,14 @@ module.exports = { | |||
// Expose entries - must be done before requiring the webpack configuration | |||
const entries = {}; | |||
const functions = this.serverless.service.getAllFunctions(); | |||
const allFilesInServicePath = listFiles(this.serverless.config.servicePath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to browse the whole service dir file tree here? I think that is very expensive - the directory might include node_modules etc.
Assuming that the handlers we have already point to the handler files we check, we know exactly where the files have to be. So just searching in getEntryExtension(handlerFile) for ${handlerFile}.*
or ${handlerFile}.{js,ts,jsx}
should retrieve the full file automatically (and even shows us if it is ambiguous, which is an error on the user side if multiple of our allowed extensions are found). We do not need to be aware of the complete file hierarchy here.
I can take care of the unit tests as soon as we have a performant and working solution. |
Improved the file search as recommended |
lib/validate.js
Outdated
const lib = require('./index'); | ||
const _ = require('lodash'); | ||
|
||
function getEntryForFunction(serverlessFunction) { | ||
function getEntryExtension(fileName, servicePath) { | ||
let files = glob.sync(`${fileName}.*`, { cwd: servicePath }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be const
lib/validate.js
Outdated
function getEntryForFunction(serverlessFunction) { | ||
function getEntryExtension(fileName, servicePath) { | ||
let files = glob.sync(`${fileName}.*`, { cwd: servicePath }); | ||
return path.extname(files[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could emit a warning in case more than one file (or no file at all) is found here:
if (_.size(files) > 1) {
this.serverless.cli.log(`WARNING: More than one matching handlers found for ${fileName}. Using ${_.first(files)}.`);
}
Of course the now global function(s) have to be moved into validate() to have access to the correct this
.
Also use _.first(files)
here instead of files[0]
as the lodash variant shows our intention in a better way and is safer.
I will add the unit tests and the doc/example updates tomorrow, so that we can release 2.2.0 also tomorrow. |
I tested it with one of our projects. That worked nicely. Also rebased onto the current webpack master. If that turns out to be a problem later, we can restrict the allowed extensions by setting the glob pattern to |
Just added some more complex test cases and a preference sorting. I will do some final tests now. |
What did you implement:
Closes #165
How did you implement it:
How can we verify it:
Todos:
Is this ready for review?: YES
Is it a breaking change?: NO