commit
303dea9e28
61
README.md
61
README.md
|
@ -19,7 +19,7 @@ For more ClojureScript React Native resources visit [cljsrn.org](http://cljsrn.o
|
|||
Contributions are very welcome.
|
||||
|
||||
## Status
|
||||
- Uses [React Native] v0.42.0
|
||||
- Uses [React Native] v0.43.4
|
||||
- Reusable codebase between iOS and Android
|
||||
- Figwheel used for REPL and live coding
|
||||
- Works in iOS (real device and simulator)
|
||||
|
@ -31,6 +31,7 @@ Contributions are very welcome.
|
|||
- Source maps available
|
||||
- Supported React wrappers:
|
||||
[Reagent], [Om.Next], and [Rum]
|
||||
- Support of windows (UWP and WPF) apps
|
||||
- [Unified way of using static images of React Native 0.14+](https://facebook.github.io/react-native/docs/images.html) supported
|
||||
|
||||
## Dependencies
|
||||
|
@ -65,7 +66,7 @@ To generate a new app, run `re-natal init` with your app's name as an argument:
|
|||
$ re-natal init FutureApp
|
||||
```
|
||||
|
||||
This will generate a project which uses Reagent v0.5.1.
|
||||
This will generate a project which uses Reagent v0.6.
|
||||
You may specify the -i option to choose a specific React wrapper: Om.Next, Reagent v0.6 or Rum:
|
||||
|
||||
```
|
||||
|
@ -239,18 +240,6 @@ Lastly, you will have to restart the packager and reload your app.
|
|||
NOTE: If you mistyped something, or no longer use the component and would like to remove it,
|
||||
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).
|
||||
|
||||
---
|
||||
|
||||
### Faster Figwheel hot reloading
|
||||
Since version 0.22 React Native supports Hot Module Reload. But at least for now, this feature is redundant because we have Figwheel.
|
||||
|
||||
It looks like Figwheel reloads are faster if Hot Moduler Reload is OFF.
|
||||
Also, the packager is not necessary to watch for changed files - Figwheel does that (except on Linux).
|
||||
|
||||
Two things you can do:
|
||||
|
||||
1. Turn off HMR from the development menu.
|
||||
2. Start the packager with option `--nonPersistent`. You can use `npm start` for that.
|
||||
|
||||
## REPL
|
||||
You have to reload your app, and should see the REPL coming up with the prompt.
|
||||
|
@ -280,6 +269,29 @@ See this [tutorial](https://gadfly361.github.io/gadfly-blog/2016-11-13-clean-ins
|
|||
See also [Linux and Windows support](https://facebook.github.io/react-native/docs/linux-windows-support.html)
|
||||
in React Native docs.
|
||||
|
||||
## Support of UWP and WPF apps (using react-native-windows)
|
||||
|
||||
To start new project with UWP app:
|
||||
```
|
||||
$ re-natal init FutureApp -u
|
||||
```
|
||||
|
||||
To start new project with WPF app:
|
||||
```
|
||||
$ re-natal init FutureApp -w
|
||||
```
|
||||
|
||||
Existing projects can also add windows platforms any time using commands:
|
||||
```
|
||||
$ re-natal add-platform windows
|
||||
|
||||
or
|
||||
|
||||
$ re-natal add-platform wpf
|
||||
```
|
||||
Note: for projects generated with re-natal version prior to 0.4.0 additional windows builds will not be added automatically to `project.clj`.
|
||||
Workaround is to generate fresh windows project and copy-paste additional builds manually.
|
||||
|
||||
## Production build
|
||||
Do this with command:
|
||||
```
|
||||
|
@ -394,16 +406,17 @@ $ node ../re-natal/index.js
|
|||
|
||||
Commands:
|
||||
|
||||
init [options] <name> create a new ClojureScript React Native project
|
||||
upgrade upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)
|
||||
xcode open Xcode project
|
||||
deps install all dependencies for the project
|
||||
use-figwheel generate index.ios.js and index.android.js for development with figwheel
|
||||
use-android-device <type> sets up the host for android device type: 'real' - localhost, 'avd' - 10.0.2.2, 'genymotion' - 10.0.3.2
|
||||
use-ios-device <type> sets up the host for ios device type: 'simulator' - localhost, 'real' - auto detect IP on eth0, IP
|
||||
use-component <name> configures a custom component to work with figwheel. name is the value you pass to (js/require) function.
|
||||
enable-source-maps patches RN packager to server *.map files from filesystem, so that chrome can download them.
|
||||
copy-figwheel-bridge copy figwheel-bridge.js into project
|
||||
init [options] <name> create a new ClojureScript React Native project
|
||||
upgrade upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)
|
||||
add-platform <platform> adds additional app platform: 'windows' - UWP app, 'wpf' - WPF app
|
||||
xcode open Xcode project
|
||||
deps install all dependencies for the project
|
||||
use-figwheel generate index.*.js for development with figwheel
|
||||
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
|
||||
use-ios-device <type> sets up the host for ios device type: 'simulator' - localhost, 'real' - auto detect IP on eth0, IP
|
||||
use-component <name> [<platform>] configures a custom component to work with figwheel. name is the value you pass to (js/require) function.
|
||||
enable-source-maps patches RN packager to server *.map files from filesystem, so that chrome can download them.
|
||||
copy-figwheel-bridge copy figwheel-bridge.js into project
|
||||
|
||||
Options:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "re-natal",
|
||||
"version": "0.3.7",
|
||||
"version": "0.4.0",
|
||||
"description": "Bootstrap ClojureScript React Native apps with reagent and re-frame for iOS and Android",
|
||||
"main": "index.js",
|
||||
"author": "Artur Girenko <a.girenko@gmail.com>",
|
||||
|
|
120
re-natal.coffee
120
re-natal.coffee
|
@ -36,7 +36,8 @@ ipAddressRx = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/i
|
|||
figwheelUrlRx = /ws:\/\/[0-9a-zA-Z\.]*:/g
|
||||
appDelegateRx = /http:\/\/[^:]+/g
|
||||
debugHostRx = /host\s+=\s+@".*";/g
|
||||
rnVersion = '0.42.0'
|
||||
rnVersion = '0.43.4'
|
||||
rnWinVersion = '0.42.0'
|
||||
rnPackagerPort = 8081
|
||||
process.title = 're-natal'
|
||||
interfaceConf =
|
||||
|
@ -55,8 +56,8 @@ interfaceConf =
|
|||
sources:
|
||||
common: ["events.cljs", "subs.cljs", "db.cljs"]
|
||||
other: [["reagent_dom.cljs","reagent/dom.cljs"], ["reagent_dom_server.cljs","reagent/dom/server.cljs"]]
|
||||
deps: ['[reagent "0.6.0" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server]]'
|
||||
'[re-frame "0.8.0"]']
|
||||
deps: ['[reagent "0.6.1" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server]]'
|
||||
'[re-frame "0.9.2"]']
|
||||
shims: ["cljsjs.react", "cljsjs.react.dom", "cljsjs.react.dom.server"]
|
||||
sampleCommandNs: '(in-ns \'$PROJECT_NAME_HYPHENATED$.ios.core)'
|
||||
sampleCommand: '(dispatch [:set-greeting "Hello Native World!"])'
|
||||
|
@ -264,7 +265,7 @@ configureDevHostForAndroidDevice = (deviceType) ->
|
|||
try
|
||||
devHost = resolveAndroidDevHost(deviceType)
|
||||
config = readConfig()
|
||||
config.android.host = devHost
|
||||
config.platforms.android.host = devHost
|
||||
writeConfig(config)
|
||||
log "Please run: re-natal use-figwheel to take effect."
|
||||
catch {message}
|
||||
|
@ -285,7 +286,7 @@ configureDevHostForIosDevice = (deviceType) ->
|
|||
try
|
||||
devHost = resolveIosDevHost(deviceType)
|
||||
config = readConfig()
|
||||
config.ios.host = devHost
|
||||
config.platforms.ios.host = devHost
|
||||
writeConfig(config)
|
||||
log "Please run: re-natal use-figwheel to take effect."
|
||||
catch {message}
|
||||
|
@ -397,20 +398,34 @@ copyProjectClj = (interfaceName, projNameHyph) ->
|
|||
edit 'project.clj', [[projNameHyphRx, projNameHyph], [interfaceDepsRx, deps], [platformCleanRx, cleans.join(' ')], [devProfilesRx, devProfiles.join("\n")], [prodProfilesRx, prodProfiles.join("\n")]]
|
||||
|
||||
updateProjectClj = (platform) ->
|
||||
proj = readFile('project.clj')
|
||||
|
||||
cleans = []
|
||||
cleans.push "\"index.#{platform}.js\""
|
||||
cleans.push platformCleanId
|
||||
|
||||
if !proj.match(platformCleanRx)
|
||||
log "Manual update of project.clj required: add clean targets:"
|
||||
log "#{cleans.join(' ')}", "red"
|
||||
|
||||
devProfileTemplate = readFile "#{resources}/dev.profile"
|
||||
devProfiles = []
|
||||
devProfiles.push devProfileTemplate.replace(platformRx, platform)
|
||||
devProfiles.push devProfilesId
|
||||
|
||||
if !proj.match(devProfilesRx)
|
||||
log "Manual update of project.clj required: add new build to dev profile:"
|
||||
log "#{devProfiles.join('\n')}", "red"
|
||||
|
||||
prodProfileTemplate = readFile "#{resources}/prod.profile"
|
||||
prodProfiles = []
|
||||
prodProfiles.push prodProfileTemplate.replace(platformRx, platform)
|
||||
prodProfiles.push prodProfilesId
|
||||
|
||||
if !proj.match(prodProfilesRx)
|
||||
log "Manual update of project.clj required: add new build to prod profile:"
|
||||
log "#{prodProfiles.join('\n')}", "red"
|
||||
|
||||
edit 'project.clj', [[platformCleanRx, cleans.join(' ')], [devProfilesRx, devProfiles.join("\n")], [prodProfilesRx, prodProfiles.join("\n")]]
|
||||
|
||||
init = (interfaceName, projName) ->
|
||||
|
@ -461,7 +476,7 @@ init = (interfaceName, projName) ->
|
|||
'babel-plugin-transform-es2015-block-scoping': '6.15.0'
|
||||
|
||||
if 'windows' in platforms || 'wpf' in platforms
|
||||
pkg.dependencies['react-native-windows'] = rnVersion
|
||||
pkg.dependencies['react-native-windows'] = rnWinVersion
|
||||
|
||||
fs.writeFileSync 'package.json', JSON.stringify pkg, null, 2
|
||||
|
||||
|
@ -527,53 +542,59 @@ init = (interfaceName, projName) ->
|
|||
message
|
||||
|
||||
addPlatform = (platform) ->
|
||||
config = readConfig()
|
||||
platforms = Object.keys config.platforms
|
||||
try
|
||||
if !(platform of platformMeta)
|
||||
throw new Error "Unknown platform [#{platform}]"
|
||||
|
||||
if platform in platforms
|
||||
log "A project for a #{platformMeta[platform].name} app already exists"
|
||||
else
|
||||
interfaceName = config.interface
|
||||
projName = config.name
|
||||
projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase()
|
||||
projNameUs = toUnderscored projName
|
||||
config = readConfig()
|
||||
platforms = Object.keys config.platforms
|
||||
|
||||
log "Preparing for #{platformMeta[platform].name} app."
|
||||
if platform in platforms
|
||||
throw new Error "A project for a #{platformMeta[platform].name} app already exists"
|
||||
else
|
||||
interfaceName = config.interface
|
||||
projName = config.name
|
||||
projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase()
|
||||
projNameUs = toUnderscored projName
|
||||
|
||||
updateProjectClj(platform)
|
||||
copySrcFilesForPlatform(platform, interfaceName, projName, projNameUs, projNameHyph)
|
||||
copyDevEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.dev, "localhost")
|
||||
copyProdEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.prod)
|
||||
log "Preparing for #{platformMeta[platform].name} app."
|
||||
|
||||
pkg = JSON.parse readFile 'package.json'
|
||||
|
||||
unless 'react-native-windows' in pkg.dependencies
|
||||
pkg.dependencies['react-native-windows'] = rnVersion
|
||||
fs.writeFileSync 'package.json', JSON.stringify pkg, null, 2
|
||||
exec 'npm i'
|
||||
updateProjectClj(platform)
|
||||
copySrcFilesForPlatform(platform, interfaceName, projName, projNameUs, projNameHyph)
|
||||
copyDevEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.dev, "localhost")
|
||||
copyProdEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.prod)
|
||||
|
||||
if platform is 'windows'
|
||||
log 'Creating React Native UWP project.'
|
||||
exec "node -e
|
||||
\"require('react-native-windows/local-cli/generate-windows')('.', '#{projName}', '#{projName}')\"
|
||||
"
|
||||
pkg = JSON.parse readFile 'package.json'
|
||||
|
||||
if platform is 'wpf'
|
||||
log 'Creating React Native WPF project.'
|
||||
exec "node -e
|
||||
\"require('react-native-windows/local-cli/generate-wpf')('.', '#{projName}', '#{projName}')\"
|
||||
"
|
||||
unless 'react-native-windows' in pkg.dependencies
|
||||
pkg.dependencies['react-native-windows'] = rnWinVersion
|
||||
fs.writeFileSync 'package.json', JSON.stringify pkg, null, 2
|
||||
exec 'npm i'
|
||||
|
||||
fs.appendFileSync(".gitignore", "\n\nindex.#{platform}.js\n")
|
||||
if platform is 'windows'
|
||||
log 'Creating React Native UWP project.'
|
||||
exec "node -e
|
||||
\"require('react-native-windows/local-cli/generate-windows')('.', '#{projName}', '#{projName}')\"
|
||||
"
|
||||
|
||||
config.platforms[platform] =
|
||||
host: "localhost"
|
||||
modules: []
|
||||
if platform is 'wpf'
|
||||
log 'Creating React Native WPF project.'
|
||||
exec "node -e
|
||||
\"require('react-native-windows/local-cli/generate-wpf')('.', '#{projName}', '#{projName}')\"
|
||||
"
|
||||
|
||||
writeConfig(config)
|
||||
fs.appendFileSync(".gitignore", "\n\nindex.#{platform}.js\n")
|
||||
|
||||
log 'Compiling ClojureScript'
|
||||
exec 'lein prod-build'
|
||||
config.platforms[platform] =
|
||||
host: "localhost"
|
||||
modules: []
|
||||
|
||||
writeConfig(config)
|
||||
|
||||
log 'Compiling ClojureScript'
|
||||
exec 'lein prod-build'
|
||||
catch {message}
|
||||
logErr message
|
||||
|
||||
openXcode = (name) ->
|
||||
try
|
||||
|
@ -761,15 +782,10 @@ cli.command 'upgrade'
|
|||
.action ->
|
||||
doUpgrade readConfig(false)
|
||||
|
||||
cli.command 'windows'
|
||||
.description 'add project for UWP app'
|
||||
.action ->
|
||||
addPlatform('windows')
|
||||
|
||||
cli.command 'wpf'
|
||||
.description 'add project for WPF app'
|
||||
.action ->
|
||||
addPlatform('wpf')
|
||||
cli.command 'add-platform <platform>'
|
||||
.description 'adds additional app platform: \'windows\' - UWP app, \'wpf\' - WPF app'
|
||||
.action (platform) ->
|
||||
addPlatform(platform)
|
||||
|
||||
cli.command 'xcode'
|
||||
.description 'open Xcode project'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns ^:figwheel-no-load env.$PLATFORM$.main
|
||||
(:require [reagent.core :as r]
|
||||
[re-frame.core :refer [clear-subscription-cache!]]
|
||||
[$PROJECT_NAME_HYPHENATED$.$PLATFORM$.core :as core]
|
||||
[figwheel.client :as figwheel :include-macros true]))
|
||||
|
||||
|
@ -9,9 +10,13 @@
|
|||
(defn reloader [] @cnt [core/app-root])
|
||||
(def root-el (r/as-element [reloader]))
|
||||
|
||||
(defn force-reload! []
|
||||
(clear-subscription-cache!)
|
||||
(swap! cnt inc))
|
||||
|
||||
(figwheel/watch-and-reload
|
||||
:websocket-url "ws://$DEV_HOST$:3449/figwheel-ws"
|
||||
:heads-up-display false
|
||||
:jsload-callback #(swap! cnt inc))
|
||||
:jsload-callback force-reload!)
|
||||
|
||||
(core/init)
|
|
@ -220,7 +220,7 @@ function loadApp(platform, devHost, onLoadCb) {
|
|||
// seriously React packager? why.
|
||||
var googreq = goog.require;
|
||||
|
||||
googreq('figwheel.connect.' + platform);
|
||||
googreq('figwheel.connect.build_' + platform);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.9.0-alpha10"]
|
||||
[org.clojure/clojurescript "1.9.198"]
|
||||
:dependencies [[org.clojure/clojure "1.9.0-alpha16"]
|
||||
[org.clojure/clojurescript "1.9.521"]
|
||||
$INTERFACE_DEPS$]
|
||||
:plugins [[lein-cljsbuild "1.1.4"]
|
||||
[lein-figwheel "0.5.8"]]
|
||||
[lein-figwheel "0.5.10"]]
|
||||
:clean-targets ["target/" #_($PLATFORM_CLEAN$)]
|
||||
:aliases {"prod-build" ^{:doc "Recompile code with prod profile."}
|
||||
["do" "clean"
|
||||
["with-profile" "prod" "cljsbuild" "once"]]}
|
||||
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.8"]
|
||||
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.10"]
|
||||
[com.cemerick/piggieback "0.2.1"]]
|
||||
:source-paths ["src" "env/dev"]
|
||||
:cljsbuild {:builds [
|
||||
|
|
Loading…
Reference in New Issue