UNPKG

16.8 kBMarkdownView Raw
1# Re-Natal
2### A utility for building ClojureScript-based React Native apps
3Artur Girenko
4[@drapanjanas](https://twitter.com/drapanjanas)
5
6---
7
8Re-Natal is a simple command-line utility that automates most of the process of
9setting up a React Native app running on ClojureScript with [Reagent] + [re-frame](https://github.com/Day8/re-frame), [Om.Next] or [Rum].
10
11This project is a fork of [dmotz/natal](https://github.com/dmotz/natal) by Dan Motzenbecker.
12
13Figwheel support is based on the brilliant solution developed by Will Decker [decker405/figwheel-react-native](https://github.com/decker405/figwheel-react-native),
14which works on both platforms.
15
16
17For more ClojureScript React Native resources visit [cljsrn.org](http://cljsrn.org).
18
19Contributions are very welcome.
20
21## Status
22- Uses [React Native] v0.48.4
23- Reusable codebase between iOS and Android
24- Figwheel used for REPL and live coding
25 - Works in iOS (real device and simulator)
26 - Works in Android (real device and simulators, specifically AVD and Genymotion)
27 - Figwheel REPL can be started from within nREPL
28 - Simultaneous development of iOS and Android apps
29 - Manual reload and automatic hot reload
30 - Custom react-native components supported
31 - Source maps available
32- Supported React wrappers:
33[Reagent], [Om.Next], and [Rum]
34- Support of windows (UWP and WPF) apps
35- [Unified way of using static images of React Native 0.14+](https://facebook.github.io/react-native/docs/images.html) supported
36
37## Compatibility with RN versions
38Current version of re-natal might not work correctly with older versions of React Native
39- use current version of re-natal with React Native >= v0.46
40- use re-natal < v0.5.0 with React Native < v0.46
41
42## Dependencies
43As Re-Natal is an orchestration of many individual tools, there are quite a few dependencies.
44If you've previously done React Native or Clojure development, you should hopefully
45have most installed already. Platform dependencies are listed under their respective tools.
46
47- [npm](https://www.npmjs.com) `>=1.4`
48 - [Node.js](https://nodejs.org) `>=7.1.0`
49- [react-native-cli](https://www.npmjs.com/package/react-native-cli) `>=0.1.7` (install with `npm install -g react-native-cli`)
50- [watchman](https://facebook.github.io/watchman/) `>=4.9.0`
51- [Leiningen](http://leiningen.org) `>=2.5.3`
52 - [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
53
54For iOS development:
55- [Xcode](https://developer.apple.com/xcode) (+ Command Line Tools) `>=6.3`
56 - [OS X](http://www.apple.com/osx) `>=10.10`
57
58## Creating a new project
59
60Before getting started, make sure you have the
61[required dependencies](#dependencies) installed.
62
63Then, install the CLI using npm:
64
65```
66$ npm install -g re-natal
67```
68
69To generate a new app, run `re-natal init` with your app's name as an argument:
70
71```
72$ re-natal init FutureApp
73```
74
75This will generate a project which uses Reagent v0.6.
76You may specify the -i option to choose a specific React wrapper: Om.Next, Reagent v0.6 or Rum:
77
78```
79$ re-natal init FutureApp -i [om-next | reagent6 | rum]
80```
81
82If your app's name is more than a single word, be sure to type it in CamelCase.
83A corresponding hyphenated Clojure namespace will be created.
84
85The init process will take a few minutes — coffee break! If all goes well you should see basic instructions on how to run in iOS simulator.
86
87## Development with Figwheel
88
89Initially the `index.*.js` files are generated with the production profile, ready for deployment.
90However, during development it is better to use the development profile and integrate with Figwheel. Switch to the development profile with:
91
92```
93$ re-natal use-figwheel
94```
95
96This command needs to be run every time you switch to the development profile or specify a development environment (with `use-ios-device` or `use-android-device`).
97
98NOTE: You might need to restart React Native Packager and reload your app.
99
100Start the Figwheel REPL with
101
102```
103$ lein figwheel [ios | android]
104```
105
106If all went well you should see the REPL prompt and changes in source files should be hot-loaded by Figwheel.
107
108#### Starting Figwheel REPL from nREPL
109To start Figwheel from within nREPL session:
110```
111$ lein repl
112```
113Then in the nREPL prompt type:
114```
115user=> (start-figwheel "ios")
116```
117Or, for Android build type:
118```
119user=> (start-figwheel "android")
120```
121Or, for both type:
122```
123user=> (start-figwheel "ios" "android")
124```
125
126## Running the app
127### Note for Linux users
128On Linux, the React Native Packager has to be started manually with
129```
130react-native start
131```
132See [here](#running-on-linux) for more details.
133
134### iOS
135#### Using iOS simulator
136
137```
138re-natal use-ios-device simulator
139react-native run-ios
140```
141
142#### Using real iOS device
143
144```
145re-natal use-ios-device real
146```
147
148If this doesn't correctly detect your computer's IP you can pass your IP address explicitly: `re-natal use-ios-device <IP address>`.
149And then run
150
151```
152react-native run-ios
153```
154
155#### Switching between iOS devices
156Run `use-ios-device` to configure device type you want to use in development:
157```
158$ re-natal use-ios-device <real|simulator>
159$ re-natal use-figwheel
160$ lein figwheel ios
161```
162
163---
164
165### Android
166
167#### Using Android Virtual Device (AVD)
168[Set up a virtual device in AVD](https://developer.android.com/studio/run/managing-avds.html). Start the virtual device then run
169```
170$ re-natal use-android-device avd
171$ re-natal use-figwheel
172$ lein figwheel android
173$ react-native run-android
174```
175
176#### Using Genymotion simulator
177Set up and start the Genymotion simulator then run
178```
179$ re-natal use-android-device genymotion
180$ re-natal use-figwheel
181$ lein figwheel android
182$ react-native run-android
183```
184
185#### Using real Android device
186To run figwheel with real Android device please read [Running on Device](https://facebook.github.io/react-native/docs/running-on-device-android.html#content).
187To make it work on a USB connected device I also had to run:
188```
189$ adb reverse tcp:8081 tcp:8081
190$ adb reverse tcp:3449 tcp:3449
191```
192Then:
193```
194$ re-natal use-android-device real
195$ re-natal use-figwheel
196$ lein figwheel android
197$ react-native run-android
198```
199
200#### Switching between Android devices
201Run `use-android-device` to configure device type you want to use in development:
202```
203$ re-natal use-android-device <real|genymotion|avd>
204$ re-natal use-figwheel
205$ lein figwheel android
206```
207
208### Developing iOS and Android apps simultaneously
209```
210$ re-natal use-figwheel
211$ lein figwheel ios android
212```
213
214---
215
216### Using external React Native Components
217
218Lets say you have installed an external library from npm like this:
219```
220$ npm i some-library --save
221```
222
223And you want to use a component called 'some-library/Component':
224```clojure
225(def Component (js/require "some-library/Component"))
226```
227This works fine when you do `lein prod-build` and run your app.
228
229The React Native packager statically scans for all calls to `require` and prepares the required
230code to be available at runtime. But, dynamically loaded (by Figwheel) code bypasses this scan
231and therefore requiring the custom component fails.
232
233In re-natal this is solved by adding all dependencies in index.*.js file which is scanned by React Native packager.
234
235#### Using auto-require
236
237To enable auto-require feature you have to run command:
238```
239$ re-natal enable-auto-require
240```
241From now on, command `use-figwheel` will scan for all required modules and generate index.*.js with all required dependencies.
242You will have to re-run `use-figwheel` command every time you use new modules via `(js/require "...")`
243
244This feature is available since re-natal@0.7.0
245
246#### Manually registering dependencies with use-component command
247
248You can register a single dependency manually by running `require` command:
249```
250$ re-natal require some-library/Component
251```
252or for a platform-specific component use the optional platform parameter:
253```
254$ re-natal require some-library/ComponentIOS ios
255```
256Then, regenerate index.*.js files:
257```
258$ re-natal use-figwheel
259```
260Lastly, you will have to restart the packager and reload your app.
261
262NOTE: If you mistyped something, or no longer use the component and would like to remove it,
263 manually open `.re-natal` and fix it there (it's just a list of names in JSON format, so the process should be straight forward).
264
265#### Scanning for dependencies with require-all command
266
267If you have used new modules in your code you can run:
268```
269$ re-natal require-all
270```
271This will scan your code for `(js/require ...)` calls and add new required modules automatically.
272After this, you still need to run `use-figwheel` command to regenerate index.*.js files.
273
274## REPL
275You have to reload your app, and should see the REPL coming up with the prompt.
276
277At the REPL prompt, try loading your app's namespace:
278
279```clojure
280(in-ns 'future-app.ios.core)
281```
282
283Changes you make via the REPL or by changing your `.cljs` files should appear live
284in the simulator.
285
286Try this command as an example:
287
288```clojure
289(dispatch [:set-greeting "Hello Native World!"])
290```
291
292## Running on Linux
293In addition to the instructions above on Linux you might need to
294start React Native packager manually with command `react-native start`.
295This was reported in [#3](https://github.com/drapanjanas/re-natal/issues/3)
296
297See this [tutorial](https://gadfly361.github.io/gadfly-blog/2016-11-13-clean-install-of-ubuntu-to-re-natal.html) on how to set up and run re-natal on a clean install of Ubuntu.
298
299See also [Linux and Windows support](https://facebook.github.io/react-native/docs/linux-windows-support.html)
300in React Native docs.
301
302## Support of UWP and WPF apps (using react-native-windows)
303
304To start new project with UWP app:
305```
306$ re-natal init FutureApp -u
307```
308
309To start new project with WPF app:
310```
311$ re-natal init FutureApp -w
312```
313
314Existing projects can also add windows platforms any time using commands:
315```
316$ re-natal add-platform windows
317
318or
319
320$ re-natal add-platform wpf
321```
322Note: for projects generated with re-natal version prior to 0.4.0 additional windows builds will not be added automatically to `project.clj`.
323Workaround is to generate fresh windows project and copy-paste additional builds manually.
324
325## Production build
326Do this with command:
327```
328$ lein prod-build
329```
330Follow the [React Native documentation](https://facebook.github.io/react-native/docs/signed-apk-android.html) to proceed with the release.
331
332#### Advanced CLJS compilation
333```
334$ lein advanced-build
335```
336The ReactNative externs are provided by [react-native-externs](https://github.com/mfikes/react-native-externs)
337Other library externs needs to be added manually to advanced profile in project.clj
338
339## Static Images
340Since version 0.14 React Native supports a [unified way of referencing static images](https://facebook.github.io/react-native/docs/images.html)
341
342In Re-Natal skeleton images are stored in "images" directory. Place your images there and reference them from cljs code:
343```clojure
344(def my-img (js/require "./images/my-img.png"))
345```
346#### Adding an image during development
347When you have dropped a new image to "images" dir, you need to restart React Native packager and re-run command:
348```
349$ re-natal use-figwheel
350```
351This is needed to regenerate index.\*.js files which includes `require` calls to all local images.
352After this you can use a new image in your cljs code.
353
354## Upgrading existing Re-Natal project
355
356#### Upgrading React Native version
357
358To upgrade React Native to newer version please follow the official
359[Upgrading](https://facebook.github.io/react-native/docs/upgrading.html) guide of React Native.
360Re-Natal makes almost no changes to the files generated by react-native so the official guide should be valid.
361
362#### Upgrading Re-Natal CLI version
363Do this if you want to use newer version of re-natal.
364
365Commit or backup your current project, so that you can restore it in case of any problem ;)
366
367Upgrade re-natal npm package
368```
369$ npm upgrade -g re-natal
370```
371In root directory of your project run
372```
373$ re-natal upgrade
374```
375This will overwrite only some files which usually contain fixes in newer versions of re-natal,
376and are unlikely to be changed by the user. No checks are done, these files are just overwritten:
377 - files in /env directory
378 - figwheel-bridge.js
379
380Then to continue development using figwheel
381```
382$ re-natal use-figwheel
383```
384
385## Enabling source maps when debugging in chrome
386To make source maps available in "Debug in Chrome" mode re-natal patches
387the react native packager to serve \*.map files from file system and generate only index.\*.map file.
388To achieve this [this line](https://github.com/facebook/react-native/blob/master/packager/react-packager/src/Server/index.js#L413)
389of file "node_modules/react-native/packager/react-packager/src/Server/index.js" is modified to match only index.\*.map
390
391To do this run: `re-natal enable-source-maps` and restart packager.
392
393You can undo this any time by deleting `node_modules` and running `re-natal deps`
394
395## Example Apps
396* [Luno](https://github.com/alwx/luno-react-native) is a demo mobile application written in ClojureScript.
397* [Re-Navigate](https://github.com/vikeri/re-navigate) example of using new Navigation component [NavigationExperimental](https://github.com/ericvicenti/navigation-rfc)
398* [Showcase of iOS navigation](https://github.com/seantempesta/om-next-react-native-router-flux) with react-native-router-flux and Om.Next
399* [Catlantis](https://github.com/madvas/catlantis) is a funny demo application about cats
400* [Lymchat](https://github.com/tiensonqin/lymchat) App to learn different cultures. Lym is available in [App Store](https://itunes.apple.com/us/app/lym/id1134985541?ls=1&mt=8).
401* [Status](https://status.im) ([Github](https://github.com/status-im/status-react/)): a web3 browser, messenger, and gateway to a decentralised world of Ethereum. re-natal + re-frame + cljs + golang
402* [React Native TodoMVC](https://github.com/TashaGospel/todo-mvc-re-natal) is a mobile application which attempts to implement TodoMVC in Clojurescript and React Native.
403
404## Tips
405- Having `rlwrap` installed is optional but highly recommended since it makes
406the REPL a much nicer experience with arrow keys.
407
408- Running multiple React Native apps at once can cause problems with the React
409Packager so try to avoid doing so.
410
411- You can launch your app on the simulator without opening Xcode by running
412`react-native run-ios` in your app's root directory (since RN 0.19.0).
413
414- To change advanced settings run `re-natal xcode` to quickly open the Xcode project.
415
416- If you have customized project layout and `re-natal upgrade` does not fit you well,
417then these commands might be useful for you:
418 * `re-natal copy-figwheel-bridge` - just copies figwheel-bridge.js from current re-natal
419
420## Local Development of Re-Natal
421
422If you would like to run any of this on your local environment first clone the code to an appropriate place on your machine and install dependencies
423
424```
425$ git clone https://github.com/drapanjanas/re-natal.git
426$ cd re-natal
427$ npm install
428```
429
430To test any changes made to re-natal, cd to an already existing project or a brand new dummy project:
431
432```
433$ cd ../already-existing
434```
435
436and run the re-natal command line like so
437
438```
439$ node ../re-natal/index.js
440
441 Usage: re-natal [options] [command]
442
443
444 Commands:
445
446 init [options] <name> create a new ClojureScript React Native project
447 upgrade upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)
448 add-platform <platform> adds additional app platform: 'windows' - UWP app, 'wpf' - WPF app
449 xcode open Xcode project
450 deps install all dependencies for the project
451 use-figwheel generate index.*.js for development with figwheel
452 use-android-device <type> sets up the host for android device type: 'real' - localhost, 'avd' - 10.0.2.2, 'genymotion' - 10.0.3.2, IP
453 use-ios-device <type> sets up the host for ios device type: 'simulator' - localhost, 'real' - auto detect IP on eth0, IP
454 use-component <name> [<platform>] configures a custom component to work with figwheel. name is the value you pass to (js/require) function.
455 enable-source-maps patches RN packager to server *.map files from filesystem, so that chrome can download them.
456 copy-figwheel-bridge copy figwheel-bridge.js into project
457
458 Options:
459
460 -h, --help output usage information
461 -V, --version output the version number
462```
463
464You can then run any of the commands manually.
465
466[React Native]: https://facebook.github.io/react-native
467[Reagent]: https://github.com/reagent-project/reagent
468[Om.Next]: https://github.com/omcljs/om/wiki/Quick-Start-(om.next)
469[Rum]: https://github.com/tonsky/rum