nx: Can't run tests with jest 28.0

Current Behavior

I tried updating jest to the latest version (28) and started experiencing the classic TypeScript errors that you get when there are Babel / compiling TypeScript issues. For example: SyntaxError: Unexpected token 'export' or SyntaxError: Cannot use import statement outside a module I’m using babel-jest as the transform for my TypeScript tests.

Expected Behavior

I should be able to use jest 28 to run my tests.

Steps to Reproduce

Here is a repo reproduction. https://github.com/Tirke/jest-28

If you switch back to jest 27 it will work. They did communicate on some changes with Babel here

Failure Logs

Environment

❯ pnx report

 >  NX   Report complete - copy this into the issue template

   Node : 16.14.2
   OS   : darwin arm64
   pnpm : 7.0.0

   nx : 14.0.5
   @nrwl/angular : Not Found
   @nrwl/cypress : 14.0.5
   @nrwl/detox : Not Found
   @nrwl/devkit : 14.0.5
   @nrwl/eslint-plugin-nx : 14.0.5
   @nrwl/express : Not Found
   @nrwl/jest : 14.0.5
   @nrwl/js : 14.0.5
   @nrwl/linter : 14.0.5
   @nrwl/nest : Not Found
   @nrwl/next : Not Found
   @nrwl/node : 14.0.5
   @nrwl/nx-cloud : Not Found
   @nrwl/nx-plugin : Not Found
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : Not Found
   @nrwl/web : 14.0.5
   @nrwl/workspace : 14.0.5
   typescript : 4.6.4
   rxjs : 6.6.7
   ---------------------------------------
   Community plugins:

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 13
  • Comments: 29 (17 by maintainers)

Most upvoted comments

@eglove @rfprod it shouldn’t break anything once the nx migration is ran. the only thing that would get overridden I think would get overridden would be the jest version if they don’t match. Any breaking changes from jest 28 the migration would update would presumably already be fixed in your code base.

I’m going to try to finish the jest 28 migration this week. Just putting the final touches on the Cypress 10 support.

it’s in progress. the migrations are a bit tricky for this one.

@Ezard I’ve been running my own resolver for a while with Nx. I had to basically take the Nx resolver and drop in my own.

jest.preset.js

const nxPreset = require('@nrwl/jest/preset').default;
module.exports = { ...nxPreset, resolver: `${process.cwd()}/jest.resolver.js` };

jest.resolver.js

const fs = require('fs');
const path = require('path');
const nrwlResolver = require('@nrwl/jest/plugins/resolver');

// Compose your own resolver function
function jestNodeExportsResolver(request, options) {
  // Modify stuff
return nrwlResolver(request,{
  ...options,
  packageFilter: pkg => {
    if (pkg.name === 'uuid') {
      delete pkg['exports'];
      delete pkg['module'];
    }
    return pkg;
  }
});
}

module.exports = jestNodeExportsResolver;

If you look into the actual @nrwl/jest resolver, you’ll see that it first tries to resolve using the Jest default resolver with the options you provide. If that fails, then it overwrites with its own packageFilter. So in the example above, your resolver should get first shot at it. Since you are dealing with node_modules it should work out. https://github.com/nrwl/nx/blob/589637fd826739e112a4ef0adf812547bf869597/packages/jest/plugins/resolver.ts#L53-L72


Edit:

I will add that all configuration settings for tooling should be extendable/composable. A lot of Nx is, but there are some pain points like Next’s config and this resolver.

If anyone needs an example of an nx workspace that uses jest 28, check this one. There are two frameworks: NestJS, Angular.

Changes that have to be made:

If @angular/fire if used, one will have to mock the package depending on what’s used like

...
jest.mock('@angular/fire/app', () => firebaseAppMockValue);
jest.mock('@angular/fire/auth', () => firebaseAuthMockValue);
jest.mock('@angular/fire/database', () => firebaseDatabaseMockValue);
...

Don’t forget the firebase-auth side of things. I bet they face the same issues. I think nanoid also released a new version that is only ESM. I haven’t looked into how to get that one working.

The whole ESM migration is poorly thought out it seems now that we are in it all.

While there is a lot of focus on Angular within the Nx team, please don’t forget React! lol 😃

I’ve just about finished my manual migration and other cleanup. The biggest thing I was running into is documented here.

https://github.com/thymikee/jest-preset-angular/issues/1625

I had to work on setting up my resolver to remove object properties from the parsed package.json so it would target main instead of the module/exports fields for importing.

you can manually install jest-environment-jsdom v28 and jest v28 without any problems. @nrwl/jest isn’t going to stop you from manually updating those.

I’m working on getting a PR for jest 28 support. just mainly working through the migrations for the changes. but in my limited testing you can just bump all your jest versions and it should just work with the exception of using @nrwl/react/plugins/jest as it needs to be updated for the new transformer return type and of course if you’re using any of the changed apis in the jest vv27-v28 migration guide.

Jest 28 support is still in the works, but probably need to update ts-jest to v28 since transformer return changed a little. I think ts-jest v28 was still prerelease

In my case (a @nrwl/next app), changing the jest.config.ts transform from

'^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/next/babel'] }]

to

'^.+\\.[tj]sx?$': [ 'babel-jest', { presets: ['next/babel'] }]

did the trick.

Talking with other on this issue I think we’ll go with maintaining the list internally inside the nrwl resolver and if there is a reason you need to extend our resolver then following @Brian-McBride example on how to do it is a good way to do it.

While maintaining that list isn’t ideal, it does prevent

  1. people having to implement/nx generating a custom resolver
  2. not having a custom resolver makes migrations easier in the future
  3. we are reasonably good at being able to quickly make new releases if we need to update that list so shouldn’t be a huge issue for the most part.

Right now I know of the packages mentioned via jest-preset-angular docs and uuid. If there are any more packages that we need to target please let me know either here on in the jest 28 PR.

uuid
rxjs
@firebase/auth
@firebase/storage
@firebase/functions
@firebase/database
@firebase/auth-compat
@firebase/database-compat
@firebase/app-compat
@firebase/firestore
@firebase/firestore-compat
@firebase/messaging
@firebase/util
firebase

nx will add it via migration and going forward when jest v28 support is released. Just saying in the meantime it would probably be best to be explicit about the devDep to prevent it from being accidentally removed from others in the project.

@mkhib It’s most probably jest-preset-angular. It has to be updated to support jest 28. If you’re impatient, give this pre-release a try https://github.com/thymikee/jest-preset-angular/releases/tag/v12.0.0-next.1 However, no guarantees it will work, I haven’t tried.

Looks like it. there are still @types/jest and jest-preset-angular that need to drop support for jest v28 as well. jest-preset-angular hast a next tag and expected to release soon-ish.

@barbados-clemens seem like ts-jest 28 is now available https://www.npmjs.com/package/ts-jest