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

Couldn't find preset "module:metro-react-native-babel-preset" when running jest #242

Open
michaelknoch opened this Issue Sep 12, 2018 · 41 comments

Comments

Projects
None yet
@michaelknoch
Copy link

michaelknoch commented Sep 12, 2018

Do you want to request a feature or report a bug?
bugreport

What is the current behavior?
I updated a react-native codebase from 0.56 to 0.57 and migrated from "babel-preset-react-native": "^2.1.0" to the current version of "metro-react-native-babel-preset". The app itself compiles and runs for iOS and android but all of the jest tests crash immediately on my mac and on our linux ci.

Test suite failed to run
Couldn't find preset "module:metro-react-native-babel-preset" relative to directory "/Users/michaelknoch/dev/repos/JestCrashReproduction"

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

I created this repo with react-native init. To run Jest we need at leat one file with pattern *.test.js
So i ended up running this: react-native init JestMetroCrash --version 0.57.0 && cd JestMetroCrash && touch App.test.js

Its worth to mention that the test suite also breaks when .babelrc with explicit "presets": ["module:metro-react-native-babel-preset"] is provided.

What is the expected behavior?
Jest should resolve the preset and transpile files correctly.

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.
node v8.11.3
npm 6.4.1
metro latest release

@ajcrites

This comment has been minimized.

Copy link

ajcrites commented Sep 13, 2018

For your jest configuration, can you also add transform: { '^.+\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js' }?

@rafeca

This comment has been minimized.

Copy link
Member

rafeca commented Sep 13, 2018

@mjesun do you know why jest is not able to pick up the preset?

@fmaso04

This comment has been minimized.

Copy link

fmaso04 commented Sep 14, 2018

I have found the same problem today.
Open the file .babelrc, you will find it in the root of the project, and replace:

{ "presets": ["module:metro-react-native-babel-preset"] }

to

{ "presets": ["react-native"] }

@rajapanidepu

This comment has been minimized.

Copy link

rajapanidepu commented Sep 16, 2018

Replacing with { "presets": ["react-native"] } can't be the solution for the existing set of tests, as it breaks loading babel-jest and fails to mock of files that test import using ES6.

@vitalets

This comment has been minimized.

Copy link

vitalets commented Sep 17, 2018

I confirm that @ajcrites's solution works, event with TypeScript.
My jest config in package.json is following:

    ...
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
      "\\.(ts|tsx)$": "ts-jest"
    },
   ...
@michaelknoch

This comment has been minimized.

Copy link

michaelknoch commented Sep 17, 2018

the solution from @ajcrites seems to work, but now everything mocked with jest.mock seems to break for some reasons. Is there any known breaking change related to that?

@hkung77

This comment has been minimized.

Copy link

hkung77 commented Sep 18, 2018

@ajcrites I tried your solution it works great locally but for some reason my CI is throwing this error.

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
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/en/configuration.html

Details:

/node_modules/react-native/jest/preprocessor.js:45
...nodeOptions,
^^^

SyntaxError: Unexpected token ...

at ScriptTransformer._getTransformer (node_modules/jest-runtime/build/script_transformer.js:231:19)
@thomashagstrom

This comment has been minimized.

Copy link

thomashagstrom commented Sep 18, 2018

Now we're using TypeScript, if that matters. The above configuration, as suggested, does work. But also yields warning:

ts-jest][DEPRECATED] - replace any occurrences of "ts-jest/dist/preprocessor.js" or "/node_modules/ts-jest/preprocessor.js" in the 'transform' section of you
r Jest config with just "ts-jest".

However, just using ts-jest has the error come back.

 "transform": {
      "\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js",
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    },
@ajcrites

This comment has been minimized.

Copy link

ajcrites commented Sep 18, 2018

Yes, you can just do "\\.(ts|tsx)$": "ts-jest",

@hanford

This comment has been minimized.

Copy link

hanford commented Sep 20, 2018

I'm running into the same issue as @michaelknoch

@dylmye

This comment has been minimized.

Copy link

dylmye commented Sep 22, 2018

