DEV Community

sasurau4
sasurau4

Posted on

metro v0.48.1 needs react-native v0.53.3 when run test with jest

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.

 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

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

For more details, see my reproduce repository
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 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

...
        (_getPrototypeOf2 = (0, _getPrototypeOf2.default)(Icon)).call.apply(
...

This code correspond to static propTypes in react-native-vector-icons

Second, I transpile create-icon-set.jsby @babal\cli.
The result is here

The result is here

The different point of result is below.

...
        (_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.

From this issue, jest still use old regeneratorRuntime from regeneratro-runtime.

I think it affects the above result.

The full result of analyze is here

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!

Top comments (0)