Closed davidje13 closed 3 years ago
I would try https://github.com/vyushin/file-replace-loader . It may look like this.
let fileReplaceLoader = require.resolve('file-replace-loader')
let testEnvironment = process.env.NODE_ENV = 'test'
neutrino.config
.when(testEnvironment, function(config){
config.module.rule('replace-svg')
.use('file-replace')
.test(/\.svg$/i)
.loader(fileReplaceLoader)
.options({
condition: 'if-replacement-exists',
replacement: resolve('./tests/mock/svgr.js'),
async: true,
})
.end()
.end()
})
I could make some mistakes because didn't run it. You can change it to match your needs
@constgen that may be a viable workaround but it's not a proper solution considering Jest has this capability built-in.
For now my preferred workaround is to set jest.config.js to:
const neutrino = require('neutrino');
const config = neutrino().jest();
config.moduleNameMapper = {
'\\.svg$': config.moduleNameMapper['\\.svg$'],
...config.moduleNameMapper,
};
module.exports = config;
(which applies the fix shown here as a post-processing stage)
Proposed change is not a fix but a new feature. Which also applied only to Jest. Other testing frameworks may still stay broken when work with SVGR. So I suggest better develop SVGR middleware which will be testing framework agnostic and doesn't require changes to core middlewres. It is easier to upgrade versions and move forward for both Neutrino and community middlewares in such architecture. Also just look at this example
module.exports = {
use: [
svgr(), // future SVGR midleware
jset()
]
}
In you case svgr()
has no chane to modify Jest config as it is not a part of webpack-chain. The end user will have to jest({ moduleNameMapper: {'\\.svg$': '<rootDir>/mocks/svgr.js'}})
every time. In my case no extra configuration is required. Everything works out of the box because svgr()
will setup everything.
Take SVGR out of the equation for a moment; the feature added here is the ability to set part of Jest's configuration which is currently not configurable if using neutrino.
Looked at one way, you could say this is a bug fix because it makes the ability to override configuration more consistent (if you set rootDir
, testRegex
, testEnvironment
, etc. they will all override the default config coming from neutrino due to the deepmerge
call. But it is currently only possible for users to override the default moduleNameMapper
config if they set the exact same key that neutrino sets. This is because Jest uses the order of the properties (tut tut) to determine priority, but of course deepmerge
has no idea that's the case. It merges properties the other way around because really why shouldn't it; no sensible person would ever rely on property ordering in JavaScript. The combination of these two things in the upstream projects causes an observable inconsistency in neutrino. Other configurable fields are not affected by this (except maybe transform
but I don't know so I left it as-is for now).
The fact that I discovered this problem while working with svgr is mostly coincidental, and I put those notes in just to give context on why this matters. The core of this is fixing the configuration precedence in the Jest module.
Other modules might have similar bugs which could be fixed separately, but I'd be surprised; the root cause here is Jest's bad choice of using object property ordering to determine priority.
Now I really see what you mean. It makes sense. If I was a maintainer I would confirm this PR.
This has been released in Neutrino v9.5.0 :-)
As explained in #1650, this small change makes it possible for users to override default configuration for Jest's
moduleNameMapper
.Specifically, this is important for me so that I can integrate svgr into my project correctly;
(without this change, the above
.svg
rule is ignored due to the built-in rule taking priority; Jest follows the key ordering of the entries inmoduleNameMapper
).I do not expect this to break anybody's config unless they had it misconfigured to begin with. If it does break for anybody, the fix is to remove any user-provided config that was previously being ignored.