loading...

Updating ReactNativeExpo.js v1 to v2

migu3l profile image Migu3l Updated on ・5 min read

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

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);
  • .buckconfig
    [android]
      target = Google Inc.:Google APIs:23

    [maven_repositories]
      central = https://repo1.maven.org/maven2
  • 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',
              },
            },
          ],
        ],
      };
    };
  • .gitattributes
    *.pbxproj -text
  • .prettierignore
    package.json
    package-lock.json
    .vscode/*
  • .prettierrc
    {
      "bracketSpacing": true,
      "semi": true,
      "singleQuote": true,
      "trailingComma": "es5",
      "printWidth": 80,
      "tabWidth": 2
    }

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
    }
  • packager-info.json
    {
      "devToolsPort": 19002,
      "expoServerPort": null,
      "packagerPort": null,
      "packagerPid": null,
      "expoServerNgrokUrl": null,
      "packagerNgrokUrl": null,
      "ngrokPid": null,
      "webpackServerPort": null
    }
  • settings.json
    {
      "hostType": "lan",
      "lanType": "ip",
      "dev": true,
      "minify": false,
      "urlRandomness": "xe-t27",
      "https": false
    }
  • 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"]
    };
    ...
  • 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
  • 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>
        );
      }
    }
  • 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": ["**/*"]
      }
    }

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

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

Discussion

pic
Editor guide