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

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

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 51
  • Comments: 46 (2 by maintainers)

Commits related to this issue

Most upvoted comments

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"] }

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

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"
    },
   ...

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

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"]
}

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

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

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.

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).

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?

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"
      }
}

@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",

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

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

I’m running into the same issue as @michaelknoch

This file is no longer available since 0.70

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"
      }
}

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’

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.

@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)

Just echoing other solutions above… depending on your use case, use only one: .babelrc or babel.config.js (as per documentation)

For me, I was in the process of migrating my code and had both files present by accident, so the bundler was confused. I removed .babelrc and kept babel.config.js and the error went away.

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

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 🙇‍♂️

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.