Updating ReactNativeExpo.js v1 to v2

boadude

Miguel Meza

Posted on April 20, 2020

Updating ReactNativeExpo.js v1 to v2

Sadly, version 1 of the ReactNativeExpo.js has gone to the end because of continuous breaking changes of Expo and React Native, but don't be alarm yet, this is not a bad thing, is just version 1 is no more supported.

Never the less, we are making some changes to the project to fulfill all the need for the continuous function of the project, let's call it version 2 now.

Note aside; this guide is for migrating from version 1 to version 2. If you want to start from fresh from version 2, follow the instruction on the repository.

If you are still here, let's continue:

Version 1 to version 2

I split the migration into three parts; files that need delete, create, and must make some changes. Let's go:

Files to Delete

  • package-lock.json
  • .babelrc
  • docs
  • src/assets/native-base-theme:

Because of the update of Native-Base, for working correctly, we must delete de folder src/assets/native-base-theme and copy the new one.

    rm -rf ./src/assets/native-base-theme
    node node_modules/native-base/ejectTheme.js
    mv ./native-base-theme ./src/assets/native-base-theme
Enter fullscreen mode Exit fullscreen mode

File to Create

  • index.js
    import { registerRootComponent } from 'expo';

    import App from './App';

    // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
    // It also ensures that whether you load the app in the Expo client or in a native build,
    // the environment is set up appropriately
    registerRootComponent(App);
Enter fullscreen mode Exit fullscreen mode
  • .buckconfig
    [android]
      target = Google Inc.:Google APIs:23

    [maven_repositories]
      central = https://repo1.maven.org/maven2
Enter fullscreen mode Exit fullscreen mode
  • babel.config.json

Handle the responsibility that one day has .babelrc

    module.exports = function (api) {
      api.cache(true);
      return {
        presets: ['babel-preset-expo'],
        plugins: [
          [
            'module-resolver',
            {
              root: ['./'],
              alias: {
                '@app': './src/app',
                '@assets': './src/assets',
                '@common': './src/common',
                '@components': './src/components',
                '@constants': './src/constants',
              },
            },
          ],
        ],
      };
    };
Enter fullscreen mode Exit fullscreen mode
  • .gitattributes
    *.pbxproj -text