Edit: scratch that, just found you have to put the transform inside the jest config, lol. Maybe the full message is useful to somebody though.

Getting the same issue as OP, even with the transform. Here's the full error as I can't see it above:

Couldn't find preset "module:metro-react-native-babel-preset" relative to directory "Q:\\Path\\to\\REPO-NAME"

      at node_modules/babel-core/lib/transformation/file/options/option-manager.js:293:19
          at Array.map (<anonymous>)
      at OptionManager.resolvePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
      at OptionManager.mergePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:264:10)
      at OptionManager.mergeOptions (node_modules/babel-core/lib/transformation/file/options/option-manager.js:249:14)
      at OptionManager.init (node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
      at File.initOptions (node_modules/babel-core/lib/transformation/file/index.js:212:65)
      at new File (node_modules/babel-core/lib/transformation/file/index.js:135:24)
      at Pipeline.transform (node_modules/babel-core/lib/transformation/pipeline.js:46:16)
@Nigh7Sh4de

This comment has been minimized.

Copy link

Nigh7Sh4de commented Sep 27, 2018

@michaelknoch I had to install babel-jest as per https://jestjs.io/docs/en/getting-started#using-babel. I also had to rename my .babelrc to babel.config.js (and add module.exports = to the top since the json file is now a regular js file). Here is my final list of babel depencies:

"@babel/core": "^7.1.0",
"@babel/runtime": "^7.0.0",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^23.6.0",
@jonathonlui

This comment has been minimized.

Copy link

jonathonlui commented Sep 27, 2018

Looks like version 0.47 of metro-react-native-babel-preset is available now. Testing now works for me with this new version including jest.mock.

@hanford

This comment has been minimized.

Copy link

hanford commented Sep 28, 2018

I finally resolved the issue I was having by bringing in https://www.npmjs.com/package/babel-plugin-jest-hoist to my project.

My dependencies:

    "react": "16.5.1",
    "react-native": "^0.57.1",
.. 
    "@babel/core": "^7.1.0",
    "@babel/runtime": "^7.0.0",
    "babel-core": "^6.26.3",
    "babel-eslint": "^8.1.1",
    "babel-jest": "^23.6.0",
    "babel-plugin-jest-hoist": "^23.2.0",
    "babel-plugin-relay": "^1.5.0",
    "jest": "^23.6.0",
    "metro-react-native-babel-preset": "^0.47.0",

and my babel.config.js:

module.exports = {
  "presets": ["module:metro-react-native-babel-preset", "module:react-native-dotenv"],
  "plugins": [
    "relay",
    "jest-hoist"
  ]
}

EDIT: my tests are now passing locally but failing on CI 🙇‍♂️

@michaelknoch

This comment has been minimized.

Copy link

michaelknoch commented Sep 28, 2018

still running into Couldn't find preset "module:metro-react-native-babel-preset" with 0.47.0

@luissmg

This comment has been minimized.

Copy link

luissmg commented Oct 3, 2018

Hey @michaelknoch. I have the following versions:

"react": "16.5.1",
"react-native": "^0.57.1",
...
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"babel-core": "^7.0.0-bridge.0",
"jest": "^23.6.0",
"metro-react-native-babel-preset": "^0.45.0",

And it works just fine. Just had to change my .babelrc to babelrc.js and install babel-core (npm i -D babel-core@bridge).

@hernancorigliano

This comment has been minimized.

Copy link

hernancorigliano commented Oct 4, 2018

I had the same issue and adding this to jest config made test work
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
But then my jest.mock() statements were not working. It seems all the jest.mock() calls need to be hoisted before all import statements in the test.

@luissmg

This comment has been minimized.

Copy link

luissmg commented Oct 4, 2018

@hernancorigliano try what I said above

@hanford

This comment has been minimized.

Copy link

hanford commented Oct 4, 2018

I've also been following this issue trying to track the jest.mock breakage

facebook/react-native#20876 (comment)

@michaelknoch

This comment has been minimized.

Copy link

michaelknoch commented Oct 4, 2018

I fixed most of my tests by moving mocks to __MOCKS__ directory instead of mocking dynamically in the test itself. @hanford

@hernancorigliano

This comment has been minimized.

Copy link

hernancorigliano commented Oct 5, 2018

@hernancorigliano try what I said above

Sorry I forgot to mention that I tried using the plugin to hoist the calls, but for some reason does not seem to be working. I did exactly the same as you. I might have a problem with babel somewhere else.

@denieler

This comment has been minimized.

Copy link

denieler commented Oct 6, 2018

looks like I've set

"jest": {
    "preset": "react-native",

and it works, even if I have installed only metro-react-native-babel-preset and react-native: 0.57.1. Not sure why...

@xe4me

This comment has been minimized.

Copy link

xe4me commented Oct 7, 2018

inside my react-native-vector-icons folder, in node_modules, there was a bablerc file which was like this

{
  "presets": ["module:metro-react-native-babel-preset"]
}

I manually changed it to this :

{
  "presets": ["react-native"]
}

@msaifa

This comment has been minimized.

Copy link

msaifa commented Oct 7, 2018

I hope this can help

  1. Go to new module folder (ex: node_module/react-native-vector-icons)
  2. Open .babelrc
  3. replace "presets": ["module:metro-react-native-babel-preset"]
  4. with "presets": ["react-native"]
  5. and rebuild project

trims

@microsockss

This comment has been minimized.

Copy link

microsockss commented Oct 11, 2018

And it works just fine. Just had to change my .babelrc to babelrc.js and install babel-core (npm i -D babel-core@bridge).

Can confirm this works for me!

addianto added a commit to addianto/konfui that referenced this issue Oct 13, 2018

Resolve babel-preset error when executing test
This commit uses a hack solution for resolving an error related to
babel-preset when executing test. The solution is based on a comment
found in the following GitHub issue on metro bundler:

facebook/metro#242

To be more precise, it follows the solution found in the comment:

facebook/metro#242 (comment)
@wironomy

This comment has been minimized.

Copy link

wironomy commented Oct 13, 2018

Hey @michaelknoch. I have the following versions:

"react": "16.5.1",
"react-native": "^0.57.1",
...
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"babel-core": "^7.0.0-bridge.0",
"jest": "^23.6.0",
"metro-react-native-babel-preset": "^0.45.0",

And it works just fine. Just had to change my .babelrc to babelrc.js and install babel-core (npm i -D babel-core@bridge).

It works for me. I didn't change my '.babelrc' though. Just installed the 'babel-core'

@esbenp

This comment has been minimized.

Copy link

esbenp commented Oct 19, 2018

After I added the custom transform mocks stopped working as well. These are the steps I completed to fix it.

  1. I added 'babel-core@^7.0.0-bridge'
  2. removed the custom transform (transform: { '^.+\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js' })
  3. changed from .babelrc to babel.config.js

babel.config.js

module.exports = function (api) {
  api.cache(true)
  return {
    "presets": ["module:metro-react-native-babel-preset"]
  };
}

now my tests are running and mocks are working as usual :-) hope it can help somebody

@ospfranco

This comment has been minimized.

Copy link

ospfranco commented Oct 19, 2018

After spending a couple of hours trying to make everything work, I noticed there is some official documentation for ts-jest to run on react-native 0.57 and babel 7:

https://kulshekhar.github.io/ts-jest/user/react-native/

Solved my problem

@makabde

This comment has been minimized.

Copy link

makabde commented Oct 20, 2018

After I added the custom transform mocks stopped working as well. These are the steps I completed to fix it.

1. I added `'babel-core@^7.0.0-bridge'`

2. **removed** the custom transform (`transform: { '^.+\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js' }`)

3. changed from `.babelrc` to `babel.config.js`

babel.config.js

module.exports = function (api) {
  api.cache(true)
  return {
    "presets": ["module:metro-react-native-babel-preset"]
  };
}

now my tests are running and mocks are working as usual :-) hope it can help somebody

