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

babel-jest does not transpile import/export in node_modules #11753

Closed
maliyshock opened this issue Aug 15, 2021 · 14 comments
Closed

babel-jest does not transpile import/export in node_modules #11753

maliyshock opened this issue Aug 15, 2021 · 14 comments

Comments

@maliyshock
Copy link

maliyshock commented Aug 15, 2021

🐛 Bug Report

This is a copy from #6229 which is closed and not fixed still
Jest throws error "SyntaxError: Cannot use import statement outside a module" for libraries imported from node_modules.

To Reproduce

Steps to reproduce the behavior:
npm install konva
If import Konva from "konva"; exist in the file from which you are going to import function you want to test by jest it will throw this error.
If i set "transformIgnorePatterns": ["node_modules/"] - it would not help
If i set "transformIgnorePatterns": ["node_modules/(?!(konva)/)"] - it would throw another error Cannot find module 'canvas' from 'node_modules/konva/lib/index-node.js'
By the way handling those packajes by hand it is really bad idea.

If you install canvas by npm install canvas and run npm run test again it will throw

    Cannot find module '../build/Release/canvas.node'
    Require stack:
    - /Users/mad/projects/game of life/node_modules/canvas/lib/bindings.js
    - /Users/mad/projects/game of life/node_modules/canvas/lib/canvas.js
    - /Users/mad/projects/game of life/node_modules/canvas/index.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/utils.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/living/events/MouseEvent-impl.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/living/generated/MouseEvent.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/living/interfaces.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/jsdom/browser/Window.js
    - /Users/mad/projects/game of life/node_modules/jsdom/lib/api.js
    - /Users/mad/projects/game of life/node_modules/jest-environment-jsdom/build/index.js
    - /Users/mad/projects/game of life/node_modules/jest-util/build/requireOrImportModule.js
    - /Users/mad/projects/game of life/node_modules/jest-util/build/index.js
    - /Users/mad/projects/game of life/node_modules/@jest/core/build/cli/index.js
    - /Users/mad/projects/game of life/node_modules/@jest/core/build/jest.js
    - /Users/mad/projects/game of life/node_modules/jest-cli/build/cli/index.js
    - /Users/mad/projects/game of life/node_modules/jest-cli/bin/jest.js
    - /Users/mad/projects/game of life/node_modules/jest/bin/jest.js

Expected behavior

Well, you should not get any errors. Also, I think it is overhead, it is unnecessary for Jest to go and check all of the node modules libraries and their dependencies and check them. Right now it works only if you isolate each function to a separate file without any dependencies from node modules.

Link to repl or repo (highly encouraged)

https://github.com/maliyshock/game-of-life
npm install
npm run test

Non of provided solutions from #6229 do not work.

@sigveio
Copy link
Contributor

sigveio commented Aug 17, 2021

Hey @maliyshock,

Looking at your reproduction, I think you are missing an transformIgnorePatterns exception for konva to be transformed by Babel. Try something along the lines of "transformIgnorePatterns": ["node_modules/(?!(konva)/)"]

I believe this is more an issue with 3rd party modules being published untranspiled, than a bug in Jest.

@maliyshock
Copy link
Author

If i set "transformIgnorePatterns": ["node_modules/(?!(konva)/)"] - it would throw another error Cannot find module 'canvas' from 'node_modules/konva/lib/index-node.js'

@sigveio
Copy link
Contributor

sigveio commented Aug 17, 2021

@maliyshock that sounds like a separate issue, and I would refer to their docs where canvas is listed as a requirement under node environments. You might have to install it yourself. They also have a Discord Channel by the looks of it; perhaps you can find further help there?

@maliyshock
Copy link
Author

I would say it is a general and pretty common JEST issue because Jest for some reason goes and parse all of node modules dependencies, even if there is "transformIgnorePatterns": ["node_modules/(?!(konva)/)"] option.
There are lots of issues on the internet with the same problem.

I would have a possibility to say "hey, Jest work with my functions ONLY, and do not touch anything else"
Because I trust library creators by default and do not want to test their applications. It might be wrong in some cases, but in some cases, it might be not. If I find i bug, I will go to the library creators and ask them to fix it. But I do not want my testing library to go end check everything that it should not.

At least that option should be. And right now transformIgnorePatterns does not make sense for me, because Jest still goes to the node modules folder and trying to check everything. Or I just do not understand how it works.

@sigveio
Copy link
Contributor

sigveio commented Aug 18, 2021

I would say it is a general and pretty common JEST issue because Jest for some reason goes and parse all of node modules dependencies, even if there is "transformIgnorePatterns": ["node_modules/(?!(konva)/)"] option.

What this pattern says is "don't do transformations for anything inside node_modules, except for konva"

By default, Jest ignore everything inside node_modules when running transformations. Because a lot (if not most) of packages on NPM are distributed with their source code already pre-transpiled into multiple formats.

