@sigmayun/react-native-template-typescript

@sigmayun/react-native template-typescript is a template scaffolding based on react-native community/react-native template-typescript secondary development. The architectural solution of this article is incorporated into this template. You don’t even need to read this article to use the best practices in this article!!

The global variable

Now that we’ve introduced TypeScript, we don’t have to worry about contaminating global objects by adding properties, but we do need to do some configuration.

Create new types in the root directory of the project and create a new global.d.ts file name.

declare const global: {
  HermesInternal: null| {}... }Copy the code

2. Set skipLibCheck in tsconfig.json to true to prevent collisions with @types/node’s Global declaration

Examples of global.ts, types/global.d.ts, tsconfig.json can be found at github.com/sigmayun/re… Look at it.

Coding standards

  • @sishuguojixuefu/eslint-config: Large, complete ESLint configuration, supports Vue, JSX, JS, TS, TSX, HTML ESLint configuration plug-in, based on Airbnb, supports Prettier
  • Husky + Lint-staged: ProhibitedcommitCode that does not conform to the specification

Example code for this part: bre. Is /3GD7cHKn

Npm Scripts

Using NPM Scripts can help improve workflow!!

{
  "scripts": {
    "postinstall": "npx jetifier"."android": "react-native run-android"."ios": "react-native run-ios"."start": "react-native start"."test": "jest"."lint": "eslint . --ext .js,.jsx,.ts,.tsx"."pod": "cd ios && pod install"."gradle:clean": "cd android && ./gradlew clean"."an:release": "yarn gradle:clean && cd android && ./gradlew app:assembleRelease"."an:installRelease": "yarn gradle:clean && cd android && ./gradlew app:installRelease"."an:releaseStaging": "yarn gradle:clean && cd android && ./gradlew app:assembleReleaseStaging"."an:installReleaseStaging": "yarn gradle:clean && cd android && ./gradlew app:installReleaseStaging"."an:genkeypair": "keytool -genkeypair -v -keystore release.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000"."an:key-debug": "keytool -list -v -keystore ./android/app/debug.keystore"."an:key-release": "keytool -v -list -keystore ./android/app/release.keystore"."icon": "npx iconfont-rn"}}Copy the code

Example code for this part: bre. Is /LC6uu8kc

Network programming

  • Axios: Axios is a Promise based HTTP library that can be used in browsers and Node.js.
  • qs: A querystring parsing and stringifying library with some added security.
  • clean-deep: recursively removes empty objects, empty arrays, empty strings from objects,nullandvalueValue. Do not change the raw data.

Example code for this part: bre. Is /39khhJtn

Routing management

  • React Navigation: This module is the official recommended Navigation component and not only supported after the upgrade to 5hooks, but also supports dynamic routing.

Example code for this part: bre. Is /pzA7JArY

Related blog: bre. Is /pzA7JArY

State management

  • mobx + mobx-react: It’s much easier to use than Redux, so if you’re still hesitating, read a good articleWhy did I move from Redux to Mobx

The local store

  • React-native simple-storage: a simple wrapper for AsyncStorage
  • RXDB: JavaScript instant database, if you have complex caching business to consider
  • WatermelonDB: a responsive database framework for React and React Native services

Startup screen

  • react-native-splash-screen

The configuration of the boot screen involves a lot of native knowledge, read bre. Is /CRC2SkqP for configuration.

Hot update

  • React-native – Pushy: ReactNative’s Chinese version of code hot update service, free, but limited, not recommended
  • React-native code-push + AppCenter
  • React-native code-push + code-push-server: suitable for a hot update server built by the company

The new hot update part I haven’t write a blog, you can reference I wrote before: first techblog.sishuxuefu.com/atricle.htm… React Native is standard.

UI framework

  • React Native: Ant Design provides a library of REACT Native UI components
  • Beeshell: The React Native component library
  • React – Native Elements: Cross-platform React Native UI tool kit
  • React-native uI-lib: Untested, looks powerful

For other components, see bre. Is /jWUGvPrK

The list of

  • Mobx + React-native largelist implements paging: React-native Largelist-V3 is recommended, which supports drop-down refresh, drop-down loading, grouped lists, tables, and waterfall streams
  • To encapsulateFlatList,SectionListReact-native largelist-V3 may not be suitable for all scenarios

icon

  • React-native iconfont cli: use pure JS to convert ICONS into RN components, independent of fonts, support multi-color, support hot update
  • @ant-design/icons-react-native: Ant Design Icons for React Native
  • react-native-vector-icons: Perfect for buttons, logos and nav/tab bars. Easy to extend, style and integrate into your project.

The font

  • React-native-fonts: a list of fonts available out of the box for React Native projects. This library only counts the fonts available in React Native
  • React Native Configures customized fonts
  • React Native Custom Fonts
  • React-native responsive fontSize: fontSize is based on the screen size of the device in React Native
  • The React Native font size does not change with font Settings
  • React Native font solutions point north
  • react-native-responsive-fontsize

tool

  • React -native-shadow-generator: Generates react Native shadow code online
  • visualize-bundle: npx visualize-bundleAllows you to one-click check your React Native bundle and find large dependencies
  • Icon Factory: One click to generate all sizes of app ICONS/startup images

React Hooks

React Navigation, Mobx and other popular libraries have built-in support for the new syntax.

Recommended reading

It is recommended to read the official document first!!

  • The official documentation
  • Learn React Hooks in 30 minutes
  • React Hooks 【 nearly 1W words 】+ project combat
  • Learn to understand react hooks
  • React Hooks

How are class components compatible

For business-critical scenarios where Hooks are not applicable, we can package a layer on top of the class component to support the Hooks component for React Navigation. This is because React Navigation 5 only uses useHeaderHeight() to get the title bar height.

class Albums extends React.Component {
  render() {
    return <ScrollView ref={this.props.scrollRef}><Text>{this.props.headerHeight}</Text></ScrollView>; }}// Encapsulate and export
export default function(props) {
  const ref = React.useRef(null);
  const headerHeight = useHeaderHeight();
  useScrollToTop(ref);
  return <Albums {. props} scrollRef={ref} headerHeight={headerHeight}/>;
}
Copy the code

Metro

  • Configure the React Native port using Metro

Third release service

Here as far as possible for everyone to recommend free services, of course, choose to build their own services is also a great choice!!

Sentry

Sentry allows users to build services on their own servers. The Sentry-React-Native plugin is provided to help React Native engineers quickly integrate services. If possible, Sentry is probably the best choice in the industry.

Sentry provides self-hosted and cloud-based error monitoring that helps all software teams discover categories and prioritize errors in real time. Already used by 1 million developers at more than 50,000 companies, Sentry delivers better software faster. Aren’t you going to join them?

Tencent Bugly

Tencent Bugly provides mobile developers with professional abnormal reporting and operation statistics to help developers quickly find and solve anomalies, and at the same time, master the operation dynamics of products and timely follow up user feedback. Provides free exception reporting, operation statistics, and application upgrade

push

Pigeons | tencent mobile push

Free, fast and easy push service for developers. QQ login can be quickly registered, for the APP access SDK immediately after the unlimited application push ability, effectively improve user retention, activity, developers of the only choice!

Xiaomi message push service

  • System-level channels on MIUI
  • IOS /Android full platform support
  • Free, stable, safe and efficient

The aurora push

Aurora push service, can be used for free, but more restrictions. React Native integration is easy

U-Push

And aurora belong to the same class, restricted level free, Umeng’s products win in the ecology, the company’s product consideration, later users up after convenient expansion.

Social sharing

ShareSDK

Provide developers with social functions such as sharing and authorization from 40+ mainstream platforms, with stable effects and complete and clear statistics of shared data

  • A key to share
  • Third-party Login
  • A closed-loop share
  • Short chain transformation
  • Data statistics
  • Sina Weibo exclusive LinkCard

jshare

  • A key to share
  • Third release Login
  • Socialized statistics
  • The official React Native SDK integrates easily

U-Share

  • Comprehensive coverage of social platforms at home and abroad
  • Integration cost is low and speed is fast
  • Freely customize the sharing interface
  • Authoritative, real-time big data analysis

other

  • React-native wechat: 🚀 wechat login, share, favorite and payment for react-native on iOS and Android platforms
  • @0x5e/react-native: alipay SDK for react native. Support mobile webpage URL payment. Support RN >= 0.47

test

The author’s understanding of this part is limited to Jest, if there are big guys, please contact me to supplement!!

  • Jest: Jest is a delightful JavaScript testing framework that focuses on simplicity. React Native is already integrated and can be used directly.

Automated operation and maintenance

The author is not familiar with this part, and only knows the scheme of Jekens + GitLab

Pit for shell files

For security purposes, shell files are not executable by default, including the android/ Gradlew script files used for packaging, which causes continuous integration problems: operations students cannot execute our packaging commands by default. The solution is simple:

$ git update-index --add --chmod=+x android/gradlew
Copy the code

Dynamically set the version of package.json

set-version.sh:

#! /bin/bash

# current_git_branch_latest_id=`git rev-parse HEAD`
current_git_branch_latest_short_id=`git rev-parse --short HEAD`
current_os=`uname -s`

# echo current git branch latest commit id=$current_git_branch_latest_id
echo current git branch latest commit short id=$current_git_branch_latest_short_id
echo current os=$current_os

if [ "$current_os"= ="Darwin" ]
  then
  sed -i ' ' 's/" version ". * / "version" : "1.0.0 -'$current_git_branch_latest_short_id'",/g' package.json
else
  echo windows
  sed -i 's/"version".*/"version": "'$current_git_branch_latest_short_id'",/g' package.json
fi
Copy the code

package.json:

{
  / / rely on husky
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"."post-commit": [
        "./scripts/set-version.sh"."git add ."."git commit -m bump version"."git push"]}}}Copy the code

Official component defect handling

  • Image corners do not work on Android
  • React Native handles text bias on Android
  • React Native custom TextInput height issues
  • [Android] Using TextInput inside ViewPagerAndroid causes context menu (copy/paste) in some cases to not display

The VsCode plug-in is recommended

  • React Native TypeScript Snippets: developed by me to help developers build pages and components quickly.
  • ES7 React/Redux/GraphQL/React-Native Snippets

Performance optimization

Automatic Remove console statement

To be exact, delete the console statement in a formal environment. For details about how to configure the console statement, see The Automatic Remove Console Statement

Recommended reading

  • React Native Performance Optimization Guide

Application of closed

  • Fir: hosting platform for internal testing of free applications
  • Dandelion: free Apple ios app app internal test distribution hosting, Android Android APP internal test distribution hosting, ios enterprise signature, ios exclusive signature, ios super signature, ios enterprise account

Android will know and will know

Configuring the Application Name

Is very simple, we directly open the android/app/SRC/main/res/values/strings. The XML, you can see app_name, in this configuration can be changed to what you want.

You can specify the name of the app when initializing the project, like this: NPX react-native init MyApp –title header

The configuration icon

1. Use the icon Factory, React-Native SVG-app-icon or have the designer give the image

2, In android\app\ SRC \main\res\mipmap-xxxxxx directly overwrite the icon, pay attention to the icon size.

Packaging APK

1. Run keytool -genkeypair -v -keystore release.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity in the root directory of the project 10000 Generate the key file release.keystore

2. Put the release.keystore file in the Android /app folder of your project.

Configure Android /app/build.gradle

android{
    ...
    signingConfigs {
        release {
            storeFile file("release.keystore")
            storePassword "* * * *"
            keyAlias "my-key-alias"
            keyPassword "* * * *"}}... buildTypes { release { ... signingConfig signingConfigs.release ... }}}Copy the code

Packaging optimization

Eliminate useless language resources

By configuring the android/defaultConfig resConfigs can choose only pack what kind of language, and then remove the aar package language around the world, especially the support in the package.

The language to be retained depends on the users and market of the product. If only the default English and Chinese languages are selected, the configuration is as follows:

defaultConfig {
	resConfigs "en"."zh"
}
Copy the code

Configuration PackagingOptions

Open the Android /app/build.gradle file and add the following configuration:

packagingOptions {
    exclude 'META-INF/android_release.kotlin_module'
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/notice.txt'
    exclude 'the meta-inf/ASL2.0'
}
Copy the code
  • pickFirsts: When duplicate files occur, the first matching file is packaged into APK
  • merges: When duplicate files occur, merge the duplicate files into APK
  • excludes: Exclude matching files when packaging

Configuration splits

Adb shell -> CD /proc -> cat cpuinfo

By default, the generated APK contains native code for both x86 and ARMv7a CPU architectures. This makes it easier for us to share APK with others, since it runs on almost all Android devices. However, this can lead to code on all devices that doesn’t run at all, taking up space. Currently, the majority of Android devices are based on ARM architecture, so for most applications, you can consider removing x86 architecture support.

You can modify the following code in Android /app/build.gradle:

- include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
+ include "armeabi-v7a", "arm64-v8a"
- def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, "x86_64": 4]
+ def versionCodes = ["armeabi-v7a":1, "arm64-v8a": 2]
Copy the code

Gradle compilation speed optimized configuration

Add the following configuration to android\gradle.properties:

Daemon =true # Let Gradle compile in parallel org.gradle.parallel=true # Let Gradle configure only when needed Org. Gradle. Configureondemand = true # increase gradle run the size of the Java virtual machine (org. Gradle. Jvmargs = - Xmx4096m - XX: MaxPermSize = 4096 m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8Copy the code

BuildConfig

In react-native, we can easily read these properties with the help of react-native config-reader

BuildConfig is a Java file generated in app\build\generated\source\ BuildConfig \debug(release)\ package according to buildType after the program is compiled. The default properties are:

  • DEBUG: Indicates whether it is a debug version
  • APPLICATION_ID: Indicates the package name of the current application
  • FLAVOR: Product (channel package name)
  • BUILD_TYPE: Current compile type (release/debug)
  • VERSION_CODE: Version number (number)
  • VERSION_NAME: the version number

Custom BuildConfig

defaultConfig {
  // Three arguments: 1. the type of the constant to be defined 2. the name of the constant 3. The value of this constant
  // APP_NAME, which corresponds to CFBundleDisplayName of ios
  buildConfigField "String"."APP_NAME"."Who am I?"
  // BUILD_TIME
  buildConfigField "String"."BUILD_TIME".'"' + new Date().format("yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("Asia/Shanghai")) + '"'
}
Copy the code

Get the main project BuildConfig in the submodule

.public static Object getBuildConfigValue(Context context, String fieldName) {
  try{ Class<? > clazz = Class.forName(context.getPackageName() +".BuildConfig");
    Field field = clazz.getField(fieldName);
    return field.get(null);
  } catch (ClassNotFoundException e) {
    e.printStackTrace();
  } catch (NoSuchFieldException e) {
    e.printStackTrace();
  } catch (IllegalAccessException e) {
    e.printStackTrace();
  }
  return null; }... String versionName = (String)getBuildConfigValue(activity,"VERSION_NAME"))
Copy the code

Detected problems with API Compatibility (visit g.co/dev/appcompat for more info)

Add the closeAndroidPDialog method in mainActivity. Java and call it in the onCreate method

import android.os.Bundle;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
importjava.lang.reflect.Method; .@Override
protected void onCreate(Bundle savedInstanceState) {
  closeAndroidPDialog(); // here
  super.onCreate(savedInstanceState); }...private void closeAndroidPDialog(a){
  try {
    Class aClass = Class.forName("android.content.pm.PackageParser$Package");
    Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class);
    declaredConstructor.setAccessible(true);
  } catch (Exception e) {
    e.printStackTrace();
  }
  try {
    Class cls = Class.forName("android.app.ActivityThread");
    Method declaredMethod = cls.getDeclaredMethod("currentActivityThread");
    declaredMethod.setAccessible(true);
    Object activityThread = declaredMethod.invoke(null);
    Field mHiddenApiWarningShown = cls.getDeclaredField("mHiddenApiWarningShown");
    mHiddenApiWarningShown.setAccessible(true);
    mHiddenApiWarningShown.setBoolean(activityThread, true);
  } catch(Exception e) { e.printStackTrace(); }}Copy the code

