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

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

Closed
na-ji opened this issue Dec 29, 2021 · 26 comments
Assignees
Labels
blocked: third-party outdated scope: testing tools Issues related to Cypress / Jest / Playwright / Vitest support in Nx stale type: bug

Comments

@na-ji
Copy link

na-ji commented Dec 29, 2021

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.

@wootencl
Copy link

wootencl commented Jan 7, 2022

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 #7844. Another related issue could be #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 🤷‍♂️.

@benediktms
Copy link

I'm encountering a similar problem with my workspace in a Next.js app. I did some testing, and the problem form me stems from using ESModules (I think; I commented out all other code in my component). This is my error:

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:

    /home/benedikt/code/grp-org/libs/client/data-access-auth/src/lib/components/AuthProvider.tsx:14
    import React from "react";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

    > 1 | export * from './lib/components/AuthProvider';
        | ^
      2 | export * from './lib/components/RegisterForm';
      3 | export * from './lib/components/LoginForm';
      4 |

      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1728:14)
      at Object.<anonymous> (../../libs/client/data-access-auth/src/index.ts:1:1)

It seems for some reason my Jest config does not like things being imported from React (commenting out all React related imports such as useEffect etc, 'fixes' the error).

@wootencl
Copy link

Zero idea why this worked but I ended up blowing away my nvm/node/npm installation and installing fresh and am no longer seeing the problem 🤷‍♂️.

@hcharley
Copy link

I am experiencing this as well. Testing a Next.JS App fails when importing a Lib that requires class properties transform.

@FrozenPandaz FrozenPandaz added the scope: testing tools Issues related to Cypress / Jest / Playwright / Vitest support in Nx label Jan 14, 2022
@IgorSoloydenko
Copy link

IgorSoloydenko commented Jan 22, 2022

Very similar error:

 FAIL   node-auth-functions  libs/node-auth-functions/src/functions/acquire-access-token.spec.ts
  ● 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:

    C:\code\our-company\shared-packages\node_modules\node-fetch\src\index.js:9
    import http from 'node:http';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

    > 1 | import fetch, { Response } from 'node-fetch';
        | ^
      2 | import { IAccessTokenResponse } from '.';
      3 | import { acquireAccessToken } from './acquire-access-token';
      4 |

      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1728:14)
      at Object.<anonymous> (src/functions/acquire-access-token.spec.ts:1:1)

In my case it seems to stem from the fact that a .js file from node-fetch dependency uses import syntax instead of require() when importing http from Node:

/**
 * Index.js
 *
 * a request API compatible with window.fetch
 *
 * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
 */

import http from 'node:http';
//     ^^^^
import https from 'node:https';
import zlib from 'node:zlib';
import Stream, {PassThrough, pipeline as pump} from 'node:stream';
import {Buffer} from 'node:buffer';

import dataUriToBuffer from 'data-uri-to-buffer';
//....................................................................

P.S. I had to downgrade node-fetch to ^2.6.6 to get successful tests.

@IgorSoloydenko
Copy link

Is this issue fixed in PR #8075 ?

@benediktms
Copy link

If iirc nx does not generate a bablerc for next, probably because it (v12) uses SWC as a compiler? For libraries this is not the case but actually, every thing works fine for me if I pull my page into a separate library and then just render it like I would a normal component.

@na-ji
Copy link
Author

na-ji commented Jan 26, 2022

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

@barbados-clemens
Copy link
Contributor

this might be related to #9640? can you add a preset to your root babel.config.json?

@na-ji
Copy link
Author

na-ji commented May 19, 2022

this might be related to #9640? can you add a preset to your root babel.config.json?

I upgraded the reproduction repository to NX 14.1.7 and then added a preset to the root babel.config.json. However, the issue is still here.

@airowe
Copy link

airowe commented Aug 26, 2022

Any solution here?

@barbados-clemens
Copy link
Contributor

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

@airowe
Copy link

airowe commented Aug 29, 2022

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

@na-ji
Copy link
Author

na-ji commented Aug 31, 2022

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

Hi @barbados-clemens, I updated the reproduction repository to use babel-jest instead of ts-jest, but the issue is still here. Do you have any idea of what I'm missing?

@barbados-clemens
Copy link
Contributor

barbados-clemens commented Aug 31, 2022

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?

@na-ji
Copy link
Author

na-ji commented Sep 5, 2022

different error is progress I guess?

Indeed, this is good progress, it means it might work with other packages with ESM modules.
This error is really weird, I don't really understand it.
Thank you for your help. :)

@lordvins226
Copy link

This working for me '^.+\\.[tj]sx?$': ['ts-jest', { presets: ['@nrwl/react/babel'] }]

@RNm-dove
Copy link

I faced similar problem. This is minimal reporoduction repository.
Strangely, the error is raised only in Docker container, not in Macbook terminal.

Error log.

    Details:

    /home/node/nx-story-test/apps/client/src/app/app.spec.tsx:2
    import { render } from '@testing-library/react';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

Docker setup.

$ docker-compose build aa
$ docker-compose run --rm aa sh
// in container
yarn nx test client
// raise error

@lordvins226
Copy link

lordvins226 commented Oct 3, 2022

@RNm-dove
image
image

This line fix your issue

@RNm-dove
Copy link

RNm-dove commented Oct 4, 2022

@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

@dukemai
Copy link

dukemai commented Oct 21, 2022

@RNm-dove what is difference when you use NODE_ENV=test? I am having the same problem as you on my mac but using NODE_ENV=test does not help

@JuxhinB
Copy link

JuxhinB commented Oct 31, 2022

@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

You can keep babel-jest but you also need to add

transformIgnorePatterns: ['node_modules/(?!ol)'] to you line.

My file looks like this

export default {
  displayName: 'general-map',
  preset: '../../../jest.preset.js',
  transform: {
    '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/react/babel'] }],
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
  coverageDirectory: '../../../coverage/libs/general/map',
  transformIgnorePatterns: ['node_modules/(?!ol)'],
};

replace ol with the library you have issues with or add other for ex. ol|another_lib

my NX verison "nx": "14.2.4"

@darktasevski
Copy link

Managed to go around this issue by replacing the executor in project.json with command, and setting the experimental-vm-modules flag to enable modules:

	"test": {
			"command": "NODE_OPTIONS=--experimental-vm-modules jest",
			"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
			"..."
	}

@barbados-clemens
Copy link
Contributor

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.

#8323 (comment)

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.

@github-actions
Copy link

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
If we missed this issue please reply to keep it active.
Thanks for being a part of the Nx community! 🙏

@github-actions
Copy link

github-actions bot commented Oct 1, 2023

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
blocked: third-party outdated scope: testing tools Issues related to Cypress / Jest / Playwright / Vitest support in Nx stale type: bug
Projects
None yet
Development

No branches or pull requests