/boot-react-native

Better development experience with ClojureScript and React Native

Primary LanguageJavaScript

Boot React Native

https://img.shields.io/clojars/v/boot-react-native.svg

Provides several tasks that helps integrate ClojureScript with the React Native packager and build process

Note on version 0.3

NOTE: Boot React Native is being prepared for its upcoming 0.3 release. Changes in latest master bring usability improvements as well as compatibility with the current release of React Native, so please try version 0.3. There are also breaking changes; please refer to the release notes for important upgrade notes.

A guide to 0.3 is available at Getting Started with Boot React Native, as well as a Troubleshooting Guide.

Why?

React Native and ClojureScript seem to be made for each other. Unfortunately, out of the box ClojureScript does not play nice with React Native.

Basically, trying to get them to work together leads to the following problems:

  • You have to set up the cljs compiler to use :optimizations :whitespace or higher - this leads to slow compilation (more than 30 seconds after each change on my PC)
  • boot-reload and boot-cljs-repl tasks do not work
  • You have to start up the React Native packager in a separate terminal

This library aims to fix all of the above. It:

  • Allows for builds with :optimizations :none - much faster builds, and 1-2 second rebuilds
  • Allows for integration with other cljs boot tasks - cljs-repl, reload, cljs-test
  • Provides tasks to auto start react native packager
  • Custom transformer for react-native to speed up builds significantly
  • Capture Android and iOS log output and print to command line
  • Run iOS application directly from command line (without starting up xcode)
  • Source map support
  • Experimental support for creating bundle for building distributable app (currently iOS only, needs more testing)

Getting started

To get started, simply add the tasks (before-cljsbuild) to your build pipeline somewhere before (cljs), and (after-cljsbuild) to somewhere after (cljs).

There is an example in the example directory that illustrates this - here’s the main task from the example:

(deftask dev []
  (comp (watch)
        (reload :on-jsload 'mattsum.simple-example.core/on-js-reload
                :port 8079
                )
        (rn/before-cljsbuild)
        (cljs-repl :ip "0.0.0.0")
        (cljs :main "mattsum.simple-example.core")
        (rn/after-cljsbuild :server-url "localhost:8081")
        ))

Features

Hot reloading

Automatically reloads cljs files as you edit them. Better than normal React Native reloading because it keeps your application state, and just changes the behaviour.

Hot reloading works in both Chrome Debug mode and normal mode. To enable reloading, just use boot-reload.

NRepl support

Integrates with normal nrepl process:

  • Setup your build pipeline (see example app)
  • Start your build pipeline (boot dev in example app)
  • In another terminal, connect to repl using boot repl -c
  • Invoke (start-repl) (see boot-cljs-repl)
  • REPL should start up - if it doesn’t, reload the app on your mobile device.

Sourcemap support

Supports Chrome Dev Tools source map mapping for cljs files. To use, simply ensure that source map support is enabled in Chrome, and then select “Debug In Chrome” option in your app. Source maps should automatically then be loaded for cljs files.

Run app in iOS simulator

Add the task run-in-simulator to the end of your build pipeline to automatically run your app in iOS simulator after building.

Print logs to console

Add tasks print-android-log or print-ios-log to your build pipeline to print Android/iOS logs to your command line. Can also run boot print-android-log or boot print-ios-log in a separate terminal to automatically follow the Android/iOS logs.

Limitations

ALPHA quality - task names, api, etc can and probably will still change. Lots of testing still needs to be done. Several additional features are planned.

This has been tested on Android and IOS.

Example App

There is an example app to demonstrate using this plugin.

To start it up:

  • Run npm install inside example/app
  • Run boot dev inside example
  • For Android:
    • Connect device to computer
    • Install app on your phone/emulator (should be connected via adb) - (cd example/app/android && ./gradlew installDebug "$@")
  • For iOS:
    • Open the SimpleExampleApp XCode project and click run.
  • If using watchman you might have to restart it

You can also build a version of the app using an offline (release) bundle. This functionality is still experimental, and has only been tested with iOS at the moment.

  • For iOS:
    • Run boot dist inside example
    • Open the XCode project
    • Open example/app/ios/SimpleExampleApp/AppDelegate.m and find the “bundle location” section. Uncomment Option 2 (offline bundle)
    • Click run

Running tests

The example app has some tests to ensure that reloading and repl support works. It is currently only set-up to work with Android, but it does give a good example of how to automate and write integration tests for React Native.

To run the tests, ensure that your device/emulator is connected to adb (run adb devices), and then run ./test-reloading.sh inside the example directory.

Related projects

Hacking

To hack on boot-react-native, simply:

  • run boot dev in one terminal. This watches and automatically rebuilds the boot task and installs the jar in the local maven repository.
  • In another terminal, run cd example && boot dev to build the example app. This way, changes to the boot task are automatically picked up.

Acknowledgements/Resources

License

Copyright © 2015 Matt Meintjes

Distributed under the Eclipse Public License, the same as Clojure.