react-native: Bundle failure on decorators

Environment

  React Native Environment Info:
    System:
      OS: Linux 4.15 Ubuntu 18.04 LTS (Bionic Beaver)
      CPU: x64 Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz
      Memory: 3.13 GB / 31.39 GB
      Shell: 4.4.19 - /bin/bash
    Binaries:
      Node: 8.11.1 - /usr/bin/node
      Yarn: 1.5.1 - /usr/local/bin/yarn
      npm: 6.1.0 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      Android SDK:
        Build Tools: 23.0.1, 25.0.0, 25.0.2, 26.0.0, 26.0.1, 26.0.2, 27.0.1, 27.0.3
        API Levels: 23, 24, 26, 27
    npmPackages:
      @client/react: ^1.0.13 => 1.0.62 
      @client/react-native: ^1.0.13 => 1.0.62 
      react-native: ^0.56.0-rc.4 => 0.56.0-rc.4 
    npmGlobalPackages:
      react-native-cli: 2.0.1

Description

Multi-platform app with both regular React (Webpack) and React Native builds. I upgraded RN to 0.56, which of course necessitated changes to the Babel environment, e.g. babel-plugin-transform-decorators-legacy@babel/plugin-proposal-decorators ({legacy:true}). The Webpack version builds fine. The RN version fails bundling:

error: bundling failed: TypeError: Property right of AssignmentExpression expected node to be of a type ["Expression"] but instead got null
    at Object.validate (/home/petter/owl/client2/root/node_modules/@babel/types/lib/definitions/utils.js:128:13)
    at validate (/home/petter/owl/client2/root/node_modules/@babel/types/lib/validators/validate.js:17:9)
    at builder (/home/petter/owl/client2/root/node_modules/@babel/types/lib/builders/builder.js:46:27)
    at Object.AssignmentExpression (/home/petter/owl/client2/root/node_modules/@babel/types/lib/builders/generated/index.js:233:31)
    at _core.types.sequenceExpression.identDecorators.map.decorator (/home/petter/owl/client2/root/node_modules/@babel/plugin-proposal-decorators/lib/transformer-legacy.js:47:26)
    at Array.map (<anonymous>)
    at applyEnsureOrdering (/home/petter/owl/client2/root/node_modules/@babel/plugin-proposal-decorators/lib/transformer-legacy.js:44:59)
    at PluginPass.ClassExpression (/home/petter/owl/client2/root/node_modules/@babel/plugin-proposal-decorators/lib/transformer-legacy.js:161:28)
    at newFn (/home/petter/owl/client2/root/node_modules/metro/node_modules/@babel/traverse/lib/visitors.js:237:21)
 BUNDLE  [android, dev] ./index.android.js ▓▓▓▓▓▓▓░░░░░░░░░ 45.7% (809/1197), failed.

What puzzles me is that, again, the Webpack version works, so presumably there’s nothing inherently problematic about our Babel setup, and migration to Babel 7 was successful. The only difference in Babel configuration here is babel-preset-react-native (5.0.2) versus @babel/preset-env. (The thought occurred to me that this might be due to the RN preset importing proposal-class-properties before -decorators, but modifying babel-preset-react-native/configs/main.js to include the decorator plugin does not help.)

Looking at the AST in Babel, it looks like it’s failing with both class and method decorators.

Unfortunately I do not have a demo and can’t share the (proprietary) source, but any suggestions on how to go about debugging this would be welcome.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 26
  • Comments: 42 (8 by maintainers)

Most upvoted comments

Okay, the problem is that React Native is bundling its own version of babel-helpers (exposed as a global variable named babelHelpers), which doesn’t include support for decorators.

This will be fixed when this PR lands in Metro, and when React Native upgrades to that version of Metro. (I’m guessing React Native 0.58)

https://github.com/facebook/metro/pull/198

In the meantime, you can use this workaround:

diff --git a/index.js b/index.js
index 77f0986..8d0a685 100644
--- a/index.js
+++ b/index.js
@@ -1,7 +1,13 @@
+import applyDecoratedDescriptor from '@babel/runtime/helpers/esm/applyDecoratedDescriptor'
+import initializerDefineProperty from '@babel/runtime/helpers/esm/initializerDefineProperty'
+
 import { AppRegistry } from 'react-native'
