The fastest way a ClojureScript coder can get started with React Native. Prove me wrong.
This is an example project using: shadow-cljs, React Native, Expo, Reagent, and re-frame.
Here follows instructions for getting started either using Calva or the command line or, and assuming you have stuff like XCode, or whatever is the Android equivalents, installed:
Open the project in VS Code. Then:
- In a Terminal pane, execute
npm install -g expo-cli
, thenyarn
and wait for it to finish. - Start build task Watch CLJS and wait for it to build the project.
- Start build task Start Expo and wait for it to fire up Expo DevTools in your browser.
- Start the app on your phone or in a simulator or in browser.
- In the Expo settings for your app (shake or force touch with two fingers), disable Live Reloadinhg and Hot Reloading. (Don't worry, shadow-cljs will take care of hot reloading for you, in the most beautiful way.)
- Connect Calva to the shadow-cljs app (
ctrl+alt+c c
) and choose to connect the:app
build. - Hack away!
$ npm install -g expo-cli
$ yarn
$ shadow-cljs watch app
# wait for first compile to finish or expo gets confused
# on another terminal tab/window:
$ yarn start
This will run Expo DevTools at http://localhost:19002/
To run the app in browser using expo-web (react-native-web), press w
in the same terminal after expo devtools is started.
This should open the app automatically on your browser after the web version is built. If it does not open automatically, open http://localhost:19006/ manually on your browser.
Note that you can also run the following instead of yarn start
to run the app in browser:
# same as expo start --web
$ yarn web
# or
# same as expo start --web-only
$ yarn web-only
Then use your editor of choice to hook up the REPL and such.
Once the app is deployed and opened in phone/simulator/emulator/browser, connect to the nrepl on port 9000 and run the following:
(shadow/nrepl-select :app)
(js/alert "Hello from Repl")
A production build invloves first asking shadow-cljs to build a relase, then to ask Expo to work in Production Mode.
NB: Currently there's a bug in the metro bundler that causes release builds to fail in Production Mode. This project includes a way to patch it (nicked from here). Patch by executing: patch node_modules/metro/src/JSTransformer/worker.js ./etc/metro-bundler.patch
- Kill the watch and expo tasks.
- Execute
shadow-cljs release app
- Start the expo task (as per above)
- Enable Production mode.
- Start the app.
If you get complaints about Module HMRClient is not a registered callable module*, you probably have Hot reloading enabled. Disable it and try again.
(This project is built from this example of his: https://github.com/thheller/reagent-expo)
The :app
build will create an app/index.js
. In release
mode that is the only file needed. In dev mode the app
directory will contain many more .js
files.
:init-fn
is called after all files are loaded and in the case of expo
must render something synchronously as it will otherwise complain about a missing root component. The shadow.expo/render-root
takes care of registration and setup.
You should disable the expo
live reload stuff and let shadow-cljs
handle that instead as they will otherwise interfere with each other.
Source maps don't seem to work properly. metro
propably doesn't read input source maps when converting sources as things are correctly mapped to the source .js files but not their sources.
Initial load in dev is quite slow since metro
processes the generated .js
files.
reagent.core
loads reagent.dom
which will load react-dom
which we don't have or need. Including the src/main/reagent/dom.cljs
to create an empty shell. Copied from re-natal.