But in your case, the module konva is only distributed as ESM (ECMAScript Module) format. Which is not fully supported by Jest yet (see #9430). So adding the exception allows Babel (or whatever transformer(s) you are using) to transpile it into CommonJS.

The new error that you are getting, is related to something else (you have to install canvas yourself).

I would have a possibility to say "hey, Jest work with my functions ONLY, and do not touch anything else"
Because I trust library creators by default and do not want to test their applications.

It doesn't have to do with trusting or checking anything; Jest needs to understand the code in modules used by code you are testing - and also the relationships between them - in order to work.

If you need further help to understand this, please check out some of the following resources:

@maliyshock
Copy link
Author

Ok, so there is no way to say "jest stop checking anything from node modules"? I still do not understand why jest goes to node modules and check everything there.

Let me give an example.
I wrote the simple test.

/**
 * @jest-environment jsdom
 */
import { make2DArray } from './utils/utils'

test('array with 3 columns and 10 rows', () => {
	const array = [
		new Array(10),
		new Array(10),
		new Array(10)
	]
	expect(make2DArray(3, 10)).toEqual(array);
});

The function make2DArray does not use kanva or canvas. It is just laying down in the same file utils, where kanva is imported as well.

So in my test, where I am checking a functionality of make2DArray function that does not use any dependencies, I should not get any errors.

@sigveio
Copy link
Contributor

sigveio commented Aug 18, 2021

It doesn't matter that you are not calling a piece of code that uses these directly; in your test you are still importing from a file that imports from konva. If you want to get a deeper conceptual understanding of the Jest architecture, this video might help. And there are various other useful resources for learning and connecting with the community around Jest in the links from my previous comment. 🙂

@maliyshock
Copy link
Author

Ok, thanks. I will check it. It is just... weird. I thought I could use it immediately and it is simple. Now after a few days it seemed to me I had to make all of my functions in separate files in that case...
Anyway, thanks for the help!

@sigveio
Copy link
Contributor

sigveio commented Aug 18, 2021

I get that the learning curve can be a bit steep when you run into something like this 🙂 For many scenarios, Jest will work really well "out of the box". But it's not possible for it to support every conceivable edge case out there as 'plug-and-play' - and as with any software there will always be some limitations, bugs, or even design flaws. In the case of ESM support, for example, there are a number of considerations that's been holding it back... such as waiting until support for older Node versions is dropped so that newer APIs can be used, or for upstream projects (projects Jest depends on) to add support for certain things.

Thankfully Jest is very flexible though; a lot of problems can be solved through configuration/customisation. And if you have trouble with a particular library, like konva, then you can always consider replacing it with something else that works better. Most importantly; just keep trying/experimenting, and it will make more and more sense with time. Before you know it, you're a Jest-ninja ✌️

@maliyshock
Copy link
Author

Yeah, because konva is the only library in the project that I started to use, I thought jest would be failed on each node modules library that I gonna use in the future. If it is a pretty rare case, ok then, there is might not be any problem with other libraries.

@basickarl
Copy link

basickarl commented Sep 3, 2021

I would like to chip in and say that I have the same issue as maily. However with the module node-fetch.

I've nailed it down to babel-jest being the issue as I got it working with ts-jest.

Working configuration:

jest.config.json:

{
  "transformIgnorePatterns": ["node_modules/(?!(node-fetch)/)"],
  "transform": {
    "^.+\\.[t|j]sx?$": "ts-jest"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true
  }
}

Non-working configution:

jest.config.json:

{
  "transformIgnorePatterns": ["node_modules/(?!(node-fetch)/)"],
  "transform": {
    "^.+\\.[t|j]sx?$": "babel-jest"
  }
}

.babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}

@maxxxymum
Copy link

maxxxymum commented Sep 10, 2021

Fixed the issue for me. I have also installed the canvas package.

I would like to chip in and say that I have the same issue as maily. However with the module node-fetch.

I've nailed it down to babel-jest being the issue as I got it working with ts-jest.

Working configuration:

jest.config.json:

{
  "transformIgnorePatterns": ["node_modules/(?!(node-fetch)/)"],
  "transform": {
    "^.+\\.[t|j]sx?$": "ts-jest"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true
  }
}

Non-working configution:

jest.config.json:

{
  "transformIgnorePatterns": ["node_modules/(?!(node-fetch)/)"],
  "transform": {
    "^.+\\.[t|j]sx?$": "babel-jest"
  }
}

.babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}

@SimenB
Copy link
Member

SimenB commented Sep 13, 2021

This is going in circles.

As has been stated, Jest doesn't touch node_modules except for loading code from there. If the code is ESM and not CJS you have two options - migrate to using ESM in your code base (https://jestjs.io/docs/ecmascript-modules) or tell Jest to transform the code (i.e. tweaking transformIgnorePatterns). The fact canvas cannot be found has nothing to do with Jest but rather konva not declaring it as a dependency (https://www.runpkg.com/?konva@8.1.3/lib/index-node.js#2).

@SimenB SimenB closed this as completed Sep 13, 2021
@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 Oct 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants