metro v0.48.1 needs react-native v0.53.3 when run test with jest
Tags: reactnative, babel, javascript
Published: 2018-10-28 06:55:39

---
title: metro v0.48.1 needs react-native v0.53.3 when run test with jest
published: true
description: Upgrade metro
tags: react-native, babel, javascript
---

## TL;DR

If you met a problem that test fail unexpectedly after upgrading metro-react-native-babel-preset v 0.48.1, you try to upgrade react-native v0.57.3.

##Jest failed situation

One day, I upgraded many libraries. After upgrade, I ran `yarn test` and saw jest failed with below error message.

```bash
 TypeError: Cannot read property 'default' of undefined
      at new Icon (node_modules/react-native-vector-icons/lib/create-icon-set.js:42:389)
      ...
```

On my environment.

```
OS: Ubuntu 18.04
node: v11.0.0
react-native: v0.57.2
react-native-elements: v0.19.1
metro-react-native-babel-preset: v0.48.1
react-native-vector-icons: v6.0.2
@babel/runtime: v7.1.2
```

my package.json

```javascript
...
"jest": {
    "preset": "react-native",
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    }
...
```
For more details, see my [reproduce repository](https://github.com/sasurau4/jestBabelTransform/tree/jest-reproduce)
Umm, why jest test failed?

## The reason why jest failed

It is because that metro changed the default config of using @babel/runtime or not when jest.
This config affects babel use plugin-tranform-runtime or not.

metro-react-native-babel-preset at v0.48.1 use plugin-transform-runtime by default.
https://github.com/facebook/metro/pull/285/files#diff-691dcb134bb2a1276f7a1fea8728f634L150

But preprocessor.js at v0.57.2 has only disableBabelRuntime option.
https://github.com/facebook/react-native/blob/v0.57.2/jest/preprocessor.js#L55

So, our javascript code are transpiled by babel with plugin-transform-runtime.

Upgrade react-native to v0.57.3 solve the problem.

## Detailed question: why jest fails with @babel/runtime?

I didn't understand the difference with @babel/runtime or not.
I read https://babeljs.io/docs/en/babel-runtime.

It's sense for me. But still remain unknown point.
My situation has `@babel/runtime` in dependencies, why the property 'default' of undefined?

So, I investigated transpiled codes by modifying preprocessor's code.

Jest failed at `create-icon-set.js` in `react-native-vector-icons package`.

First, I change the file of preprocessor.js to intercept generated code and write it to file.
[Here](https://github.com/sasurau4/jestBabelTransform/tree/analyze-babel-and-jest-collaboration/intercepted) is generated codes.
Babel generated code is minified and not human-readble, so the repo codes are formatted by prettier.

The deference of two files is same as babel's document explained.

I matched generated code and error massage from jest.
The problem is at [line 82 in babeled-by-jest-with-runtime.js](https://github.com/sasurau4/jestBabelTransform/blob/analyze-babel-and-jest-collaboration/intercepted/babeled-by-jest-with-runtime.js#L82)
```javascript
...
        (_getPrototypeOf2 = (0, _getPrototypeOf2.default)(Icon)).call.apply(
...
```

This code correspond to [static propTypes in react-native-vector-icons](https://github.com/oblador/react-native-vector-icons/blob/master/lib/create-icon-set.js#L43)

Second, I transpile `create-icon-set.js`by `@babal\cli`.
The result is [here](https://github.com/sasurau4/jestBabelTransform/blob/analyze-babel-and-jest-collaboration/babeled/create-icon-set-enabled-runtime.js)

The result is [here](https://github.com/sasurau4/jestBabelTransform/blob/analyze-babel-and-jest-collaboration/babeled/create-icon-set-enabled-runtime.js)

The different point of result is below.
```javascript
...
        (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(Icon)).call.apply(
...
```

babel by jest code is `_getPrototypeOf2.default`, babel by cli is `_getPrototypeOf3.default`.
This difference may cause of jest fail.

I'm not convinced because I don't fully understand about jest and babel.

Also, metro use babel runtime from [this commit](https://github.com/facebook/metro/commit/8932a9caa8f9ffe82160f2da25342a0bde3bbb26).

[From this issue](https://github.com/facebook/react-native/pull/21283), jest still use old regeneratorRuntime from [regeneratro-runtime](https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime).

I think it affects the above result.

The full result of analyze is [here](https://github.com/sasurau4/jestBabelTransform/tree/analyze-babel-and-jest-collaboration)

I'll happy that this article help you when you show jest fail.
If you found the cause of the proble or my misunderstood, tell me about it!
Thanks for your reading!