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

feat: Jest 28 blog post #12732

Merged
merged 5 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions website/blog/2022-04-25-jest-28.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
title: 'Jest 28: Shedding weight and improving compatibility 🫶'
author: Simen Bekkhus
authorURL: https://github.com/SimenB
authorImageURL: https://avatars.githubusercontent.com/u/1404810
---

Jest 28 is finally here, and it comes with some long requested features such as support for [sharding](/docs/cli#--shard) a test run across multiple machines, [package `exports`](https://nodejs.org/api/packages.html#exports) and the ability to customize the behavior of [fake timers](/docs/jest-object#fake-timers). These are just some personal highlights, and we'll be highlighting more in this blog post.

Additionally, as announced in the [Jest 27 blog post](/blog/2021/05/25/jest-27) last year, we have removed some packages that no longer are default from the default distribution. As a result the installation size has dropped by about 1/3.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

<!--truncate-->

## Breaking changes

The list of breaking changes is long (and can be seen fully in the [changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md#2800)), but for migration purposes, we've also written [a guide](/docs/upgrading-to-jest28) you can follow. Hopefully this makes the upgrade experience as frictionless as possible!

Main breaking changes likely to impact your migration are dropped support for Node 10 and 15 (but _not_ Node 12, which will be EOL in a few days) and some renamed configuration options.

Additionally, both of the removed modules (`jest-environment-jsdom` and `jest-jasmine2`) are still actively maintained and tested in the same way, so the only breaking change here is that you'll need to explicitly install them.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

The guide should hopefully make migration trivial, but note that if you use any of the packages Jest consists of directly, instead of just running `jest`, then you need to go through the changelog to view any breaking changes.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

## Features

Now let's talk about the new features in Jest 28, which is way more exciting! And there's quite a few of them, so buckle up.

### Sharding of test run

Jest now includes a new [`--shard`](/docs/cli#--shard) CLI option, contributed by [Mario Nebl](https://github.com/marionebl). It allows you to run parts of your test across different machine, and has been one of Jest's oldest feature requests.

Jest's own test suite went from about 10 minutes to 3 on Ubuntu, and on Windows from 20 minutes to 7.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

### `package.json` `exports`

Jest shipped minimal support of [`exports`](https://nodejs.org/api/packages.html#exports) in 27.3. However, it only supported the "main" entry point (`.`), and only if no `main` field was present in `package.json`. With Jest 28 we're excited to finally be shipping full support!

Related, in Jest 27, we provided either `require` or `import` condition. In Jest 28, `jest-environment-node` will now automatically provide `node` and `node-addons` conditions, while `jest-environment-jsdom` will provide the `browser` condition.

This has been one of the biggest compatibility issues of Jest, and hopefully this is now resolved once and for all.

### Fake timers

Jest 26 introduced the concept of "modern" fake timers, which uses [`@sinonjs/fake-timers`](https://www.npmjs.com/package/@sinonjs/fake-timers) under the hood, and Jest 27 made it the default. In Jest 28, we are now exposing more of the underlying implementation through both configuration and runtime APIs. Huge thanks to [Tom Mrazauskas](https://github.com/mrazauskas) who contributed this feature!

This allows you to for instance not mock out `process.nextTick` which improves compatibility with fake `Promise`s, or to enable `advanceTimers` to automatically advance timers.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

Please see [its configuration](/docs/configuration#faketimers-object) for details.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

### GitHub Actions Reporter

Jest now ships with a reporter to be used on GitHub Actions, which will use annotations to print test errors inline.

![GitHub Actions test error screenshot](/img/blog/28-gh-actions-reporter.png)

You can activate this reporter by passing `github-actions` in the [`reporters` configuration option](docs/configuration#reporters-arraymodulename--modulename-options).

Huge thanks to [Bernie Reiter](https://github.com/ockham) and other contributors for sticking by us and finally landing this feature.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dang, this is sweet. Can detection be automated into jest instead of setting a config option?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can probably make it default. I would like colors to work first, but that's a GH thing


### Inline `testEnvironmentOptions`

You can now pass [`testEnvironmentOptions`](/docs/configuration#testenvironmentoptions-object) inline in a file, similar to how you can set test environment. This is useful if you want to e.g. change the URL in a single file.

```js
/**
* @jest-environment jsdom
* @jest-environment-options {"url": "https://jestjs.io/"}
*/

test('use jsdom and set the URL in this test file', () => {
expect(window.location.href).toBe('https://jestjs.io/');
});
```

### All Node.js globals

If you are using the new [`fetch`](https://nodejs.org/en/blog/announcements/v18-release-announce/#fetch-experimental) implementation in Node v18, you might have noticed that this function is not available in Jest. It has been a long-standing issue that we have to manually copy over any globals into the test globals. With Jest 28, this is no longer an issue as we now inspect the global environment Jest itself is running in, and copy over any globals that are missing in the test environment.

### ECMAScript Modules

Not much has changed in Jest's support for native ESM since Jest 27 came out. We continue to be blocked by [stabilization in Node](https://github.com/nodejs/node/issues/37648), and are hopeful this situation will improve sooner rather than later!

However, we have been able to add a couple of new features in Jest 28.

#### `data:` URLs

[Tommaso Bossi](https://github.com/tbossi) has contributed support for [`data` URLs](https://nodejs.org/api/esm.html#data-imports), meaning you can now inline define some JavaScript to run without using `eval`.

#### `import.meta.jest`

While you have been able to access `jest` via `import {jest} from '@jest/globals'` in Jest, we've received feedback that this is less ergonomical than the (seemingly, but not really) global `jest` variable available in CJS. So Jest 28 ships with `import.meta.jest` to allow easier access.

### Miscellaneous

That's quite a lot of features, and are personal highlights. However, we still have many more, of which I'll quickly go through a few of.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

#### Asynchronous resolvers

[Ian VanSchooten](https://github.com/IanVS) has contributed support for [asynchronous resolvers](/docs/configuration#resolver-string), which enables tools like [Vite](https://vitejs.dev/) to have better integrations with Jest.

#### Asynchronous setup files

If you have some async work you want to do when using `setupFiles`, you can now export an `async function`, which jest will call and await before loading any tests.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

Note that this feature is only available for CJS. For ESM, we recommend using top-level `await` instead.

#### Using `globalThis`

Internally, Jest has been using `global` to refer to the [global environment](https://developer.mozilla.org/en-US/docs/Glossary/Global_object). However, since this only exists in Node, and not browsers (`window`), this led to incompatibility when attempting to use Jest's modules in another environment.

Jest 28 uses [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) instead, which works in all environments.

#### JSDOM 19

While, as mentioned, Jest no longer ships `jest-envrionemt-jsdom` in the default installation, it is still actively maintained. As part of that, Jest 28 has upgraded from `jsdom@16` to `jsdom@19`.

## TypeScript

If you use Jest with TypeScript, either in your tests or when writing plugins such as custom runners, Jest 28 comes with extensive improvements to our types. Here's a non-extensive list of the changes in Jest 28.
SimenB marked this conversation as resolved.
Show resolved Hide resolved

### `expect`

When using `expect`'s own types (either directly, or via `import {expect} from '@jest/globals'`), it's now finally possible to add custom matchers. See our [example](https://github.com/facebook/jest/tree/main/examples/expect-extend) for how to do this.

### Custom plugins

If you write a custom runner, test reporter, resolver or something else, we now export more types that should help you type these more correctly. This is a moving target, so if you are the author of something pluggable in Jest and the types aren't as useful as they could be, please file an issue!

### `jest-runner-tsd`

[`jest-runner-tsd`](https://github.com/jest-community/jest-runner-tsd) is a custom runner for running type tests. This is what Jest uses itself to test our types, and we hope it can also be used by others! As its name implies, it is based on [`tsd`](https://npmjs.com/package/tsd), although it under the hood uses the fork [`tsd-lite`](https://npmjs.com/package/tsd-lite).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very cool, and so is tsd-lite


---

All of these improvements and fixes has been contributed by [Tom Mrazauskas](https://github.com/mrazauskas). Thank you so much, Tom! 👏

Lastly, the minimum support version of TypeScript is now 4.3.

## `jest-light-runner`

The last thing we want to highlight in this blog post, is a very cool new Jest runner, created by [Nicolò Ribaudo](https://github.com/nicolo-ribaudo), called [`jest-light-runner`](https://www.npmjs.com/package/jest-light-runner). This takes almost of the DX Jest is known for, and speeds it way up by being a smaller abstraction on top of Node. Babel's tests became almost twice as fast after migrating. While there are caveats, the existence of this runner should make it even easier for people who have smaller Node modules to test to choose Jest. Thanks, Nicolò!
SimenB marked this conversation as resolved.
Show resolved Hide resolved

## Future

While Jest 28 came almost a year after Jest 27, Jest 29 will be coming sooner, probably in just a few months. The current plan then is to just have one breaking change (except dropping Node versions), and that is to default [`snapshotFormat`](/docs/configuration#snapshotformat-object) to `{escapeString: false, printBasicPrototype: false}`. This makes snapshots both more readable and more copy-pasteable.

This will of course be possible to override if you don't want to change, but you can also use those options today if you don't want to wait!

## Acknowledgements

Jest 28 contains contributions from more than 60 people, of which about half are first time contributors. Thank you so much to all contributors, old and new. Without you the project wouldn't be nearly as good as it is! I'd particularly like to thank [Tom Mrazauskas](https://github.com/mrazauskas) and [Feng Yu](https://github.com/F3n67u) for all their contributions, from code, to issue triaging to debugging, that made Jest 28 what it is. Thank you! 🙏
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice text. Reads well!

Thank you for moving Jest forward and also thanks for good questions!


Thanks for reading, and happy Jesting! 🃏
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.