nx: React's babel/jest configuration is creating an error: Cannot use import statement outside a module

Hello,

Current Behavior

When running jest tests on a React component importing ky, the tests does not build because of Jest encountered an unexpected token error. Similar issues exist for @nrwl/angular and @nrwl/node, but none of the solution worked for @nrwl/react. I tried to fix the issue by modifying Jest configuration like on some other projects, but it didn’t work:

  testPathIgnorePatterns: ['<rootDir>/node_modules/'],
  transformIgnorePatterns: ['/node_modules/'],

Reading the other issues, I have a feeling the problem might come from babel-jest.

Expected Behavior

The tests should run.

Steps to Reproduce

Running npm run test on this repository: https://github.com/na-ji/nx-jest-transform I managed to reproduce this error from nx 12 to the latest nx 13.

Failure Logs

 nx run demo-jest-transform:test 
 FAIL   demo-jest-transform  apps/demo-jest-transform/src/app/app.spec.tsx
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /Users/naji/www/demo-jest-transform/node_modules/ky-universal/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import fetch, {Headers, Request, Response} from 'node-fetch';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      1 | import { useEffect } from 'react';
      2 | import styled from 'styled-components';
    > 3 | import ky from 'ky-universal';
        | ^
      4 |
      5 | import NxWelcome from './nx-welcome';
      6 |

      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1728:14)
      at Object.<anonymous> (src/app/app.tsx:3:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.662 s
Ran all test suites.

Environment

  Node : 14.17.3
  OS   : darwin x64
  npm  : 7.24.2

   nx : 13.5.3
   @nrwl/angular : undefined
   @nrwl/cli : 13.5.3
   @nrwl/cypress : 13.5.3
   @nrwl/detox : undefined
   @nrwl/devkit : 13.5.3
   @nrwl/eslint-plugin-nx : 13.5.3
   @nrwl/express : undefined
   @nrwl/jest : 13.5.3
   @nrwl/js : 13.5.3
   @nrwl/linter : 13.5.3
   @nrwl/nest : undefined
   @nrwl/next : undefined
   @nrwl/node : undefined
   @nrwl/nx-cloud : 13.1.2
   @nrwl/react : 13.5.3
   @nrwl/react-native : undefined
   @nrwl/schematics : undefined
   @nrwl/storybook : 13.5.3
   @nrwl/tao : 13.5.3
   @nrwl/web : 13.5.3
   @nrwl/workspace : 13.5.3
   typescript : 4.4.4
   rxjs : 6.5.5
  ---------------------------------------
  Community plugins:

Thanks.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 25
  • Comments: 26 (4 by maintainers)

Most upvoted comments

Not sure if this is an issue with nx or possibly something upstream such as babel-jest. Did take a look at what is being used in the current workspace generation (for a react application), and it looks like there’s been a shift towards ts-jest usage in app/lib jest.config.js.

module.exports = {
  ...,
  transform: {
    '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
    '^.+\\.[tj]sx?$': 'ts-jest', // <- note `ts-jest` usage here _not_ `babel-jest`
  },
  ...
}

Not sure if that’s an intentional change. This might also be a duplicate of https://github.com/nrwl/nx/issues/7844. Another related issue could be https://github.com/nrwl/nx/issues/8354. Definite head scratcher.

Any insight the nx folks provide would be greatly appreciated. Will say the issue seems to be super finicky on my local. Fresh clone + install of my repo sometimes does run into the and other times a fresh clone doesn’t 🤷‍♂️.

@airowe can you try adding the babel preset to the babel-jest transformer options like so '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }]

Is this issue fixed in PR #8075 ?

I can confirm this does not work on NX 13.5.3. This is probably because the problem is for every @nrwl/react configuration, not for nextjs only. Also, I’ve updated the demo project I linked in the issue: https://github.com/na-ji/nx-jest-transform

I’m labeling this as blocked by upstream since the original issue is about the package ‘ky-universal’ and there seems to be an issue with how the output of the bundled code being created is using top level await which an for modules, but the package isn’t specified to be a module from my understandings.

https://github.com/nrwl/nx/issues/8323#issuecomment-1233029828

as for the other packages most likely running into similar things or might be unrelated as noted by the mixed responses of things working for some and not others.

If there is a helpful feedback on working with this package, ‘ky-universal’, or similar situations folks have been in with similar packages feel free to comment. otherwise will be best to open a new issue.

@lordvins226 Thanks your help! Unfortunately, this configuration cannot transform module css file, because ts-jest has no presets option (link here).

Finally, I found the cause of this error! When I changed env variable from NODE_ENV=development into NODE_ENV=test, the test passed!

This works for me.

NODE_ENV=test yarn nx test client

I was able to get a somewhat different error.

    /Users/caleb/Work/na-ji/nx-jest-transform/node_modules/ky-universal/index.js:25
            globalThis.ReadableStream = await Promise.resolve().then(() => tslib_1.__importStar(require('web-streams-polyfill/ponyfill/es2018')));
                                        ^^^^^

    SyntaxError: await is only valid in async functions and the top level bodies of modules

by adding ky package transformIgnorePatterns in the apps/demo-jest-transform/jest.config.ts file

  transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$|ky-universal|ky)'],

this tells jest to transform the ky packages since jest only uses common js and both those packages use ESM.

but for whatever reason it’s unable to run the tests because of this top level await even though we are using node v16 which has top level await support.

screenshot of terminal output containing an example of toplevel await in the node REPL await Promise.resolve('works')

if I patch the node_modules (and install the polyfills) it works as an fyi. https://cloud.nx.app/runs/IYdfe3v3IZn

maybe ask the maintainer of ky-univseral to see if they can patch it? though they shouldn’t need to since toplevel await is like okay to use. I think this might be an issue elsewhere.

    globalThis.ReadableStream = (async () => await import('web-streams-polyfill/ponyfill/es2018'))();

different error is progress I guess?

Thanks @barbados-clemens! This got me working. Much appreciated.