This guide developed based on cordova-create-react-app
npm install -g create-react-app
npm install -g cordova
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.
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.
npm start
Starts the regular create-react-app on localhost:3000/
npm run build
Builds production build for react app. I use serve to run this production build.
npm run build:cordova
builds the app by appending tags to index.html which will be needed for cordova builds
cordova platform add browser
cordova browser build
Note: This build needs www directory which is created from
npm run build:cordova
cordova run browser
Runs the browser build in browser at localhost:8000
Commands will be similar to as browser platform. cordova platforms guide.
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 generatewww
folder. So run this before adding platforms.
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.
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'"/>
- As mentioned here
Issue
Not able to see the react app content
Fix
- Added
"homepage": "./"
property inpackage.json
. - more info
Tip
- If using
react-router
useHashRouter
withbasename="/"
for development.