Customize the suffix for Android packaging

Configure the android/app/build. Gradle:

.def releaseTime() {
    return new Date().format("yyyyMMdd-HHmmss", TimeZone.getTimeZone("GMT+08:00"))}...android: {
    applicationVariants.all { variant ->
        ...
    		variant.outputs.all {
            // the apk name is e.g. galaxy_v1.0.1_2018-11-1_debug.apk
           outputFileName = "galaxy_v${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}.apk"}... }}Copy the code

Common errors and solutions

Failed to read PNG signature: file does not start with PNG signature

Sometimes the Demo resource files downloaded from the Internet are not standard. You can change the JPG file name to PNG suffix. Gradle package check shows that the compilation failed. We through aaptOptions cruncherEnabled = false to prohibit Gradle check the legitimacy of the PNG:

android {
  aaptOptions {
    cruncherEnabled=false}}Copy the code

com.android.build.api.transform.TransformException

Add the following configuration to android\gradle.properties:

dexOptions.javaMaxHeapSize = 2g
Copy the code

The number of method references in a .dex file cannot exceed 64K.

As the Android platform continues to grow, so does the size of Android apps. When your application and the libraries it references reach a certain size, you encounter build errors indicating that your application has reached the limits of the Android application build architecture.

The solution is to configure your app to subcontract Dalvik executables. In Android /app/build.gradle, do the following:

defaultConfig {
+ multiDexEnabled true
}
Copy the code

Ios will know and will know

This part of the author is not deep contact, there are big people can contact me to supplement!!

The mirror

Pod Install will pull code from GitHub, so it will be slow at home. Young people should be patriotic, consciously not over the wall!!

  • Homebrew image use help
  • CocoaPods Image usage help

Configuring the Application Name

  1. Select project name
  2. Go to the right menuInfooptions
  3. addBundle display nameAnd thevalueSet it to “App name”
  4. And finally againRunOnce, you can see the latest effect

You can specify the name of the app when initializing the project, like this: NPX react-native init MyApp –title header

The configuration icon

1. Use the icon Factory, react-Native SVG-app-icon, or ask the designer to create the image. 2.

Get BUILD_TYPE

Add BUILD_TYPE to info.plist with value $(CONFIGURATION)

Get build time

Add BUILD_TIME to info.plist with the value null and update it with the script every time it is compiled. Target-> Build Phases -> + -> New Run Script Phase

#! /bin/bash
infoplist="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
builddate=`date +%Y-%m-%d_%H:%M`
if [[ -n "$builddate" ]]; then
/usr/libexec/PlistBuddy -c "Set :BUILD_TIME $builddate" ${infoplist}
fi
Copy the code

Permission to apply for

  • Privacy - Camera Usage Description
  • Privacy - Photo Library Usage Description
  • Privacy - Microphone Usage Description

Lean Core

COMPONENT DEPRECATED? NEW HOME
AsyncStorage 0.59 @react-native-community/react-native-async-storage
ImageStore 0.59 expo-file-system or react-native-fs
MaskedViewIOS 0.59 @react-native-community/react-native-masked-view
NetInfo 0.59 @react-native-community/react-native-netinfo
Slider 0.59 @react-native-community/react-native-slider
ViewPagerAndroid 0.59 @react-native-community/react-native-viewpager
WebView 0.60 react-native-webview
NetInfo 0.60 @react-native-community/netinfo
Geolocation 0.60 @react-native-community/geolocation
Apple TV Support 0.62 react-native-community/react-native-tvos