Enter fullscreen mode Exit fullscreen mode
  • .prettierignore
    package.json
    package-lock.json
    .vscode/*
Enter fullscreen mode Exit fullscreen mode
  • .prettierrc
    {
      "bracketSpacing": true,
      "semi": true,
      "singleQuote": true,
      "trailingComma": "es5",
      "printWidth": 80,
      "tabWidth": 2
    }
Enter fullscreen mode Exit fullscreen mode

File to replace

  • package.json

With all dependencies updated.

    {
      "name": "react-native-expo-starter",
      "homepage": "https://github.com/migu33l/React-Native-Expo-Starter",
      "version": "2.0.0",
      "devDependencies": {
        "@babel/core": "^7.9.0",
        "eslint": "^6.8.0",
        "eslint-config-airbnb-base": "^14.1.0",
        "eslint-config-prettier": "^6.10.1",
        "eslint-import-resolver-babel-module": "^5.1.2",
        "eslint-plugin-flowtype": "^4.7.0",
        "eslint-plugin-import": "^2.20.2",
        "eslint-plugin-prettier": "^3.1.3",
        "eslint-plugin-react": "^7.19.0",
        "eslint-plugin-standard": "^4.0.1",
        "prettier": "^2.0.4",
        "redux-logger": "^3.0.6",
        "schedule": "^0.5.0"
      },
      "main": "index.js",
      "scripts": {
        "android": "react-native run-android",
        "ios": "react-native run-ios",
        "web": "expo start --web",
        "start": "expo start",
        "test": "jest"
      },
      "dependencies": {
        "@expo/vector-icons": "^10.0.6",
        "@react-native-community/async-storage": "^1.9.0",
        "axios": "^0.19.2",
        "babel": "^6.23.0",
        "babel-eslint": "^10.1.0",
        "babel-plugin-module-resolver": "^4.0.0",
        "expo": "~37.0.3",
        "expo-splash-screen": "^0.1.1",
        "expo-updates": "~0.1.0",
        "native-base": "2.13.8",
        "prop-types": "^15.7.2",
        "react": "~16.9.0",
        "react-dom": "~16.9.0",
        "react-native": "~0.61.5",
        "react-native-gesture-handler": "~1.6.0",
        "react-native-reanimated": "~1.7.0",
        "react-native-screens": "~2.2.0",
        "react-native-unimodules": "~0.9.0",
        "react-native-web": "~0.11.7",
        "react-redux": "^7.2.0",
        "redux": "^4.0.5",
        "redux-persist": "^6.0.0",
        "redux-thunk": "^2.3.0"
      },
      "private": true
    }
Enter fullscreen mode Exit fullscreen mode
  • packager-info.json
    {
      "devToolsPort": 19002,
      "expoServerPort": null,
      "packagerPort": null,
      "packagerPid": null,
      "expoServerNgrokUrl": null,
      "packagerNgrokUrl": null,
      "ngrokPid": null,
      "webpackServerPort": null
    }
Enter fullscreen mode Exit fullscreen mode
  • settings.json
    {
      "hostType": "lan",
      "lanType": "ip",
      "dev": true,
      "minify": false,
      "urlRandomness": "xe-t27",
      "https": false
    }
Enter fullscreen mode Exit fullscreen mode
  • src/app/store.js

In the last version of redux-persist@~6 the storage is not compatible and brings us an exception (AsyncStorage exception). You got two options:

  • Use redux-persions@~5, and no code must be changed.
  • Use redux-persist@~6, and must do these changes to store.js file.
    // before
    ...
    import storage from "redux-persist/es/storage";
    ...

    // after
    ...
    import { AsyncStorage } from "react-native";
    ...

    // before
    ...
    const config = {
      key: "root",
      storage,
      blacklist: ["status"]
    };
    ...

    // after
    ...
    const config = {
      key: "root",
      storage: AsyncStorage,
      blacklist: ["status"]
    };
    ...
Enter fullscreen mode Exit fullscreen mode
  • src/assets/fonts/Questrial-Regular.ttf

Changed his name for Questrial.ttf

  • .gitignore
    # OSX
    #
    .DS_Store

    # Xcode
    #
    build/
    *.pbxuser
    !default.pbxuser
    *.mode1v3
    !default.mode1v3
    *.mode2v3
    !default.mode2v3
    *.perspectivev3
    !default.perspectivev3
    xcuserdata
    *.xccheckout
    *.moved-aside
    DerivedData
    *.hmap
    *.ipa
    *.xcuserstate
    project.xcworkspace

    # Android/IntelliJ
    #
    build/
    .idea
    .gradle
    local.properties
    *.iml

    # node.js
    #
    node_modules/
    npm-debug.log
    yarn-error.log

    # BUCK
    buck-out/
    \.buckd/
    *.keystore

    # fastlane
    #
    # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
    # screenshots whenever they are needed.
    # For more information about the recommended setup visit:
    # https://docs.fastlane.tools/best-practices/source-control/

    */fastlane/report.xml
    */fastlane/Preview.html
    */fastlane/screenshots

    # Bundle artifacts
    *.jsbundle

    # CocoaPods
    /ios/Pods/

    # Expo
    .expo/*
    /web-build
Enter fullscreen mode Exit fullscreen mode
  • App.js
    import * as React from 'react';
    import { AppLoading } from 'expo';
    import * as Font from 'expo-font';
    import { Ionicons } from '@expo/vector-icons';

    import { Provider } from 'react-redux';
    import { PersistGate } from 'redux-persist/es/integration/react';
    import { StyleProvider } from 'native-base';
    import { StatusBar, Platform } from 'react-native';

    import getTheme from '@assets/native-base-theme/components';
    import theme from '@assets/native-base-theme/variables/commonColor';

    import configureStore from '@app/store';
    import Loading from '@components/loading/Loading';
    import Dashboard from '@components/dashboard/Dashboard';

    const { persistor, store } = configureStore();

    if (Platform.OS === 'android') StatusBar.setHidden(true);

    export default class App extends React.Component {
      constructor(props) {
        super(props);

        this.state = {
          isReady: false,
        };
      }

      async componentDidMount() {
        await this.loadFonts();
      }

      async loadFonts() {
        await Font.loadAsync({
          Roboto: require('native-base/Fonts/Roboto.ttf'),
          Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
          Questrial: require('@assets/fonts/Questrial.ttf'),
          ...Ionicons.font,
        });

        this.setState({ isReady: true });
      }

      render() {
        if (!this.state.isReady) {
          return <AppLoading></AppLoading>;
        }

        return (
          <Provider store={store}>
            <PersistGate loading={<Loading />} persistor={persistor}>
              <StyleProvider style={getTheme(theme)}>
                <Dashboard />
              </StyleProvider>
            </PersistGate>
          </Provider>
        );
      }
    }
Enter fullscreen mode Exit fullscreen mode
  • app.json
    {
      "name": "React Native Expo Starter",
      "displayName": "ReactNativeExpoStarter",
      "expo": {
        "name": "React Native Expo Starter",
        "slug": "React-Native-Expo-Starter",
        "icon": "src/assets/images/app-icon.png",
        "version": "2.0.0",
        "orientation": "portrait",
        "platforms": ["ios", "android", "web"],
        "assetBundlePatterns": ["**/*"]
      }
    }
Enter fullscreen mode Exit fullscreen mode

Final Step

So we're done, let execute these commands:

    # remove dependencies
    rm -rf node_modules

    # for clean npm cache
    npm cache clean --force

    # install dependencies
    npm i

    # expo start
    npm start
Enter fullscreen mode Exit fullscreen mode

And that its, everything must do ok.

If you had any doubt, don't hesitate and contact me, or better, contribute to this project, making changes and PR.

Extra

Version 2 of this project has disabled react-native by default (for the moment) because it has some problems with ScreenSplash.

In the meantime, if you want to fix these problems, this must-do first:3 install.

    # install the expo client
    npm install --global expo-cli

    # create a new project
    expo init my-project

    # copy the folder from my-project/ios and my-project/android and paste in the root of the project

    # if you want to test ios, first must install CocoaPods and execute this command
    pod install

    # modify the package.json and add this 2 lines underline scripts
            "android": "react-native run-android",
        "ios": "react-native run-ios",

    # now you can run ios and android nativly
    npm run ios
    npm run android
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
boadude
Miguel Meza

Posted on April 20, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Updating ReactNativeExpo.js v1 to v2
reactnative Updating ReactNativeExpo.js v1 to v2

April 20, 2020