assembleRelease fails with react-native 0.50 - react-native

Using gradle-plugin 3.0.0
Gradle distribution 4.1.0
react-native 0.50
Linux fedora 27
app name is u1b.
Project structure
/proj/mob/rn.common (this is where node_modules is and all my js related stuff)
/proj/mob/a/u1b -- is where the android app is.
the project structure is different than the one normally created by boiler plate react-native create app script (because my node_modules is not just one level up from the android app).
But not clear if this is an issue or not.
I have been building my android with react-native library, in debug mode.
Now its time to start building release.
But I am running into a problem
bash gradlew assembleRelease errors out :
> Task :app:bundleReleaseJsAndAssets
Scanning folders for symlinks in /home/v/devel/mine/proj/mob/rn.common/node_modules (12ms)
Scanning folders for symlinks in /home/v/devel/mine/proj/mob/rn.common/node_modules (9ms)
Loading dependency graph, done.
warning: the transform cache was reset.
bundle: start
bundle: finish
bundle: Writing bundle output to: /home/v/tmp/u1b/app/intermediates/assets/release/index.android.bundle
bundle: Done writing bundle output
bundle: Copying 18 asset files
bundle: Done copying assets
/home/v/tmp/u1b/app/intermediates/res/merged/release/drawable-mdpi/src_jsapp_img_material_ic_local_library_black_48dp_android_drawablexxhlack_48dp.png: **error: Invalid filename. Unable to add.**
The image file it is looking at is, indeed not there. However I have no idea how that file name is constructed and, why it something is looking for it.
my gradle.properties contains a flag to switch to old apk due to a bug
# https://github.com/react-community/react-navigation/issues/1976
android.enableAapt2=false
could somebody shed a light on how the image names are decided and what might be causing the error
thank you

Resolved.
I figured out how the offending file name was constructed, and then I was able to mitigate what seemed to be 'too deep of a path for image file'.
Basically the file name below
src_jsapp_img_material_ic_local_library_black_48dp_android_drawablexxhblack_48dp.png
was concatenation of a path where the file resided in my javascript folder (starting from same level where node_modules are )
my index.android.js referes to a static icon file
icon: require('./src/js.app/img/material/ic_local_library_black_48dp/android/drawable-xxhdpi/ic_local_library_black_48dp.png'),
When the bundler constructed that offending file name, It was basically appending elements of the path to the file together, with some 'mangling'. Like removing a dot (so js.app became jsapp)
I just copied that file over to a higher level directory (to reduce the length of the release-constructed file name)
And then the release build started working.
The length of the offending file name was about 177 characters long. Not sure why it created problem for the release build. I suspect this is a limitation of android tools, not facebook's problem. I switched back and forth between buildTools 25.0.3 and 26.0.2 (that also meant switching android plugin versions .. .and that whole thing took quite a bit of time). But the problem was in either of the buildtools versions.
So I just figured deep directory structures for js static resource (eg images) is a problem for now. So better use smaller directory depths.

Related

react-native build failed, 'native_modules.gradle' line: 182

