Skip to content

Instantly share code, notes, and snippets.

@sriramrudraraju
Last active May 2, 2018 21:36
Show Gist options
  • Save sriramrudraraju/48ea5cb9a0fd9f4c6cc4a3790b0187f7 to your computer and use it in GitHub Desktop.
Save sriramrudraraju/48ea5cb9a0fd9f4c6cc4a3790b0187f7 to your computer and use it in GitHub Desktop.

Create react app and Cordova

This guide developed based on cordova-create-react-app

Table of Contents

Installation

Install Create React App CLI

npm install -g create-react-app

Install Cordova CLI

npm install -g cordova

Create project using create-react-app

create-react-app react-with-cordova

Change the scripts in package.json

Assumption:

  • Regular build will be for react app.
  • Cordova build will be for cordova app.
  • There wont be 2 builds at same time.

For Windows

+ "start": "npm run remove:www && react-scripts-ts start",
- "start": "react-scripts-ts start"
+ "build": "npm run remove:www && react-scripts-ts build",
- "build": "react-scripts-ts build"
+ "build:cordova": "npm run remove:www && react-scripts-ts build && node __script.js && move build www",
"test": "react-scripts-ts test --env=jsdom",
+ "eject": "npm run remove:www && react-scripts-ts eject",
- "eject": "react-scripts-ts eject"
+ "remove:www": "if exist www rd /s /q www"

For Mac

+ "start": "npm run remove:www && react-scripts-ts start",
- "start": "react-scripts-ts start"
+ "build": "npm run remove:www && react-scripts-ts build",
- "build": "react-scripts-ts build"
+ "build:cordova": "npm run remove:www && react-scripts-ts build && node __script.js && mv build www",
"test": "react-scripts-ts test --env=jsdom",
+ "eject": "npm run remove:www && react-scripts-ts eject",
- "eject": "react-scripts-ts eject"
+ "remove:www": "rm -rf www"

create-react-app builds into build folder. But cordova needs application content to be in www folder. So above build:cordova will move the build folder to www.

www is cordova build folder thats needs to built for cordova app only. so this folder should be removed when building for react app. so remove:www validation is added to the scripts.

add __script.js file in the root directory and copy the below code into the file.

let FS= require('fs');

// read the index.html from build folder
let data = FS.readFileSync('./build/index.html', 'utf8');

function insertContent(fullContent, beforeWhat, newContent) {
    // get the position before which newContent has to be added
    const position = fullContent.indexOf(beforeWhat);

    // since splice can be used on arrays only
    let fullContentCopy = fullContent.split('');
    fullContentCopy.splice(position, 0, newContent);

    return fullContentCopy.join('');
}

// will add the <meta> tags needed for cordova app
const afterAddingMeta = insertContent(data, "<link", 
`<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">`+
`<meta name="format-detection" content="telephone=no">`+
`<meta name="msapplication-tap-highlight" content="no">`);

// will add <script> pointing to cordova.js
const afterAddingScript = insertContent(afterAddingMeta, "<script", `<script type="text/javascript" src="cordova.js"></script>`);

// updates the index.html file
FS.writeFile('./build/index.html', afterAddingScript, 'utf8', (err)=> {
    if(err) {
        throw err
    };
})

This script will add the necessary tags to index.html for cordova build.

Exit the react-with-cordova directory and create a cordova app

cordova create sample com.example.sample sample

Cant create the cordova project with the same name as react app. so i created with random name.

copy the config.xml from cordova project to react-with-cordova project.

Note: May need to copy other folders based on the project requirements. For this project I dont need rest.

Note: May need to change id value in <widget id="com.example.sample"> of config.xml based on project name.

React App

Start React app

npm start

Starts the regular create-react-app on localhost:3000/

Build for React app

npm run build

Builds production build for react app. I use serve to run this production build.

Cordova App

Build for Cordova app

npm run build:cordova

builds the app by appending tags to index.html which will be needed for cordova builds

Browser Platform

Add Browser platform

cordova platform add browser

Browser Build

cordova browser build

Note: This build needs www directory which is created from npm run build:cordova

Run in Browser

cordova run browser

Runs the browser build in browser at localhost:8000

Other Platforms

Commands will be similar to as browser platform. cordova platforms guide.

Troubleshooting

Adding Platforms

Issue

Error: UnhandledPromiseRejeactionWarning: Unhandled promise rejection (rejection id: 1): Current working directory is not a Cordova-based project.

Fix

  • Cordova expecting to have www folder in the root folder
  • Create empty www folder. more info
  • npm run build:cordova will generate www folder. So run this before adding platforms.

Running on Browser

Added cordova browser platform.

When checking cordova platform requirements got below error.

Issue

Error: (node:76480) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'forEach' of undefined

Fix

  • Didnt have any impact on build and running.

Running on Android

Once android studio and necessary tools are installed.

Android platform added and during cordova build android. May get the below errors.


Issue

Error: Exception in thread "main" java.net.UnknownHostException: services.gradle.org Fix

  • This is due to proxy settings
  • Go to "C:\Users[yourusername].gradle" folder (hidden folder - Go to folder option and enable show hidden files if folder is not showing up)
  • Look for file "gradle.properties" if DOES NOT (most likely this would be the case) exists, Create it under "C:\Users[yourusername].gradle\
  • Or follow this issue
systemProp.http.proxyHost=xxx.xxx.xxx.com
systemProp.http.proxyPort=0000
systemProp.http.proxyUser=xxUserIdxx
systemProp.http.proxyPassword=xxpasswordxx

systemProp.https.proxyHost=xxx.xxx.xxx.com
systemProp.https.proxyPort=0000
systemProp.https.proxyUser= xxUserIdxx
systemProp.https.proxyPassword=xxpasswordxx
  • I created a sample android exclusive project using android studio and took the gradle.properties file and pasted in platforms/android. Then updated with the above details.

  • If above config doesnt help, see Configuring Graddle


Issue

Error: something related to license agreement

Fix

  • ANDROID_HOME is set as mentioned in cordova android.
  • In cmd prompt run $ANDROID_HOME/tools/bin
  • Then run sdkmanager –licenses
  • Agree the licenses.

Once android build is successfully built.

To preview on emulator, create an emulator form Android Studio AVD.

when cordova run android executed when emulator is closed.

Issue

cmd prompt showing waiting for start . . forever

Fix

  • Open the emulator manually from AVD.
  • Then run cordova run android

This issue already reasolved in _script.js, Just referencing this for information.

Backstory

  • index.html needs extra <meta> and <script> tags than create-react-app.
  • Took those tags from sepeartely built cordova browser build.
  • One <meta> creates the issue.
  • It worked in browser build. But had issue in android build.

Issue

Bug: Javascript part not working in the emulator

Fix

  • Replaced Earlier meta tag with new meta tag.
  • Earlier tag

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">

  • New tag

<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"/>


Issue

Not able to see the react app content

Fix

  • Added "homepage": "./" property in package.json.
  • more info

Tip

  • If using react-router use HashRouter with basename="/" for development.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment