msw: Undici 6.x - Request/Response/TextEncoder is not defined (Jest) no longer works
Prerequisites
- I confirm my issue is not in the opened issues
- I confirm the Frequently Asked Questions didn’t contain the answer to my issue
Environment check
- I’m using the latest
msw
version - I’m using Node.js version 18 or higher
Node.js version
v18.19.0
Reproduction repository
http://
Reproduction steps
- Install latest version of Undici (6.x)
- Try to run tests
Current behavior
The documentation suggestion to create a jest.polyfills.js
no longer works in Undici version 6.x
All tests are returning the same error:
● Test suite failed to run
ReferenceError: ReadableStream is not defined
27 | Headers: { value: Headers },
28 | FormData: { value: FormData },
> 29 | Request: { value: Request },
| ^
30 | Response: { value: Response },
31 | });
32 |
Expected behavior
An update version of jest.polyfills.js
About this issue
- Original URL
- State: closed
- Created 7 months ago
- Reactions: 17
- Comments: 25 (7 by maintainers)
Commits related to this issue
- test: msw test setup - Add msw as a test dependency. Use v1 since v2 has jsdom issues (see https://github.com/mswjs/msw/issues/1916 and https://github.com/jsdom/jsdom/issues/2524) - Resolve fetch pol... — committed to dylants/bookstore by dylants 5 months ago
- test: msw test setup (#15) - Add msw as a test dependency. Use v1 since v2 has jsdom issues (see https://github.com/mswjs/msw/issues/1916 and https://github.com/jsdom/jsdom/issues/2524) - Resolve fe... — committed to dylants/bookstore by dylants 5 months ago
I’ve gotten to the point where I don’t personally think it’s worth it to migrate to v2 if you’re using Jest. Part of the amazing thing about this library on v1 is that it just worked. It was a magical DX when you compared it to the alternatives. But now, I’m highly advising anyone using Jest (which many of us are) to just continue using v1. I’ve followed the official migration docs with various levels of success but never able to reproduce the just works factor.
The library authors have taken a pretty clear stance that they consider Jest antiquated even though it’s currently 20x more popular than vitest according to npm downloads. And for the record, I do respect their right to take the library in that direction as the maintainers.
Conclusion
You are experiencing issues because Jest+JSDOM take away Node.js globals from you (the
structuredClone
global function in this case). For more info on this, see this and this.Solution
There is nothing we can or should do to fix legacy tooling that doesn’t embrace the platform. The issue here isn’t caused by MSW, so it’s not MSW that should be fixing it.
I suggest you migrate to a modern test framework, like Vitest. You are also welcome to tackle this in whichever fashion you choose, using custom Jest environment, downgrading to
undici@5
and other workarounds. I will not be recommending those because you don’t need them. The only reason you resort to them is because Jest forces you to. Naturally, I recommend migrating away from Jest.@azangru Thanks for the suggestion. I like it better than installing Undici and dealing with incompatibilities with each new version.
This is my
jsdom-extended.js
file if anyone wants to use the same approach:And then in the
jest.config.js
file:@joel-daros solution works when I combine it with some information from another issue thread. When I add his
testEnvironment
filejsdom-extended.js
and the following configuration injest.config.js
then it works as expected with Webpack, jest, MSW and SWR.File:
jest.config.js
File:
jsdom-extended.js
I have written an article on medium about it ⇾ Jest + React + MSW + Webpack — Solution for Errors
Update
Thank you so much everyone for battling your way through this. I think we should publish that custom Jest environment to NPM and recommend it officially for everyone using MSW (and beyond, really).
I’ve created the
jest-fixed-jsdom
repo to host that environment. I’ve invited @joel-daros, @tobiashochguertel, and @JamesZoft. You have the write access to that repo now. Please, push the source for that Jest environment and I will help you get it published to NPM! Will update the docs afterward too. Let’s solve these Jest issues once and for all.Thanks.
I had the same issue, but I’ve solved it with install web-streams-polyfill and modify jest.polyfills.js as bellow:
This is the classic answer: “It’s working on my machine”. 😄
I just want to chime in that the proposed solution using
web-stream-polyfill
did not work for me, but the alternate solution extending JSDOMEnvironment did work… sorta.I had to modify the solution as such:
Even though my tests did pass, I got a billion of these messages in my console:
As such, I’m gonna stick with using the previous major version of
undici
until either a more robust solution is presented, or I migrate to vitest.@robbieaverill @piyushchauhan2011 means a lot to me to hear this. I know issues like this suck. I also understand how natural it is to blame the tool that seemingly causes the issue when, in fact, it just helps it surface. I hope
jest-fixed-jsdom
will provide a better developer experience for everyone blocked by this. I hope even more that we migrate away from JSDOM and test browser code in the browser—that is the actual solution.@tobiashochguertel, thanks for putting the custom environment up!
So, because in the environment class’ context we’re still in regular Node.js, we can grab the globals without having to explicitly import them from anywhere? This is interesting. Sounds like it solves the
ReadableStream
/structuredClone
issue.My only concern with this is that it’s a workaround. I feel uncomfortable recommending workarounds. Granted, what we recommend in the docs right now is also a workaround, albeit with a bit smaller effect area. I’d much prefer to see those changes you propose to be a part of
jest-environment-jsdom
because without them, that environment is quite broken.Did you consider raising this as an issue/pull request to Jest? That would be a nice solution for everyone (and a contribution opportunity for you too!).
I solve it this way
I know this solution was frowned upon; but it’s been working well for me so far, and it does not require Undici.