/react-native-awesome-starter

⚛️ react-native initial development environment setting

Primary LanguageObjective-CMIT LicenseMIT

react-native-awesome-starter

This repository is about initial Development Environment Settings.

Version

  • react: 16.5.0
  • react-native: 0.57.4

Contents

  1. react-native init

  2. use typescript

  3. use eslint

  4. use mobx and mobx-react

  5. connect with code-push

  6. connect with firebase

(TODO)

  • add assets/font
  • use react-native-splash-screen
  • use react-native-fast-image
  • use react-navigation or react-native-navigation

How to set up

1. init your project with react-native-cli

$ npm install -g react-native-cli
$ react-native init MyProject
$ cd MyProject

2. use typescript

$ yarn add --dev typescript
$ yarn add --dev react-native-typescript-transformer
$ yarn tsc --init --pretty --jsx react
$ touch rn-cli.config.js
$ yarn add --dev @types/react @types/react-native

write this code in rn-cli.config.js

module.exports = {
  getTransformModulePath() {
    return require.resolve("react-native-typescript-transformer");
  },
  getSourceExts() {
    return ["ts", "tsx"];
  }
};

in order to migrate to typescript, rename App.js to App.tsx

add typescript test infra

yarn add --dev ts-jest

write this in package.json

"jest": {
  "preset": "react-native",
  "moduleFileExtensions": [
    "ts",
    "tsx",
    "js"
  ],
  "transform": {
    "^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
    "\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
  },
  "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
  "testPathIgnorePatterns": [
    "\\.snap$",
    "<rootDir>/node_modules/"
  ],
  "cacheDirectory": ".jest/cache"
}

3. use eslint

npm install --save-dev eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser

add .eslintrc.js in root directory

module.exports = {
    parser: '@typescript-eslint/parser',
    plugins: ['@typescript-eslint'],
    extends: [
        'plugin:@typescript-eslint/recommended',
        'plugin:react/recommended',
    ],
};

add settings.json in .vscode

{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "typescript",
        "typescriptreact"
      ]
}

edit compilerOptions in tsconfig.json

{
  "compilerOptions": {
    
    "baseUrl": ".",
    "paths": {
      "~/*": ["src/*"]
    }
  },
  
}

4. use mobx and mobx-react

npm install --save mobx mobx-react

add babel-preset plugin transform-decorators-legacy in .babelrc to use decorator syntax

{
  "presets": [
    "module:metro-react-native-babel-preset"
  ],
  "plugins": [
    "transform-decorators-legacy"
  ]
}

Trouble Shooting

if you have error like this

error: bundling failed: Error: The 'decorators' plugin requires a 'decoratorsBeforeExport' option, whose value must be a boolean. If you are migrating from Babylon/Babel 6 or want to use the old decorators proposal, you should use the 'decorators-legacy' plugin instead of 'decorators'.
npm install --save-dev @babel/plugin-proposal-decorators
{
  ...
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
  ]
}

let experimentalDecorators be true in tsconfig.json

{
  "compilerOptions": {
    ...
    "experimentalDecorators": true
    ...
  }
}

5. connect with code-push

install code-push-cli

npm install -g code-push-cli
code-push register

register your app in code-push

code-push app add <AppName-Android>
code-push app add <AppName-iOS>

you can check apps that you registered by this command.

code-push app list
npm install --save react-native-code-push@latest
react-native link react-native-code-push

iOS

write Staging Deployment Key in info.plist

<key>CodePushDeploymentKey</key>
<string><Staging Deployment Key></string>

Android

write Staging Deployment Key in MainApplication.java

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new CodePush("<Staging Deployment Key>", getApplicationContext(), BuildConfig.DEBUG)
    );
}

6. connect with firebase

npm install --save react-native-firebase
react-native link react-native-firebase

create your project in Firebase

Analytics

iOS

Setup GoogleService-Info.plist

install GoogleService-Info.plist and move to ios/[YOUR APP NAME] directory

Initialize Firebase

in AppDelegate.m

#import <Firebase.h>

[FIRApp configure];
Install Firebase Library

in PodFile

# Required by RNFirebase
pod 'Firebase/Core', '~> 5.9.0'
pod install

Android

Setup google-services.json

install google-services.json and move to android/app directory

write this code in app.gradle (project level)

buildscript {
  // ...
  dependencies {
    // ...
    classpath 'com.google.gms:google-services:4.0.1'
  }
}

write this code very bottom in app.gradle (app level)

apply plugin: 'com.google.gms.google-services'
Initialize Firebase
dependencies {
  // This should be here already
  implementation project(':react-native-firebase')

  // Firebase dependencies
  implementation "com.google.android.gms:play-services-base:15.0.1"
  implementation "com.google.firebase:firebase-core:16.0.3"

  ...

Analytics logEvent

You can track event with logEvent function
firebase.analytics().logEvent(eventName, params);
// eventName: string, params: object

Admob

iOS

Android

Trouble Shooting

Problem

When you build react-native application in Xcode

Xcode 10: Build input file double-conversion cannot be found

Solution

$ cd node_modules/react-native/scripts && ./ios-install-third-party.sh && cd ../../../
$ cd node_modules/react-native/third-party/glog-0.3.5/ && ../../scripts/ios-configure-glog.sh && cd ../../../../

reference: facebook/react-native#21168

Problem

error (when pod install)

In Podfile:
    React/CxxBridge (from `../node_modules/react-native`) was resolved to 0.57.2, which depends on
      Folly (= 2016.10.31.00)

Solution

write this code in Podfile

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
  pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

reference: https://facebook.github.io/react-native/docs/integration-with-existing-apps.html

Deprecated

styled-components

3. use styled-components (ts)

yarn add --dev styled-components

make index.ts file in theme directory

import * as styledComponents from "styled-components";

const {
  default: styled,
  css,
  injectGlobal,
  ThemeProvider
} = styledComponents as styledComponents.ThemedStyledComponentsModule<
  IThemeInterface
>;

export interface IThemeInterface {
  primaryColor: string;
}

export const theme = {
  primaryColor: "#e9e9eb"
};

export default styled;
export { css, injectGlobal, ThemeProvider };

In react-native, you cannot use keyframes. You should use Animated API supported by react-native.

migrate css to styled-components

// in App.tsx
const ContainerView = styled(View)`
    flex: 1;
    justify-content: center;
    align-items: center;
    background-color: #F5FCFF;
`;

class App extends Component {
  render() {
    return (
      <ContainerView>
        // ...
      </ContainerView>
    );
  }
}

Reference