question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[0.56][RELEASE] Bundler cuts off some used babel helpers in release build (decorators issue)

See original GitHub issue

Environment

  React Native Environment Info:
    System:
      OS: Linux 4.17 Arch Linux rolling
      CPU: x64 Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz
      Memory: 1.06 GB / 7.47 GB
      Shell: 5.5.1 - /bin/zsh
    Binaries:
      Node: 10.6.0 - /usr/bin/node
      Yarn: 1.7.0 - /usr/bin/yarn
      npm: 6.1.0 - /usr/bin/npm
      Watchman: 4.9.0 - /usr/bin/watchman
    SDKs:
      Android SDK:
        Build Tools: 23.0.1, 23.0.3, 25.0.2, 26.0.1, 26.0.2, 27.0.0, 27.0.3
        API Levels: 22, 23, 24, 25, 26, 27
    npmPackages:
      react: ^16.4.1 => 16.4.1 
      react-native: ^0.56.0 => 0.56.0 
    npmGlobalPackages:
      react-native-cli: 2.0.1
      react-native-git-upgrade: 0.2.7

Description

Bundler cuts off some used babel helpers in release build. Look like by mistake while optimization. For example initializerDefineProperty and applyDecoratedDescriptor needed by @babel/proposal-decorators.

2018-07-10-144351_393x122_scrot

Reproducible Demo

{
  "presets": ["react-native"],
  "plugins": [
    ["@babel/proposal-decorators", {"legacy": true}]
  ]
}
"devDependencies": {
  "@babel/plugin-proposal-decorators": "7.0.0-beta.47"
}
function test() {}

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

Workaround 1 (can have side effects)

Be care because this workaround can bring some errors with external libs.

For RN 0.56:

yarn add --dev @babel/plugin-transform-runtime@7.0.0-beta.47

.babelrc

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

For RN 0.57:

yarn add --dev @babel/plugin-transform-runtime@7.0.0

.babelrc

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

Workaround 2

Move app initialization to some other file (I’m using src/ dir for source) and update root index.js file. N.B. require main app code instead of import because require executed after.

For RN 0.56:

yarn add @babel/runtime@7.0.0-beta.47

Root index.js

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

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

require('./src');

For RN 0.57:

yarn add @babel/runtime@7.0.0

Root index.js

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

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

require('./src');

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:76
  • Comments:45 (6 by maintainers)

github_iconTop GitHub Comments

40reactions
lxcidcommented, Sep 1, 2018

In metro-react-native-babel-preset, it is stated that @babel/plugin-transform-flow-strip-types need to be before @babel/plugin-proposal-class-properties.

the flow strip types plugin must go BEFORE class properties! there’ll be a test case that fails if you don’t.

https://github.com/facebook/metro/blob/579b12974d13c7f02b2c58540ce8fddcb6a3e423/packages/metro-react-native-babel-preset/src/configs/main.js#L19-L21

This kinda explain why flow is affecting the babel output as describe around the issue…

If you provide your own plugins, it get applied first before presets, as described in Plugin Ordering section at https://babeljs.io/docs/en/plugins/#plugin-ordering

So, if you need decorators, you will have to place @babel/plugin-proposal-decorators above @babel/plugin-proposal-class-properties in plugins, which get executed first, thus not applying the @babel/plugin-transform-flow-strip-types, See https://babeljs.io/docs/en/next/babel-plugin-proposal-decorators.html

The fix for me is to add @babel/plugin-transform-flow-strip-types before the 2 other plugins…

{
  "plugins": [
    [
      "@babel/plugin-transform-flow-strip-types"
    ],
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ],
    [
      "@babel/plugin-proposal-class-properties",
      {
        "loose": true
      }
    ]
  ],
}
27reactions
hvaoccommented, Jul 19, 2018

Faced the same error with React Native 0.56, used combination of resolutions proposed including the Workaround 2 by @farwayer above.

Steps that I followed:

  1. Clean up dependencies
rm -rf node_modules
yarn
yarn upgrade react-native@0.56.0
  1. @farwayer suggested workaround 2

Check the version of babel components used with React Native by checking the yarn.lock or package-lock.json and match @babel/runtime with the same version. React native 0.56 is using babel 7.0.0-beta.47.

yarn add @babel/runtime@7.0.0-beta.47

index.js

import {AppRegistry} from 'react-native'


// RN 0.56 Release version crashes
// import App from './src/App'
// AppRegistry.registerComponent('MyApp', () => App)

// Workaround: RN 0.56 Release version crashes
// Sources:
//      https://github.com/facebook/react-native/issues/19827
//      https://github.com/facebook/react-native/issues/20150

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

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

// Your main app code is in /src/index.js
AppRegistry.registerComponent('MyApp', () => require('./src').default)

Tested iOS / Android - Debug and Release version on Simulators and Devices. - All of them are working fine.

Note: I am also using decorators for MobX and custom .babelrc

package.json

{
  "name": "MyApp",
  "version": "0.0.1",
  "dependencies": {
    "@babel/plugin-proposal-decorators": "7.0.0-beta.47",
    "@babel/runtime": "7.0.0-beta.47",
    "mobx": "^5.0.3",
    "mobx-react": "^5.2.3",
    "react": "16.4.1",
    "react-native": "0.56.0"
  },
  "devDependencies": {
    "babel-jest": "23.4.0",
    "babel-preset-react-native": "^5",
    "flow-bin": "^0.76.0",
    "jest": "^23.4.1",
    "jsc-android": "^224109.0.0",
    "react-native-cli": "^2.0.1",
    "react-test-renderer": "16.4.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

.babelrc

{
  "presets": [
    "react-native"
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ]
  ]
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found