Skip to content
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

Consider disabling JSDOM by default #5815

Closed
nickmccurdy opened this issue Mar 16, 2018 · 29 comments · Fixed by #9874
Closed

Consider disabling JSDOM by default #5815

nickmccurdy opened this issue Mar 16, 2018 · 29 comments · Fixed by #9874

Comments

@nickmccurdy
Copy link
Contributor

Do you want to request a feature or report a bug?
Default change proposal (semver breaking)

What is the current behavior?
Jest's default testEnvironment is jsdom. I understand the intention of Jest is to follow convention over configuration and make things like DOM testing very easy for beginners with minimal configuration, but there is a large overhead to having jsdom enabled by default (often 3 times as slow to boot per test suite in my experience) and I don't think most users even realize this is configuration.

What is the expected behavior?
I think swapping the default to node would be nicer (of course, not without deprecation warnings, semver major breaking changes, and possibly a helpful error message when the DOM is accessed in the Node env). While I tend to disable jsdom because I never need it, I often forget and I'd rather have the default settings optimize for performance in this case. I think this would keep the testEnvironment settings more consistent with Jest's other performance first defaults, like disabling coverage. It's also worth mentioning that many usages of Jest even in web code don't need jsdom, as shown in Jest's own documentation on react-test-renderer.

@anescobar1991
Copy link

anescobar1991 commented Mar 19, 2018

I think this could also go a long way to shed the perception that Jest is only for testing React components or that it is in any way tied to testing for web code. As surprising as it is this perception does still exist (at least people don't think it still mocks everything by default).

@nickmccurdy
Copy link
Contributor Author

I understand this is a potentially controversial and breaking change, would it help if I started a PR or should I wait for a discussion with more collaborators?

@rickhanlonii
Copy link
Member

The change should be pretty straightforward so I wouldn't recommend submitting it until we decide this is the direction we want to go

I agree that defaulting to node would be better, but I'm not sure when the timing would be right. This will be a breaking change for the majority of Jest users

@SimenB
Copy link
Member

SimenB commented May 27, 2018

@cpojer @aaronabramov @thymikee thoughts on this?

It's easier to google document is not defined than it is to discover your tests are a bit slower than they need to.

We could also potentially special case errors like document is not defined, window is not defined etc and provide a nice error message about setting environment.

@azz
Copy link
Contributor

azz commented May 28, 2018

I wonder if it possible to "detect" whether the code needs JSDOM or not?

  • Presence of imports "react", "jquery", ...
  • Use of the document or window global identifiers.

You could have the default "testEnvironment": "auto".

Not so sure on the idea myself, but worth considering?

@SimenB
Copy link
Member

SimenB commented May 28, 2018

we'd have to scan the entire dependency tree before we'd be able to start the test then. The dependency tree we have today is built up by looking at the sourcecode of every single file, and extracting require/import with regexes... Not sure if it'd be reliable enough?

@cpojer
Copy link
Member

cpojer commented May 28, 2018

Auto seems too magical. I think we can just switch the default. CRA can keep setting it to jsdom.

We can, however, add the error messages that you pointed out @SimenB. Known DOM globals (document, window, etc.) should trigger the error and ask people to update their config.

Bonus points for a jest --updateConfig feature that will automatically update the config rather than asking people to copy-paste stuff. That of course only works if the config isn't passed as a JSON encoded string to --config. Would be a cool feature, also for the transformers! cc @thymikee

@SimenB
Copy link
Member

SimenB commented May 28, 2018

I like jest --updateConfig, but I think we should encourage the docblock comment if say less than 25% of the tests require jsdom. Maybe not feasible

@cpojer
Copy link
Member

cpojer commented May 28, 2018

yeah makes sense.

@nickmccurdy
Copy link
Contributor Author

Node is the simplest built in env, right? Out of curiosity is there a third env?

@thymikee
Copy link
Collaborator

@nickmccurdy Jest only provides implementations for node and jsdom test environments.

@rickhanlonii
Copy link
Member

rickhanlonii commented May 28, 2018

So in summary:

Jest 23.x

  • Add warning for when there's no explicit environment set, "changing default env to node in Jest 24"
  • Detect errors on document or window and recommend switching env to jsdom

Jest 24.0.0

  • Switch default to node
  • Add jest --updateConfig

@SimenB
Copy link
Member

SimenB commented May 28, 2018

Detect errors on document or window and recommend switching env to jsdom

We can do that now - it'd be a pretty useful error regardless of defaults

@rickhanlonii
Copy link
Member

Good point, updated

@nickmccurdy
Copy link
Contributor Author

nickmccurdy commented May 28, 2018

Let me know if I can help with PRs.

@SimenB
Copy link
Member

SimenB commented May 28, 2018

PR very much welcomed for all except switching the default (we'll do that closer to next major)!

@cpojer
Copy link
Member

cpojer commented May 28, 2018

@rickhanlonii I'd prefer not to have any warnings or force people to choose a test environment. Can we make it so we use the same warning/error message that recommends people to use @jsdom to put testEnvironment: "jsdom" into their code (ie. accessing window/document shows the warning if it's not already explicitly set)? That way people who use Jest for node testing won't have to be bothered with this.

@SimenB SimenB added this to the Jest 25 milestone Mar 3, 2019
@SimenB
Copy link
Member

SimenB commented Mar 3, 2019

Changing the default is a breaking change, but what we can do in the meantime is add the warning (document/window is not defined blahblah) and ask people to use jsdom env. The switching of defaults will be a simple config change for the next major

@sachinmk27
Copy link
Contributor

Hi, is it okay if I give this a shot ?
Also I could use some pointers to get going.

@SimenB
Copy link
Member

SimenB commented Mar 22, 2019

Yeah! Just update jest-config/src/defaults.ts or whatever it's called (on mobile currently)

@SimenB
Copy link
Member

SimenB commented Mar 22, 2019

Look for _execModule in jest-runtime for where to put the warning about window and document

@SimenB
Copy link
Member

SimenB commented Mar 30, 2019

I've opened up #8245 as an attempt to give a nicer error if the wrong environment is used. Once we land it (or something like it), we can switch default environment in Jest 25 to node

@SimenB
Copy link
Member

SimenB commented Mar 28, 2020

^ landed, let's swap default for 26

@rickhanlonii
Copy link
Member

Wow huge

@nickmccurdy
Copy link
Contributor Author

FYI this is planned for Jest 27 (source)

@jeysal jeysal modified the milestone: Jest 27 May 29, 2020
@jeysal
Copy link
Contributor

jeysal commented May 29, 2020

Indeed, I've added the linked PR to the 27 milestone, after we mentioned it in the last blog post :)

@eddiemonge
Copy link
Contributor

Since the default is changing to node, can jest-environment-jsdom not be a required dependency of jest-config? That would remove a bunch of warnings on install as well as make it a lot faster. These warnings are all from the latest jsdom

image

@SimenB
Copy link
Member

SimenB commented Aug 1, 2020

It'll be bundled in 27 to ease migration and removed in 28 (probably)

Mentioned in the blog post: https://jestjs.io/blog/2020/05/05/jest-26

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants