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

Cannot transform the imported binding xxxxx since it's also used in a type annotation #57

Open
davisford opened this issue Oct 5, 2021 · 16 comments · May be fixed by #64
Open

Cannot transform the imported binding xxxxx since it's also used in a type annotation #57

davisford opened this issue Oct 5, 2021 · 16 comments · May be fixed by #64

Comments

@davisford
Copy link

davisford commented Oct 5, 2021

I'm getting this error when trying to execute a Jest test:

import React, { ReactElement } from 'react';
import TestRenderer, { ReactTestRenderer } from 'react-test-renderer';

    SyntaxError: /Users/dford/git/project/test/floorplan/Circle.unit.test.tsx: Cannot transform the imported binding "ReactTestRenderer" since it's also used in a type annotation. Please strip type annotations using @babel/preset-typescript or @babel/preset-flow.
      14 |
      15 | describe('Circle', () => {
    > 16 |   let component: ReactTestRenderer;
         |                  ^^^^^^^^^^^^^^^^^
      17 |   let spy: jest.SpyInstance<boolean, [Event]>;
      18 |   const transformRef = {
      19 |     nodes: jest.fn(),

I thought esbuild will strip out all type annotations, so I'm not sure what is wrong here?

Here is my jest.config.js transform:

  transform: {
    '^.+\\.(tsx?|jsx?)$': ['esbuild-jest', {target: 'es2020'} ],
    '.+\\.(css|styl|less|sass|scss)$': '<rootDir>/node_modules/jest-css-modules-transform',
  },
@davisford
Copy link
Author

This is happening here
-- called from here (i.e. related to the special handling for jest mocks)...but the test file itself has type annotations (.tsx test), which causes babel-jest to throw. If I just run the test file itself through esbuild that works fine.

@bvanjoi
Copy link

bvanjoi commented Oct 6, 2021

I have the same problem, have you solved it?

@davisford
Copy link
Author

@bvanjoi a colleague solved it by adding @babel/preset-typescript as a dependency and add this snippet to package.json:

"babel": {
    "presets": [
        "@babel/preset-typescript"
    ]
},

One other workaround we had to do to get past the error ReferenceError: React is not defined in tests was to replace the import React from 'react'; with import * as React from 'react';

Hope that helps someone....

@kevinhalliday
Copy link

thanks @davisford for coming back and posting your solution. I ran into the same issues you did (SynatxError when leaving type annotations in test files, and ReferenceError: React is not defined when using jsx in files that also include jest.mock). I'm curious, did you also only get the ReferenceError in files that included a jest.mock call? Based on the esbuild-jest source you linked to, it seems like that would make sense.

It's a bit of a bummer to have to add a babel configuration to my project when there are no explicit references to babel anywhere in my project. If not for a comment linking back to this issue, it would seem like my babel config was doing nothing.

@davisford
Copy link
Author

@khalliday7 I don't recall 100% if it occurred just on files that do jest.mock, but I suspect your assumption is correct.

@ahlec
Copy link

ahlec commented Dec 3, 2021

Locally, I found that the ReferenceError: React is not defined in TSX files was because the babel transformation would transform the import from import React from 'react' to var _react = _interopRequireDefault(require("react")), but the JSX syntax was being left intact for ESBuild to transform, and it wasn't finding the React symbol.

If you add @babel/plugin-transform-react-jsx to your package.json and then include

"plugins": [
  "@babel/transform-react-jsx"
]

in your Babel configuration, it fixed the problem for me without needing to change import styles to import * as React from 'react'.

Since only a subset of the files go through the Babel transformation and therefore only some of the files will have React renamed to _react, I don't think you'd be able to fix this by specifying the jsxFactory option on the transformation.

petebacondarwin added a commit to petebacondarwin/esbuild-jest that referenced this issue Jan 5, 2022
The `@babel/plugin-transform-modules-commonjs` transform runs before the esbuild step, which is where TS type annotations are removed.

This can cause files that contain typings to fail with errors like:

```
SyntaxError: xxx.ts: Cannot transform the imported binding "XXX" since it's also used in a type annotation. Please strip type annotations using @babel/preset-typescript or @babel/preset-flow.
```

This commit ensures that files that are transformed via this Babel plugin have their type annotations removed via the `@babel/preset-typescript` preset beforehand.

Fixes aelbore#57
@petebacondarwin
Copy link

So the simplest workaround is to run the babel-typescript transform but of course that defeats the point of this plugin which is to use esbuild to transform the typescript.

Another workaround is to do both the following:

  • avoid type annotations in files that need to be transformed. As mentioned above esbuild-jest decides whether to run this transform by checking to see if the content of the code contains the string ock(. (Look for those characters in your file.)
  • avoid the letters ock( in any file that does have type annotations

@ErikSchierboom
Copy link

I think the workarounds are not that appealing. I think the code that looks for the mock calls should probably not do a string search, which feels a bit brittle to me.

@AndrewSouthpaw
Copy link

AndrewSouthpaw commented Apr 15, 2022

I tried the workaround (install the plugin @babel/preset-typescript, add to package.json#babel.presets) didn't do the trick, though we don't otherwise have babel set up for anything so maybe that's our issue? Is there any further integration required with jest or esbuild or esbuild-jest?

For us, I can reproduce the problem with a minimal repro, which gives us a SyntaxError, even without type annotations in the test file:

// bar.ts
// =====
export type Bar = {
  a: string;
};

// foo.ts
// =====
import { Bar } from "./bar";  // <-- important to import a type

export const returnBar = (): Bar => ({ a: "foo" }); // use as annotation

// ock(  <-- just put in this bogus text to trigger the transform

// foo.test.ts
// ========
import { add } from "./foo";

// no type annotations
it("does something", () => {
  expect(add(1, 2)).toEqual(3);
});

I'm not very familiar with esbuild, I was mostly seeing if I could use it to speed up my Jest test runs, but wouldn't passing the code through a babel transform counteract any speed gains we'd find by using esbuild? Or does it still make a difference?

If it does make a difference, any ideas why the workaround isn't working on my end?

@nojvek
Copy link

nojvek commented Jul 13, 2022

I'm encoutering the same issues as well

SyntaxError: ../mongo.test.ts: Cannot transform the imported binding "MongoClient" since it's also used in a type annotation. Please strip type annotations using @babel/preset-typescript or @babel/preset-flow.

This plugin worked great in another repo but it seems it has real trouble when files use jest.Mock or jest.Mocked

Gonna try using the swc plugin to see if it does any better.

@AndrewSouthpaw
Copy link

We ended up going with swc, worked much better.

@krystofbe
Copy link

avoid the letters ock( in any file that does have type annotations

this worked for me and i had a good laugh when searching my code and finding this text fragment

    <button
      onClick={() => {
        setBlock(block);
      }}
...

my jest tests ran again after renaming setBlock to setBlck. yet, this does not give me a good feeling to use esbuild-jest in production and i'm probably going to move away from esbuild and use swc like @AndrewSouthpaw

@jmikrut
Copy link

jmikrut commented Dec 28, 2022

Any updates on this issues? We'd like to use esbuild-jest in Payload and I've followed the fixes above, which are great, but I agree that it feels weird to have to add a Babel config to our package.json when we're completely leveraging esbuild at this point.

@ziogas
Copy link

ziogas commented Jan 19, 2023

So the simplest workaround is to run the babel-typescript transform but of course that defeats the point of this plugin which is to use esbuild to transform the typescript.

Another workaround is to do both the following:

  • avoid type annotations in files that need to be transformed. As mentioned above esbuild-jest decides whether to run this transform by checking to see if the content of the code contains the string ock(. (Look for those characters in your file.)
  • avoid the letters ock( in any file that does have type annotations

Thanks, was going crazy just to realize that one of React components was named function Block()...

To repeat, you can't have ock( in your codebase. So the code like function AnythingBlock() immediately triggers the unwanted behavior.

blakeyp added a commit to govuk-one-login/ipv-core-back that referenced this issue Jan 30, 2023
esbuild-jest fails when test files have type annotations and jest.mock() calls
(see aelbore/esbuild-jest#57)
xzhayon added a commit to xzhayon/imho that referenced this issue Jul 28, 2023
Due to esbuild looking for `ock(` string, code containing something like `Clock()` requires a Babel plugin to run, which is odd.

Refs: aelbore/esbuild-jest#57
@jeremyhewett
Copy link

jeremyhewett commented Nov 30, 2023

you can't have ock( in your codebase

LOL, that is bizarre! Who wrote this thing?!

@klausbadelt
Copy link

We also had to move to swc. Using Babel to pre-transform, which seems foundational concept here, seems defeating the purpose of esbuild.

AshCorr added a commit to guardian/service-catalogue that referenced this issue May 17, 2024
Fun fact, esbuild-jest cannot compile/transform tests that have the characters `ock(` anywhere in the code!
This makes it very hard to mock anything with `jest.mock()`! See aelbore/esbuild-jest#57
AshCorr added a commit to guardian/service-catalogue that referenced this issue May 17, 2024
Fun fact, `esbuild-jest`cannot compile/transform tests that have the characters `ock(` anywhere in the code!
This makes it very hard to mock anything with `jest.mock()`! See aelbore/esbuild-jest#57
AshCorr added a commit to guardian/service-catalogue that referenced this issue May 17, 2024
Fun fact, `esbuild-jest`cannot compile/transform tests that have the characters `ock(` anywhere in the code!
This makes it very hard to mock anything with `jest.mock()`! See aelbore/esbuild-jest#57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.