I init a new project using react native 0.61.2 , using react-native init proj command, after that when I try to react-native run-android, the build fails with this error :
FAILURE: Build failed with an exception.
Where:Script '..\node_modules#react-native-community\cli-platform-android\native_modules.gradle' line: 182
What went wrong:
A problem occurred evaluating script.
Unable to determine the current character, it is not a string, number, array, or object
The current character read is 'D' with an int value of 68
Unable to determine the current character, it is not a string, number, array, or object
line number 1
index number 0
as i mentioned, it's a fresh project.
any idea how to fix this ?
I ran into the same issue today and noticed that react recently released new versions to react-native and react.
I downgraded to versions i know work properly which are:
"react": "~16.8.0",
"react-native": "~0.60.0"
cleared all cache and the project loads correctly.
in order to do so change the dependencies in your package.json file
then delete your node_modules directory, package.lock file and run npm cache clean
finally run npm i
perhaps there are still issues in the new releases.
I am aslo facing the same issue. Downgrading works, however i have two other projects that r working fine and they are react native 0.61.2
Only new projects are giving this error. I read in some blogs that removing react community cli from global and trying again might do the trick.
Will try that tomorrow and post my findings.
Look for mistakes in your AndroidManifest.xml!!!
For me, I solved this by replacing the character ” with "
(And also read some people telling that unclosed tags did that too)
As dumb as it looks, I got to this error from following a tutorial.
(tip: VS code would often show these quotes in different colors, unless you have installed another XML files extension)
I ran into the same issue in a fresh project with RN 0.64.0. The project was created inside a monorepo that was using Yarn workspaces. In my case, Yarn had moved or "hoisted" the #react-native-community/cli-platform-android/native_modules.gradle file to the root node_modules directory.
The Android project's settings.gradle and build.gradle files are expecting the #react-native-community/cli-platform-android/native_modules.gradle file to be in the RN project's node_modules directory and not the repo's root node_modules directory.
Try updating line 2 of settings.gradle to something like:
apply from: file("../../../node_modules/#react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
And line 222 of build.gradle to something like:
apply from: file("../../../../node_modules/#react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
Obviously, you will need to adjust how many leading ../ you add to the path depending on how nested your project is.
You could also look into using the nohoist options available with Yarn to keep packages from moving around.

Can ios/build folder be ignored in a React-Native project?

I'm currently working on a project alone but soon I'll be working with other people on my React-Native project and everytime I commit changes, there's A LOT of files that changed in this folder and I'm afraid this could cause a lot of problems if I were to work with a team on this project. Can I add this folder to my .gitignore file without having any problems? Also the size of this folder is very huge, something like 537Mb so far.
Side question: is the content of this folder generated by React-Native when it compiles the whole project?
Thanks
Yes, you can ignore this folder, it's generated every time you build a project
Here is safe list which you can add to .gitignore to ignore xcode unnecessary files:
# Xcode
#
build/
Pods/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
Also you can clean project if it comes to that big size:
(Product -> Clean or CMD+Shift+K)

React-Native: How to open locally bundled binary file

I'm writing a react-native app, and I want it to deploy with a zip file that contains a device firmware update.
Before letting the user send the update, I need my code to open the zip and do some validation of its contents.
I've found lots of zip-handling NPM packages, so all I need to do is load the file contents so I can feed it to one of these.
require('./firmware/fw.zip'); <-- packager doesn't include .zip by default
require('./firmware/fw.pdf'); <-- [gross hack] packager includes pdfs, but the actual result of the require() call is a number: 5. I don't know what I can do with this number to get file contents, but I'm pretty sure this require() system is designed for loading images, not binary data.
ReactNativeFs.openFile('./firmware/fw.zip'); <-- fails with ENOENT
ReactNativeFs.openFile(${ReactNativeFs.MainBundlePath}/firmware/fw.zip); <-- MainBundlePath is undefined on android.
This seems like a really basic question, so I'm sure I've missed a piece of documentation somewhere, but I'm heading into my third hour trying to load the contents of this file with no luck.
I'm pretty sure I could manually put the zip file into the appropriate android and ios resource directories, but that seems like a step down a hard-to-maintain road.
I encountered this problem again a couple months later (I'm apparently the only guy that needs to package .zips in react-native), and the above answer didn't work out for iOS. So I encoded the .zips as base64, put them in .js files, then used import to get the data from those .js files. This actually seems like a somewhat hacky but also flexible long-term solution, without having to mess around with platform-dependent file locations.
See whole answer at my new question: React-native packager configuration - How to include .zip file in bundle?
Partial solution:
Modify android/app/build.gradle, and add
task copyData(type: Copy) {
from '../../firmware/fw.zip'
into 'src/main/assets/raw/firmware'
}
preBuild.dependsOn copyData
This will at least ensure that the file gets copied each time you build, and is then available with ReactNativeFs.readFileAssets('raw/firmware/fw.zip', 'base64'). I'm not entirely thrilled because I still have to have iOS/android dependent code when loading the file, but at least it's loading now.
Tip: watch out for your syntax in gradle. into src/main/assets/myFirmware.zip will create a DIRECTORY called myFirmware.zip, and put your zip file underneath it. Then readFileAssets will still fail because it's finding a directory at your path, not a file.

Can I Copy Over React Native Files Initialized Under One Project Over To Another Separately Initialized Project?

Let's say I initialize a project under react-native init <filename>, installed a bunch of node packages, and added code.
Then separately I initialize a different project under react-viro init <filename>, installed a bunch of node packages, and added code.
If I wanted to combine what I created under react-native init into what I created under react-viro init, is it as simple as copying files over and reinstalling missing node packages into the react-viro project?
Assuming you are working in the ./src folder, every file is independent of iOS or Android as part of the JavaScript bundle.
You can simply copy the .js files over and install the node packages in that project.
You probably should not copy any files that are outside the ./src folder, but I also suspect you wouldn't need to. Files in the Android and iOS folders are rarely touched as they contain operating system config settings and custom modules that you would have wrote in the native languages.
If the file renders JSX, you will be safe to just copy it over and hook it back up.
To state it another way, go into the folder that has node_modules in it. You shouldn't copy anything that is in that folder except additional files that you created. This is where people normally create an src folder and place all their JavaScript. You probably have an index file in there that points to ./src/app.js or you may have an index.ios.js and index.android.js that both point to a ./src/app.js. Anything inside src is safe.
That's my best answer without seeing your folders and files.
If you intend to copy code from one react native project to another, make sure the code you intend to copy is JS and not any native files. Make sure you do register the correct component using AppRegistry. Rest assured you can copy the code from one project to another.
Assuming you have a project at folder
/my-project/android
/my-project/ios
/my-project/src
Copy my-project and paste it at your desired folder like
/new-my-project
Change git origin
git remote set-url origin https://gitlab.com/..../**.git
Open /new-my-project/android in Android Studio, and then rename app/java/com.myproject to com.newmyproject
Go to app/build.grade and change com.myproject to com.newmyproject and sync
Create firebase project and download google-services.json file and add to new-my-project/android/app
Build application, then test application under metro bundler
npx react-native start
Create keystore, test notifications, change base_url_api, test apk etc Android finish now, iOS
Update pods on new-my-project/ios
pod install && pod update
open myproject.xcworkspace
Change bundle identifier to org.reactjs.native.newmyproject, version to 1.0, build to 1 and desired Display name. Let it index completely
Setup in firbase and replace GoogleService-Info.Plist file and Clean build folder in xcode
Go to developer.apple.com and create identifiers, APNS certificates, profiles
Download certificates from keychain and upload to firebase
Build the project in simulator/device and test it.
Done

Build for production Electron (using npm and webpack)

When I build my Electron app for production I still get a node_modules folder with the dependencies. The folder is constituted by:
The dependencies which are installed via package.json I already noticed that I can just delete them from the folder (since their code is inside webpack bundle.js )
ffprobe-static, which actually occupies the largest amount with 40Mb
The nodejs modules such as ajv,deferential, debug, decamelize, etc (158 folders total, while I don't even know most of them, let alone use them directly)
Regarding 2: Is it mandatory to have the binary for ffprobe-static? Can I use ffprobe-static with the ffmpeg.dll given alongside Electron binary?
Regarding 3: Why do I need these and how can I get rid of them? Also, Electron binary already comes with an 18.9Mb node.dll file. Again, can't I use this instead of having again the node_modules?