-
-
Notifications
You must be signed in to change notification settings - Fork 525
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
"Cannot find module 'msw/node'" in Jest JSDOM environment #1786
Comments
|
I got a similar error but running ESLINT
I'm not sure why this "node: null" is needed 👇 Lines 16 to 17 in a54138a
but removing it fixes my issue above |
This is what resolved it for me from the examples repository. I don't pretend to know what this does, but it works. https://github.com/mswjs/examples/blob/main/examples/with-jest/jest.config.ts#L20 |
For me, this works only partially. As it breaks other imports. |
We are unfortunately seeing the same issue when upgrading to v2. This is blocking us from moving to the new version. It is a Nextjs project and works without issue in v1 |
cc @kettanaito |
I have the same issue using
System: |
Why does this error happen?Because JSDOM forces the The Lines 23 to 24 in 1d1fbca
The same is true for the How to solve this?Opt out of the // jest.config.js
module.exports = {
testEnvironmentOptions: {
customExportConditions: [''],
}
} This will force JSDOM to use the If you encounter other import-related issued after this change, they aren't related and have to be addressed separately. Adding this recommendation to the migration guide as well so everyone could follow. |
Confirmed, now 🟢 passes in both |
I see that it is working for {
// ...
define: {
'process.env.NODE_ENV': `"${mode}"`,
},
build: {
target: ['ES2022'],
outDir: 'build',
},
server: {
open: mode === 'development', // <-- here (it was true before). It will be 'test' and will not open the server
port: 8101,
},
// https://vitest.dev/config/
test: {
globals: true,
environment: 'jsdom',
setupFiles: 'src/setupTests.ts',
},
// ...
} |
Disabling Jest's Instead, I'm using a custom Jest resolver to modify MSW's imports. Please note: This is a hack. It's deliberately doing something not intended by the MSW project. Subsequent MSW updates may break it. If you do this and it causes problems, please do not report any resulting issues to this project. To do this: In the Jest config, define your resolver:
And create it with the following contents: // Based on https://github.com/microsoft/accessibility-insights-web/pull/5421#issuecomment-1109168149
module.exports = (path, options) => {
// Call the defaultResolver, so we leverage its cache, error handling, etc.
return options.defaultResolver(path, {
...options,
// Use packageFilter to process parsed `package.json` before the resolution
// (see https://www.npmjs.com/package/resolve#resolveid-opts-cb)
packageFilter: (pkg) => {
if (pkg.name === 'msw') {
delete pkg.exports['./node'].browser;
}
if (pkg.name === '@mswjs/interceptors') {
delete pkg.exports;
}
return pkg;
},
});
}; |
Here's an improved version of my custom Jest module.exports = (path, options) => {
// Jest + jsdom acts like a browser (i.e., it looks for "browser" imports
// under pkg.exports), but msw knows that you're operating in a Node
// environment:
//
// https://github.com/mswjs/msw/issues/1786#issuecomment-1782559851
//
// The MSW project's recommended workaround is to disable Jest's
// customExportConditions completely, so no packages use their browser's
// versions. We'll instead clear export conditions only for MSW.
if (/^(msw|@mswjs\/interceptors)(\/|$)/.test(path)) {
return options.defaultResolver(path, { ...options, conditions: [] });
}
return options.defaultResolver(path, options);
}; If this works for others, it may be worth adding as an option in the docs. |
JSDOM is broken export conditions-wise, I believe I explained it at length. It's not about making MSW happy, it's about resolving third-party modules using the @joshkel, your custom resolver implementation looks interesting. I will leave it up to the people to decide which approach works best for them, but may I please stress this one last and final time: You need all this because you are using an OLD testing framework. Whether you decide to ignore the |
I have a similar situation Inside the test environment (using If I follow the instruction to remove the conditional Does anyone have any suggestions? |
I put a vitest config example here (#1786 (comment)). It is working for me. No need to do anything else. |
Please refer to the usage examples with Vitest that feature both ESM and CJS tests, all functional with MSW v2.0: I've also just migrated the entire internal test suite of MSW to Vitest yesterday without any issues. You don't need to configure JSDOM in any way for Vitest+MSW to work. |
Thanks for the reply, @kettanaito (and for your patience). If I'm understanding correctly, it's not a matter of Jest being old or not supporting modern module resolution. (Jest fully supports modern modules and module resolution, as far as I know - somewhat held back by issues in Node.js itself.) Instead, it's a legitimate trade-off:
Jest and jsdom seem to default to the first approach. jsdom won't use implementations if they're not W3C-spec-compliant, and Jest uses the VM API (I think) to exclude Node.js globals (so code under test won't mistakenly reference them), and Jest decides to emulate the browser as closely as possible when using jsdom, including honoring the Vitest takes the second approach (e.g., it exposes Buffer because "TODO a lot of dependencies use it") - but that means I can have production browser-side code that mistakenly references Buffer and passes tests and fails at runtime. MSW 2 picks the second approach (for reasons that you explain in depth), and I'm certain those are the correct tradeoffs for MSW - but now I have test failures because It wouldn't surprise me if Jest's tradeoffs are worse in general. (They've certainly caused a lot of complexity.) But it doesn't seem quite fair to say that picking a worse set of tradeoffs is broken. (I'm interested in switching to Vitest, but parts of the ecosystem still aren't there for my project.) I'm happy to accept MSW's decision as to appropriate tradeoffs when using it. (That's what I meant by "making MSW happy"; I apologize if I contributed to any confusion.) |
Sorry to drag this out more, but this is just not accurate @kettanaito. I understand the technical details of your explanation and the differences between Jest and jsdom are not "OLD" or outdated. As @joshkel mentioned, they provide a far more accurate testing environment for browser code. They are actively maintained and updated. They support the bleeding edge of browser changes and many wide-sweeping libraries and tools. I've already spent far too much time trying to work around this issue including your suggestion, using other DOM implementations that fall short (such as As such, this is a total blocker for us. We will not be sacrificing the accuracy of our tests in relation to the production environment they'll be running in for one library. Somehow all the thousands of other libraries we use haven't had this issue. This could be fixed for your users with some action on your part and you're choosing not to. That said, I understand if this is the direction you're taking the library. I'm not asking for anything and I expect nothing in return. I simply wanted to share feedback with you about the entrenched position you've taken that is very clearly not cut and dry like you've painted it. You spend your time making this awesome tool and I appreciate that, it's just that I'll be unable to continue using it going forward. Thanks for all of your hard work and maybe I'll still be able to use it on some other non-browser project because I really do like it a lot ❤️ |
This comment was marked as outdated.
This comment was marked as outdated.
Nope, my hopes were dashed. The custom resolver solution above is working great for me too. |
Just because I struggled a bit, I wanted to share our solution to this Error because this didn't help in our case while using Vitest. We were trying all attempts described here whithout succes. But then discoverd that the Error was thrown during coverage report generation. Our reporter "@vitest/coverage-istanbul" apparently looks at everything INSIDE our I also have this little sandbox to reproduce this. |
React Vite Vitest & MSW v2 still doesnt work 😵I have same problem on React 18, Vite 5.1.0 , Vitest 1.2.2 and MSW 2.0 See no resolution for that on Vite and Vitest config. I have checked example in Vitest from @kettanaito, but I cannot see the solution there... Like @mkalvas said, there should be separated solution in documentation below Jest solution, as Vitest is huge communitt as well. https://mswjs.io/docs/migrations/1.x-to-2.x/#cannot-find-module-mswnode-jsdom Waiting for solution guide for Vitest 🧪 |
So far have had to stop jsdom declaring that tests are running in a browser: mswjs/msw#1786 Fiddle with whatwg-fetch polyfill: reduxjs/redux-toolkit#1271 Still more things to fix, some presumably a consequence of first issue.
@joshkel thanks so much for this! Saved me a ton of time. I made one small tweak to this:
Namely, I left the conditions intact aside from filtering out browser. I'm still early in my testing, but this seems to be working for me and preventing another issue I was running into when I overwrote conditions to be empty. |
As a beer league hockey player, Given it's light outside, When I open the Wolfpack app, Then I see a light-themed app, So that it's easier on my eyes. As a beer league hockey player, Given it's dark outside, When I open the Wolfpack app, Then I see a dark-themed app, So that it's easier on my eyes. https://www.pivotaltracker.com/story/show/186950237 Some other notes: iOS uses [PlatformColor](https://reactnative.dev/docs/platformcolor)'s, while other platforms use regular [react native color keywords](https://reactnative.dev/docs/colors#color-keywords). Because of this, in order to test all the logic for a single color scheme (we use light), we needed to test the behavior on another platform (Android and web). The default platform that we'd been testing was iOS - only iOS. We now test on iOS and Android. We would have liked to have tested all of iOS, Android, and web, since we deploy all three, but we had [trouble getting MSW to work in the web environment](mswjs/msw#1786). We tried [the official solution in the docs](https://mswjs.io/docs/migrations/1.x-to-2.x#cannot-find-module-mswnode-jsdom) and several solutions mentioned in the issue page, linked above. None of those solutions worked well for us. In lieu of testing the web env, we're going to try to only do iOS specific things, and then any other logic that's used should be kept to work for both Android and the web environment, so that all the web environment features are still under test in the android test suite. The solution isn't ideal, but as long as we stick with this approach (and it'd be easy to forget or not do things this way, which is why it isn't ideal) all the specs should cover all scenarios in every environment. It's also worth noting that we decided not to test other color schemes (we only test light by default) because testing the dark color scheme seems like it won't add any value, unless we do [snapshot tests](https://jestjs.io/docs/snapshot-testing), which don't align well with the spirit of TDD (you write them after the fact) and would promote difficulting in refactoring (changing the <View> structure of a page (similar to changing the <div> structure of a webpage)) would cause a test to fail - which isn't what we're looking for in tests. We like to know that our feature specs still work after a change is made - which is to say we like to have confidence that our refactors don't change behavior, not that they don't change exactly _how_ features are implemented.
As a beer league hockey player, Given it's light outside, When I open the Wolfpack app, Then I see a light-themed app, So that it's easier on my eyes. As a beer league hockey player, Given it's dark outside, When I open the Wolfpack app, Then I see a dark-themed app, So that it's easier on my eyes. https://www.pivotaltracker.com/story/show/186950237 Some other notes: iOS uses [PlatformColor](https://reactnative.dev/docs/platformcolor)'s, while other platforms use regular [react native color keywords](https://reactnative.dev/docs/colors#color-keywords). Because of this, in order to test all the logic for a single color scheme (we use light), we needed to test the behavior on another platform (Android and web). The default platform that we'd been testing was iOS - only iOS. We now test on iOS and Android. We would have liked to have tested all of iOS, Android, and web, since we deploy all three, but we had [trouble getting MSW to work in the web environment](mswjs/msw#1786). We tried [the official solution in the docs](https://mswjs.io/docs/migrations/1.x-to-2.x#cannot-find-module-mswnode-jsdom) and several solutions mentioned in the issue page, linked above. None of those solutions worked well for us. In lieu of testing the web env, we're going to try to only do iOS specific things, and then any other logic that's used should be kept to work for both Android and the web environment, so that all the web environment features are still under test in the android test suite. The solution isn't ideal, but as long as we stick with this approach (and it'd be easy to forget or not do things this way, which is why it isn't ideal) all the specs should cover all scenarios in every environment. It's also worth noting that we decided not to test other color schemes (we only test light by default) because testing the dark color scheme seems like it won't add any value, unless we do [snapshot tests](https://jestjs.io/docs/snapshot-testing), which don't align well with the spirit of TDD (you write them after the fact) and would promote difficulting in refactoring (changing the <View> structure of a page (similar to changing the <div> structure of a webpage)) would cause a test to fail - which isn't what we're looking for in tests. We like to know that our feature specs still work after a change is made - which is to say we like to have confidence that our refactors don't change behavior, not that they don't change exactly _how_ features are implemented.
Still having the issue with vite, vitest and react... |
Got problem in Jest and
See discussion here: getsentry/sentry-javascript#10429 It turned out that it was this solution that caused it #1786 (comment)
When I changed to this solution #1786 (comment) with the custom resolver for just MSW, the error disappeared.
|
Jest provides a built-in way to do this. We still need to add polyfill to work with jsdom const config = {
testEnvironment: 'jsdom',
testEnvironmentOptions: {
customExportConditions: ['msw'],
},
};
module.exports = config; |
I found this was the custom resolver I needed to use, but I also needed to use the jest-fixed-jsdom environment - otherwise you get errors like:
|
I was at first thinking about applying the hack from @joshkel at #1786 (comment), but I opted to changing the testEnvironmentOptions: {
customExportConditions: ['node'],
}, This is more idiomatic, avoids the need to patch |
Prerequisites
Environment check
msw
versionNode.js version
v18.18.2
Reproduction repository
https://github.com/textbook/msw2-mre
Reproduction steps
npm ci && npm test
Current behavior
Error message
🔴 Failing Actions run
Expected behavior
The test should pass, as it does if you switch to the Node environment by updating
jest.config.js
as follows:Outcome:
The text was updated successfully, but these errors were encountered: