Merge pull request #111 from drapanjanas/0.4.0-rc

0.4.0-rc
This commit is contained in:
Artūr Girenko 2017-05-01 13:48:01 +02:00 committed by GitHub
commit 303dea9e28
6 changed files with 117 additions and 83 deletions

View File

@ -19,7 +19,7 @@ For more ClojureScript React Native resources visit [cljsrn.org](http://cljsrn.o
Contributions are very welcome. Contributions are very welcome.
## Status ## Status
- Uses [React Native] v0.42.0 - Uses [React Native] v0.43.4
- Reusable codebase between iOS and Android - Reusable codebase between iOS and Android
- Figwheel used for REPL and live coding - Figwheel used for REPL and live coding
- Works in iOS (real device and simulator) - Works in iOS (real device and simulator)
@ -31,6 +31,7 @@ Contributions are very welcome.
- Source maps available - Source maps available
- Supported React wrappers: - Supported React wrappers:
[Reagent], [Om.Next], and [Rum] [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 - [Unified way of using static images of React Native 0.14+](https://facebook.github.io/react-native/docs/images.html) supported
## Dependencies ## 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 $ 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: 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, 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). 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 ## REPL
You have to reload your app, and should see the REPL coming up with the prompt. 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) See also [Linux and Windows support](https://facebook.github.io/react-native/docs/linux-windows-support.html)
in React Native docs. 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 ## Production build
Do this with command: Do this with command:
``` ```
@ -394,16 +406,17 @@ $ node ../re-natal/index.js
Commands: Commands:
init [options] <name> create a new ClojureScript React Native 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) 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 add-platform <platform> adds additional app platform: 'windows' - UWP app, 'wpf' - WPF app
deps install all dependencies for the project xcode open Xcode project
use-figwheel generate index.ios.js and index.android.js for development with figwheel deps install all dependencies for the project
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-figwheel generate index.*.js for development with figwheel
use-ios-device <type> sets up the host for ios device type: 'simulator' - localhost, 'real' - auto detect IP on eth0, IP 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-component <name> configures a custom component to work with figwheel. name is the value you pass to (js/require) function. use-ios-device <type> sets up the host for ios device type: 'simulator' - localhost, 'real' - auto detect IP on eth0, IP
enable-source-maps patches RN packager to server *.map files from filesystem, so that chrome can download them. use-component <name> [<platform>] configures a custom component to work with figwheel. name is the value you pass to (js/require) function.
copy-figwheel-bridge copy figwheel-bridge.js into project 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: Options:

View File

@ -1,6 +1,6 @@
{ {
"name": "re-natal", "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", "description": "Bootstrap ClojureScript React Native apps with reagent and re-frame for iOS and Android",
"main": "index.js", "main": "index.js",
"author": "Artur Girenko <a.girenko@gmail.com>", "author": "Artur Girenko <a.girenko@gmail.com>",

View File

@ -36,7 +36,8 @@ ipAddressRx = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/i
figwheelUrlRx = /ws:\/\/[0-9a-zA-Z\.]*:/g figwheelUrlRx = /ws:\/\/[0-9a-zA-Z\.]*:/g
appDelegateRx = /http:\/\/[^:]+/g appDelegateRx = /http:\/\/[^:]+/g
debugHostRx = /host\s+=\s+@".*";/g debugHostRx = /host\s+=\s+@".*";/g
rnVersion = '0.42.0' rnVersion = '0.43.4'
rnWinVersion = '0.42.0'
rnPackagerPort = 8081 rnPackagerPort = 8081
process.title = 're-natal' process.title = 're-natal'
interfaceConf = interfaceConf =
@ -55,8 +56,8 @@ interfaceConf =
sources: sources:
common: ["events.cljs", "subs.cljs", "db.cljs"] common: ["events.cljs", "subs.cljs", "db.cljs"]
other: [["reagent_dom.cljs","reagent/dom.cljs"], ["reagent_dom_server.cljs","reagent/dom/server.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]]' deps: ['[reagent "0.6.1" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server]]'
'[re-frame "0.8.0"]'] '[re-frame "0.9.2"]']
shims: ["cljsjs.react", "cljsjs.react.dom", "cljsjs.react.dom.server"] shims: ["cljsjs.react", "cljsjs.react.dom", "cljsjs.react.dom.server"]
sampleCommandNs: '(in-ns \'$PROJECT_NAME_HYPHENATED$.ios.core)' sampleCommandNs: '(in-ns \'$PROJECT_NAME_HYPHENATED$.ios.core)'
sampleCommand: '(dispatch [:set-greeting "Hello Native World!"])' sampleCommand: '(dispatch [:set-greeting "Hello Native World!"])'
@ -264,7 +265,7 @@ configureDevHostForAndroidDevice = (deviceType) ->
try try
devHost = resolveAndroidDevHost(deviceType) devHost = resolveAndroidDevHost(deviceType)
config = readConfig() config = readConfig()
config.android.host = devHost config.platforms.android.host = devHost
writeConfig(config) writeConfig(config)
log "Please run: re-natal use-figwheel to take effect." log "Please run: re-natal use-figwheel to take effect."
catch {message} catch {message}
@ -285,7 +286,7 @@ configureDevHostForIosDevice = (deviceType) ->
try try
devHost = resolveIosDevHost(deviceType) devHost = resolveIosDevHost(deviceType)
config = readConfig() config = readConfig()
config.ios.host = devHost config.platforms.ios.host = devHost
writeConfig(config) writeConfig(config)
log "Please run: re-natal use-figwheel to take effect." log "Please run: re-natal use-figwheel to take effect."
catch {message} 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")]] edit 'project.clj', [[projNameHyphRx, projNameHyph], [interfaceDepsRx, deps], [platformCleanRx, cleans.join(' ')], [devProfilesRx, devProfiles.join("\n")], [prodProfilesRx, prodProfiles.join("\n")]]
updateProjectClj = (platform) -> updateProjectClj = (platform) ->
proj = readFile('project.clj')
cleans = [] cleans = []
cleans.push "\"index.#{platform}.js\"" cleans.push "\"index.#{platform}.js\""
cleans.push platformCleanId 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" devProfileTemplate = readFile "#{resources}/dev.profile"
devProfiles = [] devProfiles = []
devProfiles.push devProfileTemplate.replace(platformRx, platform) devProfiles.push devProfileTemplate.replace(platformRx, platform)
devProfiles.push devProfilesId 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" prodProfileTemplate = readFile "#{resources}/prod.profile"
prodProfiles = [] prodProfiles = []
prodProfiles.push prodProfileTemplate.replace(platformRx, platform) prodProfiles.push prodProfileTemplate.replace(platformRx, platform)
prodProfiles.push prodProfilesId 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")]] edit 'project.clj', [[platformCleanRx, cleans.join(' ')], [devProfilesRx, devProfiles.join("\n")], [prodProfilesRx, prodProfiles.join("\n")]]
init = (interfaceName, projName) -> init = (interfaceName, projName) ->
@ -461,7 +476,7 @@ init = (interfaceName, projName) ->
'babel-plugin-transform-es2015-block-scoping': '6.15.0' 'babel-plugin-transform-es2015-block-scoping': '6.15.0'
if 'windows' in platforms || 'wpf' in platforms 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 fs.writeFileSync 'package.json', JSON.stringify pkg, null, 2
@ -527,53 +542,59 @@ init = (interfaceName, projName) ->
message message
addPlatform = (platform) -> addPlatform = (platform) ->
config = readConfig() try
platforms = Object.keys config.platforms if !(platform of platformMeta)
throw new Error "Unknown platform [#{platform}]"
if platform in platforms config = readConfig()
log "A project for a #{platformMeta[platform].name} app already exists" platforms = Object.keys config.platforms
else
interfaceName = config.interface
projName = config.name
projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase()
projNameUs = toUnderscored projName
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) log "Preparing for #{platformMeta[platform].name} app."
copySrcFilesForPlatform(platform, interfaceName, projName, projNameUs, projNameHyph)
copyDevEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.dev, "localhost")
copyProdEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.prod)
pkg = JSON.parse readFile 'package.json' updateProjectClj(platform)
copySrcFilesForPlatform(platform, interfaceName, projName, projNameUs, projNameHyph)
unless 'react-native-windows' in pkg.dependencies copyDevEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.dev, "localhost")
pkg.dependencies['react-native-windows'] = rnVersion copyProdEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.prod)
fs.writeFileSync 'package.json', JSON.stringify pkg, null, 2
exec 'npm i'
if platform is 'windows' pkg = JSON.parse readFile 'package.json'
log 'Creating React Native UWP project.'
exec "node -e
\"require('react-native-windows/local-cli/generate-windows')('.', '#{projName}', '#{projName}')\"
"
if platform is 'wpf' unless 'react-native-windows' in pkg.dependencies
log 'Creating React Native WPF project.' pkg.dependencies['react-native-windows'] = rnWinVersion
exec "node -e fs.writeFileSync 'package.json', JSON.stringify pkg, null, 2
\"require('react-native-windows/local-cli/generate-wpf')('.', '#{projName}', '#{projName}')\" 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] = if platform is 'wpf'
host: "localhost" log 'Creating React Native WPF project.'
modules: [] 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' config.platforms[platform] =
exec 'lein prod-build' host: "localhost"
modules: []
writeConfig(config)
log 'Compiling ClojureScript'
exec 'lein prod-build'
catch {message}
logErr message
openXcode = (name) -> openXcode = (name) ->
try try
@ -761,15 +782,10 @@ cli.command 'upgrade'
.action -> .action ->
doUpgrade readConfig(false) doUpgrade readConfig(false)
cli.command 'windows' cli.command 'add-platform <platform>'
.description 'add project for UWP app' .description 'adds additional app platform: \'windows\' - UWP app, \'wpf\' - WPF app'
.action -> .action (platform) ->
addPlatform('windows') addPlatform(platform)
cli.command 'wpf'
.description 'add project for WPF app'
.action ->
addPlatform('wpf')
cli.command 'xcode' cli.command 'xcode'
.description 'open Xcode project' .description 'open Xcode project'

