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.
- 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!
- 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
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.
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.
npm install -g react-native-cli
git clone https://github.com/mjmeintjes/cljs-react-native-tictactoe.git
cd app
npm i
react-native android # Don't overwrite index.android.js or .gitignore
react-native upgrade
Change occurrences “matt-dev” to point to the hostname/ip of your development machine
boot fast-build
Wait for it to finish building, and then wait for the react packager to start up.
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)
- 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!
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).
- 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 modesCustom 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?
- 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.