Decorators and MobX (e.g. @observable)

#1

I can’t get MobX decorators (e.g. @observable) to work with Expo v25. I keep getting babel-related errors, e.g. from mobx-react. Has anyone gotten them to work with Expo v25?

I noticed that Snacks don’t seem to support them either.

I tried a dozen approaches found online, that usually involve installing Babel presets and/or modifying .babelrc. For instance, https://mobx.js.org/best/decorators.html. None of them work. I couldn’t find any Expo-specific instructions. I was however able to get them to work with regular React Native without Expo. BTW I’m on Windows 10, node v8.9.4. I’ll happily provide more information you may need.

Thanks a lot to the hero(es) who may be willing to help!

Christian

#2

BTW in case it may help, I started a Snack that demonstrate the issue:

https://snack.expo.io/@claforte/stack-navigator

It’s not complete yet but it demonstrates that @observable can’t be parsed (unexpected token).

#3

I’ve never tried MobX in Snack, but I’ve been using @observable / @observer in Expo for quite a while, including in Expo 25.

This is what my .babelrc looks like:

{
  "presets": ["babel-preset-expo"],
  "sourceMaps": "inline",
  "plugins": ["transform-react-jsx-source", "transform-decorators-legacy"],
  "env": {
    "production": {
      "plugins": ["transform-remove-console"]
    }
  }
}

And package.json devDependencies (looks like one or two of these might be redundant):

"devDependencies": {
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-remove-console": "^6.8.5",
    "babel-preset-stage-2": "^6.24.1",
    "eslint": "^4.12.0",
    "eslint-config-universe": "^1.0.6",
    "eslint-import-resolver-react-native": "^0.1.0",
    "jest-expo": "^25.1.0",
    "jsonfile": "^4.0.0",
    "prettier": "^1.9.2",
    "react-test-renderer": "16.2.0"
  },

Other potential gotcha- make sure observer is imported from mobx-react/native, e.g.,

import { observer } from 'mobx-react/native';
#4

Awesome! I’ll try it out this afternoon! :smile:

#5

@llamaluvr, can you post the rest of your package.json? I tried a simplified version of your config, but I still have problems…

I have this .babelrc:

{
  "presets": ["babel-preset-expo"],
  "plugins": ["transform-react-jsx-source", "transform-decorators-legacy"]
}

… and this is my package.json:

{
  "main": "node_modules/expo/AppEntry.js",
  "private": true,
  "scripts": {
    "test": "node ./node_modules/jest/bin/jest.js --watchAll",
    "start": "exp start --lan --dev",
    "start_no-dev": "exp start --lan --no-dev",
    "start_tunnel": "exp start --tunnel",
    "start_redirect": "exp start --redirect"
  },
  "jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "/node_modules/(?!native-base)/"
    ]
  },
  "dependencies": {
    "@expo/samples": "2.1.1",
    "@expo/vector-icons": "^6.2.2",
    "@feathersjs/authentication-client": "^1.0.2",
    "@feathersjs/feathers": "^3.1.2",
    "@feathersjs/socketio-client": "^1.1.0",
    "expo": "^25.0.0",
    "mobx": "^3.5.1",
    "mobx-react": "^4.4.1",
    "native-base": "^2.3.8",
    "react": "16.2.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-25.0.0.tar.gz",
    "react-native-gifted-chat": "^0.3.0",
    "react-navigation": "^1.0.0-beta.27",
    "socket.io-client": "^2.0.4"
  },
  "devDependencies": {
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-remove-console": "^6.8.5",
    "babel-preset-stage-2": "^6.24.1",
    "jest-expo": "^25.1.0"
  }
}

as soon as I include this import:

import {observer} from 'mobx-react/native';

I get this error message when running yarn test:

 FAIL  __tests__\App-test.js
  ● Test suite failed to run

    Couldn't find preset "es2015" relative to directory "C:\\cl\\lrn\\pera\\pera
-app\\node_modules\\mobx-react"

So I tried yarn add --dev babel-preset-es2015. That added to my devDependencies:

    "babel-plugin-transform-remove-console": "^6.8.5",
    "babel-preset-es2015": "^6.24.1",

Now, I modified .babelrc to be almost identical to yours:

{
  "presets": ["babel-preset-expo"],
  "plugins": ["transform-react-jsx-source", "transform-decorators-legacy"],
  "env": {
    "production": {
      "plugins": ["transform-remove-console"]
    }
  }
}

