Skip to content

Setting loose: false on @babel/plugin-proposal-class-properties breaks fast refresh on React Native #3102

@mrVito

Description

@mrVito

I'm using React Native 0.65.1 with TypeScript and Decorators for mobx and was following the official guide for enabling decorators.

The guide states that the Babel plugin @babel/plugin-proposal-class-properties must be installed and enabled in babel.config.js like so:

['@babel/plugin-proposal-class-properties', {loose: false}],
// In contrast to MobX 4/5, "loose" must be false!    ^

But doing that breaks the fast refresh on React Native.

Intended outcome:

React Native fast refresh should work as intended.

Actual outcome:

React Native fast refresh does not work at all.
Interesting part here is that setting loose: true on @babel/plugin-proposal-class-properties fixes the fast refresh and most importantly mobx still works just fine. Furthermore removing the @babel/plugin-proposal-class-properties entirely has the same effect - fast refresh works fine and mobx works just fine as well.

My tsconfig.json file looks like this:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "commonjs",
    "lib": ["ESNext"],
    "allowJs": true,
    "jsx": "react-native",
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "skipLibCheck": false,
    "resolveJsonModule": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "useDefineForClassFields": true
  },
  "exclude": [
    "node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
  ]
}

How to reproduce the issue:

  • Create new React Native project via React Native CLI with typescript template: npx react-native init AwesomeTSProject --template react-native-template-typescript;
  • Install mobx and mobx-react;
  • Set "experimentalDecorators": true, and "useDefineForClassFields": true in tsconfig.json file;
  • Add plugins to babel.config.js:
  plugins: [
    ['@babel/plugin-proposal-decorators', {legacy: true}],
    ['@babel/plugin-proposal-class-properties', {loose: false}],
  ],
  • Launch the app in emulator;
  • Touch some ts/tsx files on the project and confirm that fast refresh does not work.

Versions

mobx: 6.3.3
mobx-react: 7.2.0
react: 17.0.2
react-native: 0.65.1
typescript: 3.8.3

Additional notes
I'm confused why mobx decorator documentation requires @babel/plugin-proposal-class-properties to have loose set to false but setting loose to true or entirely removing @babel/plugin-proposal-class-properties doesn't break mobx. Am I missing something here? If loose: false is truly required maybe I have not encountered something that setting it to true breaks?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions