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

Failure with ts-jest and babel #160

Open
dpovey opened this issue Nov 17, 2020 · 13 comments
Open

Failure with ts-jest and babel #160

dpovey opened this issue Nov 17, 2020 · 13 comments

Comments

@dpovey
Copy link

dpovey commented Nov 17, 2020

I am trying to use babel-plugin-macros (specifically with the twin macro and tailwind) and while it works fine when running normally it fails with jest. This is the relevant part of my jest config:

module.exports = {
  preset: 'ts-jest',
  globals: {
    'ts-jest': {
      babelConfig: {
        plugins: ['macros'],
        presets: [['@babel/preset-env'], '@babel/preset-react'],
      },
    },
  },

I have also tried setting babelConfig to my babel.config.js (plus tried babelrc and babel.config.json). All results in the following error when I run jest on an application test:

 FAIL  tests/App.test.tsx
  ● Test suite failed to run

    MacroError: The macro you imported from "undefined" is being executed outside the context of compilation with babel-plugin-macros. This indicates that you don't have the babel plugin "babel-plugin-macros" configured correctly. Please see the documentation for how to configure babel-plugin-macros properly: https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md

      82 |
      83 |   #desktop-nav & {
    > 84 |     ${tw`flex items-center px-2 py-2 text-xs leading-5 transition ease-in-out duration-150`};
         |       ^
      85 |     div {
      86 |       ${tw`mx-auto`}
      87 |     }

      at Object.macroWrapper [as default] (node_modules/babel-plugin-macros/dist/index.js:60:13)
      at Object.<anonymous> (src/chrome/AppChrome.tsx:84:7)
      at Object.<anonymous> (src/App.tsx:20:1)
      at Object.<anonymous> (tests/App.test.tsx:3:1)

I am not exactly sure what to do from here, it seems most likely that the error is with the check in babel-plugin-macros. I'm relatively sure that babel is running, or at least it chokes if I add a plugin that doesn't exist:

module.exports = {
  preset: 'ts-jest',
  globals: {
    'ts-jest': {
      babelConfig: {
        plugins: ['macros', 'no-such-plugin'],
        presets: [['@babel/preset-env'], '@babel/preset-react'],
      },
    },
  },

Fails with:

 FAIL  tests/App.test.tsx
  ● Test suite failed to run

    Cannot find module 'babel-plugin-no-such-plugin' from '/Users/dpovey/src/ppcsamurai/shogun-react'

      at Function.resolveSync [as sync] (node_modules/resolve/lib/sync.js:90:15)
      at resolveStandardizedName (node_modules/@babel/core/lib/config/files/plugins.js:101:31)
      at resolvePlugin (node_modules/@babel/core/lib/config/files/plugins.js:54:10)
      at loadPlugin (node_modules/@babel/core/lib/config/files/plugins.js:62:20)
      at createDescriptor (node_modules/@babel/core/lib/config/config-descriptors.js:154:9)
      at node_modules/@babel/core/lib/config/config-descriptors.js:109:50
          at Array.map (<anonymous>)
      at createDescriptors (node_modules/@babel/core/lib/config/config-descriptors.js:109:29)
      at createPluginDescriptors (node_modules/@babel/core/lib/config/config-descriptors.js:105:10)
      at node_modules/@babel/core/lib/config/config-descriptors.js:63:53

Any help would be greatly appreciated. It seems to be a variation on a common problem, based on googling the error.

@dpovey
Copy link
Author

dpovey commented Nov 17, 2020

The only workaround I could find was to move from ts-jest to using babel for transpiling typescript. It means I lose typechecking but I am guessing that's the only reasonable workaround for now.

@kentcdodds
Copy link
Owner

it seems most likely that the error is with the check in babel-plugin-macros

I'm confident this is not the issue. But if you can figure out what the issue is and contribute a fix that would be great. I don't have the bandwidth to work on this I'm afraid.

@conartist6
Copy link
Collaborator

Are you remembering to jest --clearCache when you make changes to jest's internal transpilation? It can be easy to pass over a configuration that does really work that way. Also you might try creating a custom transformer. Here is an example from one of my projects. Then in jest.config.js you can use your transformer:

module.exports = {
  transform: {
    '.*': '<rootDir>/path/to/transformer',
  },
};

@lucas-janon
Copy link

@dpovey I'm having the same issue, can't move to babel-jest because of our app's setup, did you find a workaround?

@conartist6
Copy link
Collaborator

If you're willing to debug through the issue with with me I could probably help you over the next few days. This sat because we never got down to a root cause.

@lucas-janon
Copy link

If you're willing to debug through the issue with with me I could probably help you over the next few days. This sat because we never got down to a root cause.

Sure, thank you!
As a workaround, I used your solution of a custom transformer and it worked, so, thanks for it.
I can write you an email (to the one you have in your profile) and we can debug it next week if you want.

My workaround:

const tsJest = require("ts-jest");

const tsJestTransformer = tsJest.createTransformer();

/**
 * @todo (lucas): this is far from ideal, it removes every tailwind/tw statement to prevent errors in jest
 * that means all our tailwind styles won't be applied in the tests
 * @see https://github.com/kentcdodds/babel-plugin-macros/issues/160
 */
module.exports = {
  ...tsJestTransformer,
  process: (src, filename, jestConfig, ...rest) => {
    const procesedSrc = src.replace(/\$\{tailwind`.*`\}/g, "").replace(/\$\{tw`.*`\}/g, "");

    return tsJestTransformer.process(procesedSrc, filename, jestConfig, ...rest);
  },
};

@conartist6
Copy link
Collaborator

Cool. Yeah I'm happy to look at it, and I think any email I've listed is fine.

@dpovey
Copy link
Author

dpovey commented Apr 2, 2021

@dpovey I'm having the same issue, can't move to babel-jest because of our app's setup, did you find a workaround?

Alas no I ended up just moving to Babel for transpilation and used the fork-ts-checker plugin for type checking with tsc.

@theladyjaye
Copy link

theladyjaye commented Aug 4, 2021

I ran into this as well. I ended up with a jest config like this to work around it:

const { defaults: tsjPreset } = require("ts-jest/presets");

module.exports = {
  "//": "... the rest of the config ...",
  transform: {
    // this one file uses a babel macro
    // it's a generated file that combines
    // typescript and the macro. So that 1 file
    // we compile with `babel-jest` and the rest we
    // compile with `ts-jest`
    "src\/mypath\/myfile\.tsx": [
      "babel-jest",
      {
        plugins: ["macros"],
        presets: ["@babel/preset-typescript"],
     },
    ],
    ...tsjPreset.transform,
  },
}

Since that one file, in my case, is a tool generated file, there is no need to worry about typescript related type checking at compile time which we lose with the babel compile:

See: https://devblogs.microsoft.com/typescript/typescript-and-babel-7/#caveats

As we mentioned above, the first thing users should be aware of is that Babel won’t perform type-checking on TypeScript code; it will only be transforming your code, and it will compile regardless of whether type errors are present.

@tareqdayya
Copy link

The problem I had was with ts-jest (tried replacing it with babel-jest and it worked fine).

All I did to get ts-jest to work was to update its config by passing useESM: true. Here's the section in question in the jest.config.js:

globals: {
    'ts-jest': {
      tsconfig: '<rootDir>/tsconfig.json',
      babelConfig: 'babel.config.js',
      useESM: true  // added this
    }
}

Notice I'm also passing the babelConfig option which is disabled by default.

Hope that helps someone.

@kopax-polyconseil
Copy link

What's the point of using ts-jest if behind you still use babel for transpiling your code ?

@mariojankovic
Copy link

I thought I'd chime in with what worked for me - instead of specifying the transform I've added this into my jest.config.js:

moduleNameMapper: {
  '\\.macro$': '<rootDir>/node_modules/babel-plugin-macros/dist/index.js',
},

@StJohn3D
Copy link

StJohn3D commented Jul 26, 2023

Thanks @mariojankovic , your workaround didn't work for me but it did inspire me to try this

moduleNameMapper: {
  '@emotion/styled/macro': '@emotion/styled'
}

This way the bundler still uses the macros but the test run doesn't.

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

No branches or pull requests

9 participants