-import App from './App'
+
+Object.assign(babelHelpers, { applyDecoratedDescriptor, initializerDefineProperty })
+
+const App = require('./App').default
 
 AppRegistry.registerComponent('Ctrlpanel', () => App)

Together with npm add @babel/runtime

was exactly in the situation @haggholm mentioned,

It seems the error is caused by a dependency version missmatch between the plugins used in babel-plugin-react-native, which use the 7.0.0-beta.47 version and the local babel packages.

Be sure to check that all the babel package are actually installed with the beta.47 version:

grep -r 'version' node_modules/@babel/*/package.json|grep -v "beta.47"

The problem in our case was that some babel packages where installed using a caret range ^7.0.0-beta.47. we fixed it using the hard coded version 7.0.0-beta.47.

@flexaddicted, i got same error Unhandled JS Exception: babelHelpers.typeof is not a function. in release build and fixed it by deleting @babel/preset-env from presets in .babelrc

Here my .babelrc:

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

@Fendoro Thank you very much! Removing @babel/preset-env the app now works also in release mode.

BTW related to decorators I found this in a React-related issue I was reading earlier, I think it’s worth sharing here:

For people coming to this thread later—if you use MobX or a similar library, you don’t need decorators. They are just syntax sugar in this case. Learn more: #214 (comment), #411 (comment). Here is why we don’t include them: #411 (comment).

@SurpassRabbit You MUST use fixed version 7.0.0-beta.47 for all @babel dependencies, like this

    "@babel/core": "7.0.0-beta.47",
    "@babel/plugin-proposal-decorators": "7.0.0-beta.47",
    "@babel/plugin-transform-runtime": "7.0.0-beta.47",
    "@babel/runtime": "7.0.0-beta.47"

Using @babel/transform-runtime fix the problem with babelHelpers.applyDecoratedDescriptor is not a function.

{
  "presets": ["react-native"],
  "plugins": [
    ["@babel/proposal-decorators", {"legacy": true}],
    ["@babel/transform-runtime", {
      "polyfill": false,
      "regenerator": false
    }]
  ]
}
"devDependencies": {
...
    "@babel/plugin-proposal-decorators": "7.0.0-beta.47",
    "@babel/plugin-transform-runtime": "7.0.0-beta.47",
    "@babel/runtime": "7.0.0-beta.47"
...
  }

Thanks to @alessandro-bottamedi. But this brings another problem:

TypeError: undefined is not an object (evaluating '_getPrototypeOf2.default')

This error is located at:
    in Icon
    in RCTView
    in App
    in RCTView
    in RCTView
    in AppContainer

I have another problem with decorators with 0.56 in release build only:

function test() {}

class Test {
  @test val;
}
undefined is not a function (evaluating 'babelHelpers.applyDecoratedDescriptor(_class.prototype, "val", [test], {
    enumerable: true,
    initializer: null
  })')

P.S. “Old Version” tag should be removed.

I’m not sure my current issue on RELEASE build is related with @farwayer above comment My code uses Platform module from react-native to check OS

if (Platform.OS === 'ios') {
    this._backup()
}

It is ok on DEBUG, but throws the below exception log on RELEASE [tid:com.facebook.react.ExceptionsManagerQueue] Unhandled JS Exception: TypeError: undefined is not an object (evaluating 'e.default')

I MUST change my code to use babel optional chaining syntax and it is fine. The stranger thing now is the line this._backup() can be executed on IOS

if (Platform?.OS === 'ios') {
    this._backup()
}

@kelset , Can you investigate this case? 😦

@kelset It should be doc’ed of course but what about errors in RELEASE bundle transformation? Build should work as is without using @babel/tranform-runtime. Some babel helpers missed in RELEASE bundle (initializerDefineProperty, applyDecoratedDescriptor for example).

2018-07-10-144351_393x122_scrot

Not sure but look like it is trimming error while bundle optimization. Should we open new issue for this?

@thientnc-ibl I already have same babel config as @alessandro-bottamedi. It’s another error I got while using @babel/transform-runtime.

I’m also having this problem in RN 0.57 which uses the stable version 7.0.0 of Babel. My debug builds works, but when doing a release build it crashes on startup with:

09-14 09:48:23.097 16270 16315 E ReactNativeJS: babelHelpers.applyDecoratedDescriptor is not a function. (In 'babelHelpers.applyDecoratedDescriptor(s.prototype,"nameOfMyProperty",[t],{configurable:!0,enumerable:!0,writable:!0,initializer:null})', 'babelHelpers.applyDecoratedDescriptor' is undefined)
09-14 09:48:23.112 16270 16315 E ReactNativeJS: Module AppRegistry is not a registered callable module (calling runApplication)

This is my .babelrc:

{
  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-transform-runtime", { "helpers": true }]
  ]
}

and the relevant part of package.json:

    "@babel/plugin-proposal-decorators": "^7.0.0",
    "@babel/plugin-transform-runtime": "^7.0.0",
    "@babel/runtime": "^7.0.0",

Currently trying to figure out what’s wrong and where the fix should be applied…

After purging some old Babel plugins, pinning the versions of all @babel/-scoped packages to match the precise version pinned by babel-preset-react-native, &c., I was finally able to get past this error message and get stuck on a different error message that also seems to be related to Babel and decorators, and also happens in RN even though it works with Webpack: https://github.com/facebook/react-native/issues/20038

@kelset I’m working on a Brownfield app and I’ve just updated to 0.57.

I receive this error when doing the release (both iOS and Android):

[tid:com.facebook.react.ExceptionsManagerQueue] Unhandled JS Exception: babelHelpers.typeof is not a function. (In ‘babelHelpers.typeof(n)’, ‘babelHelpers.typeof’ is undefined)

I’ve applied the workaround by @LinusU but it does not work. The console.log is never printed.

import applyDecoratedDescriptor from '@babel/runtime/helpers/esm/applyDecoratedDescriptor'
import initializerDefineProperty from '@babel/runtime/helpers/esm/initializerDefineProperty'

console.log(applyDecoratedDescriptor);
console.log(initializerDefineProperty);

Object.assign(babelHelpers, {
  applyDecoratedDescriptor,
  initializerDefineProperty
});

require('./src/ApplicationRegistry');

ApplicationRegistry is the file where I register the components exposed to the native world.

Here my package.json.

"dependencies": {
    "@babel/polyfill": "^7.0.0",
    "@babel/runtime": "7.0.0",
    "ent": "^2.2.0",
    "jssha": "^2.3.1",
    "lodash": "^4.17.10",
    "moment": "^2.19.4",
    "moment-timezone": "^0.5.17",
    "react": "^16.5.2",
    "react-native": "^0.57",
    "react-native-elements": "^0.19.1",
    "react-native-fast-image": "^4.0.14",
    "react-native-htmlview": "^0.13.0",
    "react-native-hyperlink": "0.0.11",
    "react-native-remote-svg": "^1.2.0",
    "react-native-scrollable-tab-view": "^0.8.0",
    "react-native-svg": "^6.3.1",
    "react-native-vector-icons": "^5.0.0",
    "react-redux": "^5.0.7",
    "redux": "^4.0.0",
    "redux-saga": "^0.16.0",
    "reselect": "^3.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "babel-core": "7.0.0-bridge.0",
    "babel-plugin-transform-inline-environment-variables": "^0.4.3",
    "concurrently": "^2.2.0",
    "jest": "^23.6.0",
    "metro-react-native-babel-preset": "^0.45.2",
    "msvgc": "^0.1.1",
    "prettier": "1.9.2",
    "react-dom": "^16.3.0-alpha.1",
    "react-native-storybook-loader": "^1.6.0"
  }

Here my .babelrc:

{
  "presets": ["@babel/preset-env", "module:metro-react-native-babel-preset"],
  "plugins": [
    ["transform-inline-environment-variables"]
  ]
}

Any idea?

Created new issue with 2 workarounds for babel helpers bug https://github.com/facebook/react-native/issues/20150

Same problem here after upgrading to RN 0.56.

The app works in DEBUG with this configuration:

package.json

...
"devDependencies": {
    "@babel/core": "7.0.0-beta.47",
    "@babel/plugin-proposal-decorators": "7.0.0-beta.47"
    ...
}

.babelrc

{
  "presets": [
    ["react-native"]
  ],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
  ]
}

But in RELEASE xCode crash with this error:

babelHelpers.applyDecoratedDescriptor is not a function.