Sunday, April 17, 2016

Changing the "Entry JavaScript File" for your React Native iOS App

This article is relevant for: 
- node 5.8.0
- npm 3.7.3
- react-native-cli 0.1.10
it may or may not work for other versions.


So I've entered the world of React Native. I've been spending the last couple weeks working on a React Native Started Project for a Start Up i've working with. There are plenty of starter projects out there for React Native but I needed something that supports a Web App (built using React) and iOS and Android apps as well. The final solution should be able to compile into a Web, iOS and Android with as much code reuse as possible. (Obviously we cant have full code reuse as the UI screens will need to be different across the platforms, but most of the Business Logic can be shared)

As I wrote the Started Project, I wanted to refactor my code so that all my "Entry Point Code Files" reside in the same "src" directory. This makes the Project Structure clean and readable.

Entry Point Code Files as basically the first files that are loaded into the iOS, Android compilers.

So I wanted to have this clean structure:



But when you create a new React Native Application, you will notice that the default scaffold puts the index.ios.js and index.andriod.js files into the root like so:



As I moved these files into my "src" folder and I tried to build and run my iOS app using XCode I got this ugly error:

"Cannot find entry file index.ios.js in any of the roots" Error

I dug around and it seems as though the location of my index.ios.js was hardcoded into a file within the scaffold. I found this unusual and looked for a way to "programmatically" change the location of my file (instead of updating the core scaffold files in the "ios" directory), unfortunately I could not find a solution.

So I hacked the scaffold files to update the starter file location. This is not my preferred method but I had to get it working (If there is a better way to do this then please let me know in the comments below)

So what do you need to do to update the Starter File location for iOS?

1) In your "ios" directory locate the "AppDelegate.m" file which should be in a folder with your app name. For me it was here:



2) In that file, locate the line assigning the "jsCodeLocation" variable and update the location of the file. So change it to be like so (I've basically added the "src" folder to the string):

Click on the image to view a larger version


And we are done!

3) Close your XCode project and reopen it and when you start the app it should now work :)

It's a dirty hack and not my preferred way to so this, but until there is a official clean way to do it, it will have to do.

______________________________________________________________________
Update (25/07/2016):
In projects where I used the above method to move my index.ios.js file to a "src" folder I recently started getting the below error as I wanted to run my app in my iPhone (using local provision profiles to deploy and test my apps on my actual iPhone)

"Cannot find entry file index.ios.js in any of the roots:"... "Command /bin/sh failed with exit code 1"

I dug around and worked out that at times the none_modules/react-native/packager/react-native.xcode.sh file was still referencing the entry file as index.ios.js from the root.

Towards the bottom of this file I had to make the below change to get it working:
$NODE_BINARY "$REACT_NATIVE_DIR/local-cli/cli.js" bundle \ 
--entry-file src/index.ios.js
--platform ios \ --dev $DEV \ 
--bundle-output "$DEST/main.jsbundle" \ 
--assets-dest "$DEST"

This is so Hacky I know! but React Native seems to have all these weird issues. Hopefully it matures soon.

2 comments:

  1. Thanks for your post. This help me to find out solution to fix it. However I try not to change boilerplate code. For now I am going to use the root location to keep index.ios.js file.

    ReplyDelete
  2. But you don't mention how to do it for android too?

    ReplyDelete

Fork me on GitHub