Now I get this error when running yarn test:

 FAIL  __tests__\App-test.js
  ● Test suite failed to run

    Couldn't find preset "stage-0" relative to directory "C:\\cl\\lrn\\pera\\per
a-app\\node_modules\\mobx-react"

I previously tried to add the “stage-0” Babel preset and that brought tons of new errors in the depths of React. Any idea?

Thanks a lot,

Christian

#6

Here’s what I’ve got:

{
  "name": "...",
  "version": "1.0.0",
  "private": true,
  "devDependencies": {
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-remove-console": "^6.8.5",
    "babel-preset-stage-2": "^6.24.1",
    "eslint": "^4.12.0",
    "eslint-config-universe": "^1.0.6",
    "eslint-import-resolver-react-native": "^0.1.0",
    "jest-expo": "^25.1.0",
    "jsonfile": "^4.0.0",
    "prettier": "^1.9.2",
    "react-test-renderer": "16.2.0"
  },
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "exp start --offline",
    "eject": "exp detach",
    "android": "exp start --android --offline",
    "ios": "exp start --ios --offline",
    "test": "node node_modules/jest/bin/jest.js --watch",
    "test-all": "node node_modules/jest/bin/jest.js",
    ...
  },
  "jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|@shoutem/theme|@shoutem/animation|@shoutem/ui|tcomb-form-native|native-base-shoutem-theme|react-navigation|@expo/react-native-action-sheet|expo|@expo/vector-icons)"
    ]
  },
  "dependencies": {
    "@expo/react-native-action-sheet": "^1.0.1",
    "@expo/vector-icons": "^6.2.2",
    "expo": "^25.0.0",
    "lodash": "^4.17.4",
    "mobx": "3.2.1",
    "mobx-react": "4.2.2",
    "moment": "^2.19.1",
    "moment-timezone": "^0.5.13",
    "numeral": "^2.0.6",
    "prop-types": "^15.6.0",
    "pusher-js": "4.2.2",
    "qs": "^6.4.0",
    "react": "16.2.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-25.0.0.tar.gz",
    "react-native-calendar-datepicker": "^1.2.2",
    "react-native-datepicker": "^1.6.0",
    "react-native-drawer": "^2.3.0",
    "react-native-flexible-thumbnail": "https://github.com/nudgeyourself/react-native-flexible-thumbnail.git",
    "react-native-gifted-chat": "0.3.0",
    "react-native-image-progress": "^1.0.1",
    "react-native-iphone-x-helper": "^1.0.1",
    "react-native-keyboard-spacer": "^0.4.0",
    "react-native-loading-spinner-overlay": "^0.5.0",
    "react-native-material-initials": "0.0.12",
    "react-native-message-bar": "^2.0.6",
    "react-native-modal": "^4.1.1",
    "react-native-modalbox": "^1.4.2",
    "react-native-search-box": "^0.0.9",
    "react-native-snap-carousel": "^3.4.0",
    "react-navigation": "1.0.0-beta.27",
    "sentry-expo": "~1.7.0",
    "underscore": "^1.8.3"
  },
  "resolutions": {
    "moment-timezone/moment": "2.19.1",
    "react-native-datepicker/moment": "2.19.1"
  }
}

Some of this stuff caches pretty aggressively, so be sure to try clearing the cache when running via exp and jest. Speaking of that, does it work in the app itself?

#7

Hi Llamaluvr, thanks so much for your help and your very fast response! I’m trying these out and will report shortly.

Christian

#8

OK, I deleted node_modules, cleared the jest cache (node ./node_modules/jest/bin/jest.js --clearCache), ran yarn install and got the following warnings:

yarn install v1.3.2
warning ..\package.json: No license field
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.1.3: The platform "win32" is incompatible with this module.
info "fsevents@1.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning "expo > react-native-maps@0.19.0" has incorrect peer dependency "react@16.0.0".
warning "expo > react-native-maps@0.19.0" has incorrect peer dependency "react-native@0.51.0".
warning "jest-expo > babel-jest@22.1.0" has unmet peer dependency "babel-core@^6.0.0 || ^7.0.0-0".
[4/4] Building fresh packages...
Done in 91.41s.

Do you know if that warning about jest-expo is something I need to fix?

I then ran exp start --clear:

[exp] Using project at C:\cl\lrn\pera\pera-app
[exp] Starting React Native packager...
[exp] Scanning folders for symlinks in C:\cl\lrn\pera\pera-app\node_modules (62ms)
[exp] Loading dependency graph.
[exp] Dependency graph loaded.
[exp] Your JavaScript transform cache is empty, rebuilding (this may take a minute).
[exp] Finished building JavaScript bundle in 175871ms.
[exp] Running application "main" with appParams: {"rootTag":21,"initialProps":{"exp":{"manifest":{"splash":{"resizeMode":"contain","image":"./assets/images/splash.png","backgroundColor":"#ffffff","imageUrl":"http://192.168.1.10:19001/assets/./assets/images/splash.png"},"privacy":"public","logUrl":"http://192.168.1.10:19000/logs","orientation":"portrait","mainModuleName":"node_modules/expo/AppEntry","platforms":["ios","android"],"id":"@claforte/pera-app","developer":{"projectRoot":"C:\\cl\\lrn\\pera\\pera-app","tool":"exp"},"iconUrl":"http://192.168.1.10:19001/assets/./assets/images/icon.png","name":"pera-app","sdkVersion":"25.0.0","xde":true,"env":{},"debuggerHost":"192.168.1.10:19001","icon":"./assets/images/icon.png","slug":"pera-app","isVerified":true,"packagerOpts":{"lanType":"ip","dev":true,"minify":false,"urlRandomness":"uf-m56","hostType":"lan"},"ios":{"supportsTablet":true},"bundleUrl":"http://192.168.1.10:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false&assetPlugin=C:\\cl\\lrn\\pera\\pera-app\\node_modules\\expo\\tools\\hashAssetFiles","version":"1.0.0","description":"A very interesting project."},"initialUri":"exp://192.168.1.10:19000","appOwnership":"expo","shell":false}}}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF

On both iPhone and Nexus 5, I don’t see any warning or error, although I’m not doing anything with MobX yet. (Just import {observer} from 'mobx-react/native';)

I tried jest again, with the same result:

 FAIL  __tests__\App-test.js
  ● Test suite failed to run
    Couldn't find preset "stage-0" relative to directory "C:\\cl\\lrn\\pera\\pera-app\\node_modules\\mobx-react"
      at node_modules/babel-core/lib/transformation/file/options/option-manager.js:293:19
      at Array.map (<anonymous>)
      at OptionManager.resolvePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
...

I’m going to look more carefully at your dependencies. I noticed you’re using older versions of MobX*… maybe mine (latest) have some regression. I’ll report soon what came out. In the meantime if you have other ideas they’ll be very welcome! Thanks so much!

Christian

#9

Hi Llamaluvr,

Good news! The jest problem goes away when I use your versions of mobx*:

    "mobx": "3.2.1",
    "mobx-react": "4.2.2",

Do you know to whom I should report the issue? I could try to pinpoint which version(s) introduced the regression but that might take a couple of hours…

Thanks a lot for your help, I really appreciate it! :slight_smile:

Christian

#10

Turns out the bug was fixed 3 hours ago: https://github.com/mobxjs/mobx-react/issues/415

I confirmed the latest versions work:

    "mobx": "3.5.1",
    "mobx-react": "4.4.2",

Llamaluvr, thanks again for your very fast assistance, and have a great day,

Christian

2 Likes
#11

Nice! I’m glad you found that- I’m sure I would have run into it at some point.

I have another repo that is using version 3.3.1 and hasn’t had issues, so it’s at least after that one.

It’s definitely something to report either on the mobx or mobx-react Github. You could try to isolate if it happens with @observer (mobx) or @observable (mobx-react). If you aren’t able to do that, since it’s likely pretty specific to React Native, mobx-react is probably the safe choice. Since it seems like maybe it’s not possible to use decorators on Snack, an producing an example repo based on the “black” exp init project that you can toggle between having the issue and not having the issue by tweaking the version numbers might get the best response.

#12

LOL, you posted about the fix just as I was posting my last response. Awesome that it’s fixed! Guess we figured somebody else in the world had to have had a problem with that. Maybe I’ll update my MobX now :-P.

#13

I have:

"mobx": "^3.4.1",
"mobx-react": "^4.3.5"

Never had any issues though.

This is correct. :slight_smile: That’s the gotcha.

closed #14

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.