This solution worked for me but I also had to bring @babel/plugin-proposal-class-properties to my devDependencies
https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-class-properties

@hieunc229

This comment has been minimized.

Copy link

hieunc229 commented Oct 24, 2018

@makabde It worked for me too, without adding @babel/plugin-proposal-class-properties

@ferdicus

This comment has been minimized.

Copy link

ferdicus commented Oct 31, 2018

one thing I noticed and was taken aback by was, that jest is caching tests.
So if you think "why aren't my babel config changes doing anything", chances are, that jest is running the tests out of it's cache without considering the config changes.

Make sure to run jest --clearCache when trying to test config changes.

@igorrfc

This comment has been minimized.

Copy link

igorrfc commented Nov 9, 2018

@esbenp's suggestion worked for me. Thanks, man !

@ramanandapanda

This comment has been minimized.

Copy link

ramanandapanda commented Nov 13, 2018

I was facing the same issue and while implementing detox e2e test.
fixed it by adding the following code in the e2e/config.json

"transform": {
"^.+\\.js$": "<rootDir>/../node_modules/react-native/jest/preprocessor.js"
}

under the main {}.
my final config.json file looks like this:

{
    "setupTestFrameworkScriptFile": "./init.js",
    "testEnvironment": "node",
    "transform": {
        "^.+\\.js$": "<rootDir>/../node_modules/react-native/jest/preprocessor.js"
      }
}
@henrique1977