View File

@ -1,5 +1,6 @@
(ns ^:figwheel-no-load env.$PLATFORM$.main (ns ^:figwheel-no-load env.$PLATFORM$.main
(:require [reagent.core :as r] (:require [reagent.core :as r]
[re-frame.core :refer [clear-subscription-cache!]]
[$PROJECT_NAME_HYPHENATED$.$PLATFORM$.core :as core] [$PROJECT_NAME_HYPHENATED$.$PLATFORM$.core :as core]
[figwheel.client :as figwheel :include-macros true])) [figwheel.client :as figwheel :include-macros true]))
@ -9,9 +10,13 @@
(defn reloader [] @cnt [core/app-root]) (defn reloader [] @cnt [core/app-root])
(def root-el (r/as-element [reloader])) (def root-el (r/as-element [reloader]))
(defn force-reload! []
(clear-subscription-cache!)
(swap! cnt inc))
(figwheel/watch-and-reload (figwheel/watch-and-reload
:websocket-url "ws://$DEV_HOST$:3449/figwheel-ws" :websocket-url "ws://$DEV_HOST$:3449/figwheel-ws"
:heads-up-display false :heads-up-display false
:jsload-callback #(swap! cnt inc)) :jsload-callback force-reload!)
(core/init) (core/init)

View File

@ -220,7 +220,7 @@ function loadApp(platform, devHost, onLoadCb) {
// seriously React packager? why. // seriously React packager? why.
var googreq = goog.require; var googreq = goog.require;
googreq('figwheel.connect.' + platform); googreq('figwheel.connect.build_' + platform);
}); });
}); });
} }

View File

@ -3,16 +3,16 @@
:url "http://example.com/FIXME" :url "http://example.com/FIXME"
:license {:name "Eclipse Public License" :license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"} :url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.9.0-alpha10"] :dependencies [[org.clojure/clojure "1.9.0-alpha16"]
[org.clojure/clojurescript "1.9.198"] [org.clojure/clojurescript "1.9.521"]
$INTERFACE_DEPS$] $INTERFACE_DEPS$]
:plugins [[lein-cljsbuild "1.1.4"] :plugins [[lein-cljsbuild "1.1.4"]
[lein-figwheel "0.5.8"]] [lein-figwheel "0.5.10"]]
:clean-targets ["target/" #_($PLATFORM_CLEAN$)] :clean-targets ["target/" #_($PLATFORM_CLEAN$)]
:aliases {"prod-build" ^{:doc "Recompile code with prod profile."} :aliases {"prod-build" ^{:doc "Recompile code with prod profile."}
["do" "clean" ["do" "clean"
["with-profile" "prod" "cljsbuild" "once"]]} ["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"]] [com.cemerick/piggieback "0.2.1"]]
:source-paths ["src" "env/dev"] :source-paths ["src" "env/dev"]
:cljsbuild {:builds [ :cljsbuild {:builds [