-
-
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
Initial support for Resource Queries #6282
base: main
Are you sure you want to change the base?
Conversation
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up 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 the corporate CLA signed. If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
Anyone? :) Having support for Resource Queries will make Jest even more modular. Imagine, that users could pass parameters to resolvers, runtimes or transformers. This allows a bunch of applications, esp. for dynamic instrumentation. |
@rubennorte @rafeca any opinions here? Would something like this be useful for e.g. metro? |
Codecov Report
@@ Coverage Diff @@
## master #6282 +/- ##
==========================================
+ Coverage 64.92% 64.98% +0.05%
==========================================
Files 288 283 -5
Lines 12199 12108 -91
Branches 3024 2992 -32
==========================================
- Hits 7920 7868 -52
+ Misses 3639 3604 -35
+ Partials 640 636 -4
Continue to review full report at Codecov.
|
3ed57c8
to
c42c110
Compare
packages/jest-runtime/src/__tests__/test_root/moduleWithResourceQuery.js
Outdated
Show resolved
Hide resolved
c42c110
to
4040368
Compare
4040368
to
29e1b0c
Compare
Anyone 🙏😤😇 |
This feature would be awesome. I hate just mocking every ressource query. |
This is a dirty workaround, but I have no time now to make it proper. The proper solution, btw, would be to make Jest understand query params in imports jestjs/jest#6282
How are you mocking resource queries @veitbjarsch ? For me Jest will complain that the module cannot be found. Cannot find module '../assets/user_background.jpg?min=320&max=800&steps=3' from 'index.test.tsx' |
Sadly, no motion around this issue @peter-leonov are you still driving this? |
I’d love to drive, but I’m not sure what else to do and who to poke 😅 |
I think we can start by reviewing some conflicts this has with master now |
Being there, done that:
|
So sorry about the slow response here @peter-leonov! We'll need this for ESM support (#9430), see https://nodejs.org/api/esm.html#esm_url_based_paths. I'll try to find the time to dive into this at some point, but if you have time to work on it, I'd love to help land changes! I don't really care what bundlers do with queries (the resolver is pluggable, so people can swap it out if they want something for webpack specific syntax), we should follow whatever the ESM spec tells us to do. From node's short docs above it's just returning a separate module instead of the cached one. Does the fuller ESM spec say anything more? Should it be added to
Thinking about it, I disagree with myself. For |
@SimenB, thanks for spending time to dig this one out! I'm still up to finish this one, will look into closer asap. |
3b718bc
to
0e03d34
Compare
Rebased the branch (my own migration experience from Flow to TS helped a lot).
True, but it still is important to keep that original file name with the query suffix somewhere in the API for other parts of Jest (or it's plugings) to inspect, right?. Otherwise we loose the whole point of having queries in the first place: to modify the module's perceived content. For example, I have a use case for my own tool (kinda like What do you think, @SimenB? |
We can provide it to custom resolvers maybe? That way you can plug in some other resolver if you want, and use the query to do something. It might make sense to also provide it to code transforms, that way you can use it to transform files in any way you want (like how Default behaviour in Jest should match Node.js - so it should be to not find the module when using CJS and to use it as a cache vary for ESM. Since we don't support ESM yet, for now it should cause a Some interesting discussion for how it'll affect ESM here: nodejs/modules#417 |
That's a good idea and it will require a quite significant change in the The issue why a more significant change is required is that the tail of the chain described above has type I believe, that making such an API change in now clearly required to support ESM modules, but I'd like to first agree on a hight level solution first and then only continue. As I'm very new to the Jest dev process, maybe you can help me here with a bigger picture view? |
Cool, thanks for the instant replies! Starting getting my hands dirty then. The plan is as simple as:
And maybe:
Next steps:
|
0e03d34
to
413db38
Compare
11b581a
to
501ed69
Compare
501ed69
to
23c174f
Compare
Hey @SimenB, I'd like to check with you if this PR is going in the right direction. |
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've let this sit in the slow cooker for some time now, and I now think we don't need to change the API of the resolver here.
I think we can just
- pop of any query
- resolve as normal
- re-add the query when passing the resolved path back.
so you'll do Resolver.findNodeModule('./bla.js?hey=there')
and get back /some/absolute/path/bla.js?hey=there
. Then it's up to the caller what to do about the query
I think it makes sense for jest-runtime
to extract the query so it can be used to vary the cache and pass it as its own argument to @jest/transformer
so it can pass it on to transformers.
Thoughts?
) | ||
.update(CACHE_VERSION) | ||
.digest('hex'); | ||
return ( |
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.
There's also https://github.com/tc39/proposal-module-attributes to consider |
This PR is stale because it has been open 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
@peter-leonov hiya! 👋 is this thing still alive? Minimal support for query was added in #9914. As for import assertions (which the above linked proposal has been renamed to), #12755 has a start on that. |
This helps to simplify the Jest configuration and to reduce the mocking too. It's somehow related to the fact that Jest does not fully support resource queries, see jestjs/jest#6282
This PR is stale because it has been open 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
Any chance we could get this PR merged at one point please? |
This PR is stale because it has been open 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
Any chance we could get this PR merged at one point please? |
UPDATE: See this comment for the changes plan and the latest progress.
TL;DR; this PR needs an architecture decision for further development 🙏DONE in the comment linked above 🎉Backstory
Resource Queries is a relatively recent trend defined by support by WebPack's import() and in ES6 import(). Having Resource Queries supported in dynamic
import()
means it should be also supported in staticimport * from 'module'
. It is expected that developers will build features on top of the web driven semantics ofimport
, so it would be of use to have basic support for Resource Query aware plugins in Jest as well.As decided in #4549 this PR should only demonstrate how minor would be the impact fo the Solution 3 described below. A scope of the final goal is defined in #4181 (comment).
Description
Firstly, here go file path use cases in the core test running process:
Solution 1: Smart filename
Full scale solution satisfying all use cases would be to teach a user defined
resolver()
to return an object{path, id}
instead of a string, and then refactor all the code which uses typePath
, as currently the full module path is (expectedly) used as a uniq file identifier across many modules;Good example is the
getScriptCacheKey()
at script_transformer.js. It needs a module file path to get it's mtime and also the file id to add it to the key, as for the same physical file the modification time will also be the same leading to the same cache keys for two different resources queries. Here is how it might look like:Solution 2: Smart resolver
Less aggressive approach might be to just teach Jest to transform original file path before use in functions from
fs
andpath
modules with new method of resolver (say,getFsPath()
). This could enable a native support for Resource Queries by default or any other file path overloading. This will require changing code in few places where Jest runtime touches filesystem or needs a real file name by injecting thatgetFsPath()
.The example with
getScriptCacheKey()
would then look like this:Solution 3: Too smart fs module
The most general and least intrusive solution (but also kind of hacky) is to make the
fs
module configurable, so that a plugin developer can provide a version offs
which tolerates the resource query appendix. This might be a first baby step towards a full Resource Query support. This solution breaks though two use cases. The one where a module file name extension is used to select a transformer (path.extname('a.out?query')
return'.out?query'
). The other one is matching a module file path against an ignore RegExp (as/test/.'/path/to/load.js?ab_test=1'.
returnstrue
). This could be partially fixed by prefixing a file path with filters (like webpack does) internally instead of appending.If you know how to better resolve this architectural challenges, please, help 😊