This comment has been minimized.

Copy link

henrique1977 commented Nov 20, 2018

@esbenp's suggestion worked for me as well.

@esbenp, you rock!!

Thank you!

@btravel

This comment has been minimized.

Copy link

btravel commented Nov 20, 2018

@esbenp solution works for me, except of missed transform:
transform: { '^.+\\.(js|jsx)$': '<rootDir>/node_modules/react-native/jest/preprocessor.js', },

I've returned it to be able to use ES6 syntax in my test files.

blefebvre added a commit to blefebvre/react-native-sqlite-demo that referenced this issue Nov 22, 2018

yurykabanov added a commit to yurykabanov/helloworld-rn that referenced this issue Nov 26, 2018

@haswalt

This comment has been minimized.

Copy link

haswalt commented Dec 4, 2018

Can confirm @esbenp solution works, in fact the only one here that works. Thanks!

@isaiahgrey93 isaiahgrey93 referenced this issue Dec 6, 2018

Merged

Upgrade to Storybook 4 and React-Native 0.57 #11

0 of 1 task complete
@GetSource1234

This comment has been minimized.

Copy link

GetSource1234 commented Dec 10, 2018

@esbenp solution works for me. I am wondering why it doesn't work out of the box....

@itinance

This comment has been minimized.

Copy link

itinance commented Dec 11, 2018

This issue occur even on a newly fresh installed version of an react-native application:

cd /tmp
react-native init test
cd test
react-native-git-upgrade

gives

git-upgrade ERR! An error occurred during upgrade:
git-upgrade ERR! Error: Couldn't find preset "module:metro-react-native-babel-preset" relative to directory "/private/tmp/test"
at /usr/local/lib/node_modules/react-native-git-upgrade/node_modules/babel-core/lib/transformation/file/options/option-manager.js:293:19
at Array.map ()

@satishkumarganga

This comment has been minimized.

Copy link

satishkumarganga commented Dec 14, 2018

Getting same issue
Error: Couldn't find preset "module:metro-react-native-babel-preset" relative to directory
and also tried
For your jest configuration, can you also add transform: { '^.+\.js$': '/node_modules/react-native/jest/preprocessor.js' }?

But, still its not working

@debugpai

This comment has been minimized.

Copy link

debugpai commented Jan 11, 2019

I was getting this error when running tests with detox
@esbenp s solution worked for me to remove the error with not finding metro bundler. However I started getting the error
ReferenceError: regeneratorRuntime is not defined.

On removing the line disableBabelRuntime: true from react-native/jest/preprocessor.js this error goes away. This change was introduced by this commit

To fix it temporarily, I copied react-native/jest/preprocessor.js to <project_root>/jest-preprocessor.js and removing disableBabelRuntime: true and directing the path to transform to this file.

@liangguohun

This comment has been minimized.

Copy link

liangguohun commented Jan 11, 2019

so i choose to use the old version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment