Do you want to request a feature or report a bug?
~Bug~ Feature.
What is the current behavior?
Jest fails to apply a transform to a file if the import path includes query parameters. The associated test fails with the following error.
Cannot find module './puppy.jpg?sizes=300w' from 'withQueryParams.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:179:17)
at Object.<anonymous> (withQueryParams.js:1:104)
If the current behavior is a bug, please provide the steps to reproduce and either a repl.it demo through https://repl.it/languages/jest or a minimal repository on GitHub that we can yarn install and yarn test.
You can recreate the unexpected behavior with this reproduction repository.
What is the expected behavior?
Jest should transform the imported file that matches the transform config regex. The associated test should pass.
Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.
{
"jest": {
"transform": {
"^.+\\.(gif|png|jpg|ttf|eot|svg)(\\?.+)?$": "<rootDir>/__mocks__/fileMock.js"
}
}
}
20.0.48.2.10.27.55.3.010.12.6Is there anything else I can do to help verify that this is a legitimate bug? Thanks.
This is not a bug, this is an unsupported feature. If you'd like this to be supported in Jest, you'll need to go through sending a PR for it with tests yourself.
@cpojer thank you for the follow up. I'll update this ticket to be a feature request and work on a PR for this addition.
Ran into the same problem as the @dcalhoun where Jest test explodes if import declarations include resourceQuery: import file from 'path/to/file?resourceQuery'.
I saw the PRs for stripping out /\?.*/ getting rejected, and extracted it into a babel-plugin that can be used with babel-jest. I think this will solve the majority of issues people have with resourceQueries.
https://www.npmjs.com/package/babel-plugin-import-remove-resource-query
Thank you @hkjorgensen! Can you mention the plugin in Webpack tutorial?
Hey here! The functionality of a file path query is quite essential for some sort of plugins, like introscope which I'm working on now. To allow a unit test developer to mark a particular import to be instrumented with a babel plugin of mine (much like code coverage, but less advanced), I've implemented a monkey patch which enables Jest to allow adding query strings to a module name like this:
const { introscope } = require('./my-module?introscope');
The monkey patch is surprisingly short, but, surely, it was huge before refactoring. It tries hard to preserve all the Jest functionality like caching, watching and code coverage while still allowing queries.
As I now understand Jest's architecture a bit better I'd be happy to invest more time and make module name queries first class citizens in Jest.
@cpojer, @dcalhoun, what do you guys think?
If you have answers for the questions posed in #4549 I say go for it!
Let's see if I have :)
It resulted in a long read, but there are TL;DR; 馃槆
What happens when I want to do: require('foo?a') and require('foo?b')?
TL;DR; Same as for require('foo.a') and require('foo.b')
My mental model for queries in module names is exactly the same as for a normal URL. These two modules should be treated as different with no assumptions on equality of their contents.
But the sensitive part I've found doing monkey patching is that a user still would like to see error messages pointing to a real file in filesystem without the query so that a control-click in smart terminal leads to the real file and line number. With errors coming from Babel plugin it was ok, as it supports any file name as a parameter to transform() to provide proper source maps. I'm sure it would not be a big deal to tweak Jest to report errors using format like file/system/path with query ?foo&bar if there is any query. Or something better :)
What will happen in various bundlers that support this syntax?
TL;DR; Depends on which transformer get's the query.
I can speak for Webpack only as it's my primary bundler. As found in Webpack the resource queries are used in rules to filter loaders application and also provide it as a free variable. This might lead us to a concept of loaders, which I see as a too big shift for this little issue. Anyway, forwarding a module query to a transformer might set free some power for loader/transformer writers, say, to make a plugin for more Webpack friendly and delightful JavaScript testing. ;)
Introscope, as an example of non-intrusive loader/transformer, passes query by modifying module content with a magic comment and Babel plugin parses it then from there. It would require no modifications to Jest if the query could somehow be given to general transformer API and in case of babel-jest given to Babel's transform() as an ordinary option, like jestModuleResourceQuery.
If they are two JS files, will they be the same module instance or will they evaluate the possibly same code twice?
TL;DR; No, not the same instance, and yes code might get duplicated.
In terms of resource queries, it's expected that user wants a different behaviour of a module required with a different query. So, in general, the user will some times evaluate same code twice as it would happen for two files 'foo/a and 'foo/b. Here I find it possible to utilise the multilayered caching system of Jest, so that if on the transform stage the same file content get's produced Jest might reuse the same Script object to just run it in a different Context.
Are they to be considered separate modules, or the same ones?
TL;DR; Separate.
In line with the questions addressed above, I would say yes, they should be considered as separate modules in the highest layer of Jest's caching system.
With this change to Jest, what is the behavior and how does it diverge or match those bundlers?
TL;DR; Depends on the plugin writers.
If we decide to keep the scope of this issue as small as possible, then it is for the future contributors to decide how their Jest plugins going to use resource queries to mimic which bundler. I see supporting the adding queries to a module in Jest as a first step towards more robust plugin writing including a tooling for Webpack users.
Thanks for your time reading this!
Hey guys, @cpojer, @SimenB, I'm not aware of how you make decisions and spread work in Jest community and that's why I'm asking for help on making decision on if should I move forward and if yes what should be the acceptance criteria for a PR like this to be smoothly merged? 馃槉
@mjesun, thoughts on ^?
Yes / No / Banana? 馃お
Yes. I'm now trying to make resource queries work with adjustments to resolver.
Most helpful comment
Ran into the same problem as the @dcalhoun where Jest test explodes if import declarations include resourceQuery:
import file from 'path/to/file?resourceQuery'.I saw the PRs for stripping out
/\?.*/getting rejected, and extracted it into a babel-plugin that can be used withbabel-jest. I think this will solve the majority of issues people have with resourceQueries.https://www.npmjs.com/package/babel-plugin-import-remove-resource-query