-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
module: resolve _-prefixed dependencies to real path #6460
Conversation
c784c7b
to
82cce24
Compare
@@ -144,52 +182,24 @@ Module._findPath = function(request, paths, isMain) { | |||
return Module._pathCache[cacheKey]; | |||
} | |||
|
|||
var exts; | |||
const exts = Object.keys(Module._extensions); |
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.
Why was the lazy-loading of the extensions removed?
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.
Simplified the control flow, since tryFindPath
was split out in order to reduce redundancy (just like readFilePath
).
More than happy to add it back in, but seemed like a very marginal cost to me.
Looks like it's causing |
82cce24
to
9cf3bdd
Compare
Despite the test failure, I ran the module loader benchmark before and after this change (and after fixing a
|
@mscdex @thealphanerd Fixed. |
@mscdex Yes, this is expected, since now we need to check if the prefixed symlink exists for every required module. I don't think there is any way around in any of the proposed solution. Update Actually there is, but is means the precedence changes (default to new behaviour if both files exist). |
// If _basePath is a symlink, use the real path rather than the path of the | ||
// symlink as cache key. | ||
const _basePath = path.resolve(curPath, '/_' + request); | ||
const basePath = path.resolve(curPath, request); |
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 above two lines are contributing to v8 aborting optimization of Module._findPath()
because of the const
usage. They should be reverted to var
for now.
@alexanderGugel ... Thank you very much for this. I'm still skeptical if this is the right approach. As an interim solution, I'm currently leaning towards a flag based fix that conditionally reverts the change that was made with the long term solution being closer to the two cache model I described. I'll have some time to walk through this PR in detail soon tho. Really appreciate you putting this together tho! |
Since nodejs#5950, `require('some-symlink')` no longer resolves the module to its real path, but instead uses the path of the symlink itself as a cache key. This change allows users to resolve dependencies to their real path when required using the _-prefix. Example using old mechanism (pre v6.0.0): --- node_modules/_real-module -> ../real-module real-modules/index.js require('./real_module') === require('real_module') Example using new mechanism (post v6.0.0): --- node_modules/real-module -> ../real-module real-modules/index.js require('./real_module') !== require('real_module') As discussed in nodejs#3402
9cf3bdd
to
6564aae
Compare
Sorry, was too fast. Didn't actually fix the |
That way stat() only needs to be called once in most cases (assuming non _-prefixed symlinks are more common).
// If _basePath is a symlink, use the real path rather than the path of the | ||
// symlink as cache key. | ||
const _basePath = path.resolve(curPath, '_' + request); | ||
const basePath = path.resolve(curPath, request); |
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 above two lines need to be changed to use var
instead of const
to avoid aborted optimziations of _findPath()
by v8.
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.
fixed.
const in for-loop can not be optimized.
* Fixes `test-cwd-enoent-preload.js` * Minor performance improvement
@@ -190,15 +190,15 @@ Module._findPath = function(request, paths, isMain) { | |||
// For each path | |||
for (var i = 0; i < paths.length; i++) { | |||
// Don't search further if path doesn't exist | |||
const curPath = paths[i]; | |||
var curPath = paths[i]; |
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.
Actually, this line was fine. It was just the other 3 that were causing problems.
@alexanderGugel Assuming With the most recent changes I now see:
|
@mscdex Thanks. I would assume the performance regression is most likely because of functions not being optimised rather than unneeded syscalls, since the benchmarks most likely don't even cover those. |
@alexanderGugel Can you explain what you mean by "not being optimized?" |
37b7b5e means there are no additional Going to bed now. |
I will look into additional optimizations |
Ensure that `require('some-module/index.js')` is being resolved properly when `some-module` is a _-prefixed symlink.
@alexanderGugel I haven't had time yet unfortunately. I will try to dig into it this week though. |
It looks like the commit that broke this in the first place is about to be reverted, which would render this PR obsolete (#6537). So maybe the default should be changed... use the realpath of symlinks by default and use the path of the symlink if the linkname starts with That way backwards compatibility with v5.0.0 could be preserved while adding the ability to conditionally use the v6.0.0 mechanism (= path of symlink). |
+1 as a possible way to address the peer dependency bug. However, we should explore other ideas as well. |
Since we reverted to the old behavior and put the new behavior behind a flag is it safe to close this? |
Yup, although there is still no way to have both solutions. |
We still need a way get both behaviors working without a flag -- but I don't think this option was going to work (at least not on its own). |
Checklist
Affected core subsystem(s)
require()
)Description of change
Since #5950,
require('some-symlink')
no longer resolves the module to itsreal path, but instead uses the path of the symlink itself as a cache key.
This change allows users to resolve dependencies to their real path when
required using the _-prefix.
Example using old mechanism (pre v6.0.0):
Example using new mechanism (post v6.0.0):
As discussed in #3402