An example application for using React Native, Reagent and the re-frame application pattern to build a native Android application.
Clojure JavaScript Shell
Latest commit b41ead9 Nov 30, 2015 @mjmeintjes Merge pull request #1 from olivergg/patch-1
Add missing "install" in the npm installation command

readme.org

Re-Frame React Native TicTacToe

An example application for using React Native, Reagent and the re-frame application pattern to build a native Android application.

Based on the React Native TicTacToe example found here.

Main Features:

  • Uses boot to script different build environments
  • Based on re-frame application pattern/library
  • Automatic rebuild and running of unit tests - boot auto-test
  • Live reload while developing (does not reset app state) and fast re-compilation (supports :optimizations :none) - boot fast-build
  • Logging server to display console.log events from the React application running on your mobile phone on the development CLI
  • Fully playable, free 2 player tic-tac-toe game for your Android phone!

Detailed Features

  • Custom React Native Boot tasks to integrate ClojureScript build output with React Packager (allows React Packager to pick up and combine cljs output files, which allows for much faster compilation times)
  • Custom React Native Packager transformer that skips transformation for cljs output files, again increasing the performance of the compilation significantly
  • “Auto mocking” of React Native when testing - allows unit tests to run in browser environment
  • Interface agnostic app layer (tictactoe_app), which can also work with web based React or iOS if needed

Developing

I’ve found the fastest way to develop with this is to use unit tests. The feedback loop is a lot faster than having to run the app on your device.

To start the auto-tester, just run boot auto-test. This will automatically recompile and run your unit tests (defined with deftest). It takes about 2 seconds to recompile and run tests on my machine (VirtualBox VM).

Because of the way re-frame is structured, it is pretty easy testing each part in seperation - see here for a good overview of how to test re-frame apps.

Running the application (development mode)

In this mode, hot reload is enabled, which means that any changes you make in your code will automatically be updated on the device (usually within 2 seconds).

The really cool thing is that your application state does not reset - i.e. you can make a few moves, change the headline, and the headline updates but the game state stays the same.

The disadvantage is that it is really slow. Because the way React Native works, in this mode all code is actually executed within Chrome on your computer and the results are then passed back to the device.

This means you can expect 1 second delays after each action.

Install React Native CLI

npm install -g react-native-cli

Clone this repository

git clone https://github.com/mjmeintjes/cljs-react-native-tictactoe.git

Install React Native

cd app
npm i
react-native android # Don't overwrite index.android.js or .gitignore
react-native upgrade

Edit the build.boot file

Change occurrences “matt-dev” to point to the hostname/ip of your development machine

Start the boot build

boot fast-build Wait for it to finish building, and then wait for the react packager to start up.

Start the React Packager in a separate terminal

You’ll have to have Android SDK installed for this step - see here for instructions and your Android device/emulator connected to adb via USB or Wifi.

Run (cd app && react-native run-android)

Run the app

  • Open Chrome browser, and navigate to http://localhost:8081/debugger-ui
  • For hot-reloading to work, you need to start the Chrome Debugger. To do this, on your Android device, press the hardware menu button (or shake the phone), and select “Debug in Chrome”
  • Place some Tic Tac Toe, against yourself, or a friend!

Building an apk

I haven’t done a lot of work on getting the deployment story sorted out, but for now it should be possible to just boot fast-build, and then follow the instructions here to build the APK. The final output size is about 7.7mb (without any optimizations).

Todo

  • Extract the boot tasks into their own project
  • Split out reagent-native into its own library
  • Split out reagent-native unit testing support into its own library
  • Remove the ugly hack that I currently use to choose between live reloading and fast build modes
  • Custom React Native transformer should be specified using command line arguments to the Packager server, and should just derive from the existing one (instead of copying all the code as it currently does.
  • Add deploy boot task to deploy apk with optimizations set to :simple
  • Add deploy boot task to deploy apk with optimizations set to :advanced? Not sure if this is even worth it.
  • Add support for iOS? Shouldn’t be difficult, but without access to a Mac not possible at the moment?

Acknowledgements/Resources

  • A lot of the work with regards to hot reloading came from decker405.
  • Also got a lot of info from mfikes, chendesheng, Gonzih and nicholaskariniemi.
  • Here’s another great resource with information about ClojureScript and React Native that helped a lot.
  • Several other projects here on GitHub that I can’t find at the moment.