-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
fix: add global path in require.resolve.paths #13633
Conversation
Hi @lvqq! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
2bf0efe
to
349dd7d
Compare
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.
Hi, thanks for the contribution! I left some comments on things that struck me as potentially not ideal
packages/jest-runtime/src/index.ts
Outdated
@@ -1454,8 +1464,10 @@ export default class Runtime { | |||
return moduleRegistry.get(key) || null; | |||
}, | |||
}); | |||
|
|||
module.paths = this._resolver.getModulePaths(module.path); | |||
module.paths = [ |
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.
While I haven't profiled this and can't know the perf impact for sure, this is a code path that runs very often, so I'd rather be safe and do something like
module.paths = this._resolver.getModulePaths(module.path);
if(moduleName) module.paths=[...module.paths, ...this._resolver.getGlobalPaths(etc)]
But read the other comment first, perhaps this code might change anyway
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.
Also, cc @SimenB who knows more about the ESM impl cause I don't know all implications changing module.paths
might have
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.
module.*
is unused in ESM, so any change to it shouldn't affect ESM stuff
const globalPaths: Array<string> = []; | ||
|
||
const paths = require.resolve.paths(moduleName); | ||
if (paths) { |
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.
I may be missing something, but do we need to spend CPU time to grab the global paths every time? I'm thinking the solution could be as simple as grabbing those global dirs once, probably just straight away in nodeModulesPaths.ts
:
const GLOBAL_PATHS = findGlobalPaths();
function findGlobalPaths() {
const paths=require.resolve.paths('/')
// findIndex, slice, etc.
}
and append them to the paths list?
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.
LGTM
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.
I agree with grabbing only once, but it cannot be directly in funtion nodeModulesPaths
since module paths will be cached. For instance, if the path without module name is cached. then it won't update. I'd add a new function to export
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.
Not sure I understand the caching problem. We're talking about the "global paths" that come after /node_modules
. Aren't they independent of the moduleName
, something like
[
'/home/user/.node_modules',
'/home/user/.node_libraries'
]
Thanks for your reviewing! I will update it later |
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.
thanks! few things to perhaps improve on the test other than that looks good.
not sure how worried I should be about any _execModule
performance impact @SimenB (other than that it seems to only affect the require.resolve
code path)
expect(globalPaths).toStrictEqual([]); | ||
}); | ||
|
||
it('return empty array with absolute path', () => { |
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.
it('return empty array with absolute path', () => { | |
it('return global paths with absolute path', () => { |
@@ -707,3 +707,51 @@ describe('Resolver.getModulePaths() -> nodeModulesPaths()', () => { | |||
expect(dirs_actual).toEqual(expect.arrayContaining(dirs_expected)); | |||
}); | |||
}); | |||
|
|||
describe('findGlobalPaths', () => { |
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 removed I think, it's kind of internal and we're testing it through Resolver.getGlobalPaths
jest.doMock('path', () => _path.posix); | ||
const resolver = new Resolver(moduleMap, {} as ResolverConfig); | ||
const globalPaths = resolver.getGlobalPaths('jest'); | ||
expect(globalPaths.length).toBeGreaterThan(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.
Probably we could test this more precisely with something like
expect(globalPaths.length).toBeGreaterThan(0); | |
globalPaths.forEach(globalPath => expect(require.resolve.paths('jest')).toContain(globalPath)) |
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.
Thanks! I will update it
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.
lgtm, added a changelog entry and clarified logic a bit. waiting a bit to see if @SimenB wants to review
…aths * origin/main: fix typecheck:tests type err
Pushed a commit to main fixing 2 of the 3 I did not fix the third one in Either way it's definitely not caused by this PR so don't need to block this on it. |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
Close #13439, add global path supported in
require.resolve.paths
.Test plan
Test cases have been added under
packages/jest-resolve/src/__tests__/resolve.test.ts
.And with this changes,
require.resolve.paths
could react global paths under jest's scope.Example in https://github.com/lvqq/jest-require-resolve-paths with the following changes works fine