Skip to content
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

Make sure correct client files are served, fixes #3555 #3557

Closed
wants to merge 2 commits into from

Conversation

Apollon77
Copy link

The old logic missed some places and was not able to look into the node_modules of the socket.io library itself.

The new logic always uses require.resolve to lookup the "correct" location for the socker.io-client library and then construct the path correctly

This fixes #3555

A fast release of a fixed version would be awesome!

The kind of change this PR does introduce

  • a bug fix
  • a new feature
  • an update to the documentation
  • a code change that improves performance
  • other

Current behaviour

New behaviour

Other information (e.g. related issues)

The old logic missed some places and was not able to look into the node_modules of the socket.io library itself.

The new logic always uses require.resolve to lookup the "correct" location for the socker.io-client library and then construct the path correctly

This fixes socketio#3555 

A fast release of a fixed version would be awesome!
Copy link

@dasilvacontin dasilvacontin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relevant docs:

I think the comment inside the function should explain the logic and concerns (e.g., the concerns that cause the #3555 bug).

And ideally we have a regression test as well.

lib/index.js Outdated Show resolved Hide resolved
}
return require.resolve(file);
var clientPath = require.resolve('socket.io-client'); // resolve the client dep. end in lib/index
return path.normalize(path.join(path.dirname(clientPath), '..', '..', file));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the sake of code legibility, I'd be great to have each function execution on a separate line, assigning the result to a variable with a readable+understandable variable name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If needed I can do that, but is it not undrstandable?
Else my proposals would be

var clientLibDir = path.dirname(clientPath)
var clientFilePath = path.join(clientLibDir, '..', '..', file);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Just to be clear, I don't think the original code is very legible either).

My intuition is something like:

var pathToClosestSocketIOClientMainFile = require.resolve('socket.io-client');
var pathToParentNodeModulesFolder = path.join(path.dirname(clientPath), '..', '..')
return path.normalize(path.join(pathToParentNodeModulesFolder, file));

Imo, ideally code is readable without comments.

Copy link

@dasilvacontin dasilvacontin May 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If needed I can do that, but is it not undrstandable?"

We have the context, but someone else might not know why not just do require.resolve(file). (Which I just realized isn't really addressed in my suggestion, and it should. Maybe a comment)

And 2), to someone just reading, path.join(clientLibDir, '..', '..', file) is quite confusing. Like, where are you trying to go?? Why .. .. ? etc

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now you know how long I needed to understand the problem ;-) But yes you were right ... so i "learned" the context the hard way.

I think your names (even veeery long) are ok and basically understandable. Maybe some more details in the JSDoc of the method would so help to understand what is done there. Then maybe good variable names are enough.

Co-authored-by: David da Silva <[email protected]>
@Apollon77
Copy link
Author

And ideally we have a regression test as well.

What you mean by that?

@dasilvacontin
Copy link

dasilvacontin commented May 6, 2020

@Apollon77 A regression test is a type of test that makes sure that a previously known bug is no longer happening in the code.

Here's socket.io's test folder: https://github.com/socketio/socket.io/tree/master/test

Here's how the tests are run: https://github.com/socketio/socket.io/blob/master/package.json#L24

Ideally we have that regression test to 1) make sure that the bug is real, 2) make sure that the fix actually works (and doesn't make something else stop working (hopefully you have tests for other cases/functionality)), and 3) make sure that in the future someone doesn't make a change to the code that makes the bug happen again.

If you don't happen to be interested in coding it, happy to take care of it! :)

@Apollon77
Copy link
Author

If you don't happen to be interested in coding it, happy to take care of it! :)

In general I would love to do it but it would take me some weeks to find time for it. We currently prepare a big release in one of my main projects and I'm spending all my free time to complete and manage this at the moment.
So if you have time before me I would be happy to review your tests.

As soon as it is accepted and released I can also remove my workarounds from some projects ;-)

@Apollon77
Copy link
Author

BTW: This is the current workaround I found to work around that issue :-)

https://github.com/ioBroker/ioBroker.socketio/blob/master/lib/socket.js#L1669-L1705

@dasilvacontin
Copy link

BTW: This is the current workaround I found to work around that issue :-)

https://github.com/ioBroker/ioBroker.socketio/blob/master/lib/socket.js#L1669-L1705

Cool, this is great insight, thanks! :)

@dasilvacontin
Copy link

dasilvacontin commented May 7, 2020

Okay, I've been testing a bit more to try to understand the problem, and it feels like the problem you are running into is that, if your socket.io installation has a node_modules inside it (with an installation of socket.io-client), it is ignored when trying to seek an installation of socket.io-client, defaulting to checking first the node_modules folder that contains the socket.io installation. Is this spot on, @Apollon77?

If this is the case, to describe the bug/need better in the regression test / documentation, what's making you have a node_modules folder inside your socket.io installation?

Thank you @Apollon77! :)

@Apollon77
Copy link
Author

Apollon77 commented May 8, 2020

The reason for it is "npm" and how they organize the packages. The topic here is that we have a system which is extenable by plugins. In fact they all end up in one big "node_modules" structure.

And the issue here was that some package installed one version of socket.io (1.7.x) and because it was the first one, npm put on top level as usual.

Now a second package came and wanted to have socket.io 2.3.0 which is by "usual carrot deps" incompatible. So npm is not allowed to overwrite the "socket.io placed in root node-modules" but put it in the node-modules in the local package.

This is a complete normal logic on how npm strcutures the package files.

Node.js is resolving with the following logic: get the directory of the js-file that requires a module and check if there is a node-modules and check if required module is there. If not, go one directory to up, check the same there ... end if you found the module or you end up in "root" :-)

The resolve logic from socket.io in 2.3.0 ignored the possibility that there could be an "own"/local node-modules and starts one level too high to search for the package ... and so we ended in always finding the socket.io-client 1.7.x package which was wrong in this case.

Better understandable?

@dasilvacontin
Copy link

@Apollon77 That's perfect, thank you!! :)

Might be a bit busy the upcoming week though (doing a design sprint) but will come back to this around May 19.

@Apollon77
Copy link
Author

np ... my workaroud works fine so far, so no need to hurry (at least not foru me) :-)

@dasilvacontin
Copy link

Added a failing test in #3604. You can see that it failed previous to pulling in your fix, and how it passes after pulling in your fix: https://github.com/socketio/socket.io/pull/3604/commits.

@Apollon77
Copy link
Author

great work @dasilvacontin

@darrachequesne
Copy link
Member

Superseded by 7603da7 (included in [email protected]). Thanks for the PR!

@darrachequesne darrachequesne added this to the 3.0.0 milestone Jan 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Served socket.io client does not find client installed in own node_modules
3 participants