Skip to content

Commit

Permalink
Merge pull request #111 from drapanjanas/0.4.0-rc
Browse files Browse the repository at this point in the history
0.4.0-rc
  • Loading branch information
drapanjanas authored May 1, 2017
2 parents 46570b5 + 5e784fd commit 303dea9
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 87 deletions.
61 changes: 37 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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:

```
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
```
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>",
Expand Down
128 changes: 72 additions & 56 deletions re-natal.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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!"])'
Expand Down Expand Up @@ -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}
Expand All @@ -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}
Expand Down Expand Up @@ -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) ->
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

log "Preparing for #{platformMeta[platform].name} app."

updateProjectClj(platform)
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'

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'

if platform is 'windows'
log 'Creating React Native UWP project.'
exec "node -e
\"require('react-native-windows/local-cli/generate-windows')('.', '#{projName}', '#{projName}')\"
"
config = readConfig()
platforms = Object.keys config.platforms

if platform is 'wpf'
log 'Creating React Native WPF project.'
exec "node -e
\"require('react-native-windows/local-cli/generate-wpf')('.', '#{projName}', '#{projName}')\"
"
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

fs.appendFileSync(".gitignore", "\n\nindex.#{platform}.js\n")
log "Preparing for #{platformMeta[platform].name} app."

config.platforms[platform] =
host: "localhost"
modules: []
updateProjectClj(platform)
copySrcFilesForPlatform(platform, interfaceName, projName, projNameUs, projNameHyph)
copyDevEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.dev, "localhost")
copyProdEnvironmentFilesForPlatform(platform, interfaceName, projNameHyph, projName, defaultEnvRoots.prod)

writeConfig(config)
pkg = JSON.parse readFile 'package.json'

log 'Compiling ClojureScript'
exec 'lein prod-build'
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'

if platform is 'windows'
log 'Creating React Native UWP project.'
exec "node -e
\"require('react-native-windows/local-cli/generate-windows')('.', '#{projName}', '#{projName}')\"
"

if platform is 'wpf'
log 'Creating React Native WPF project.'
exec "node -e
\"require('react-native-windows/local-cli/generate-wpf')('.', '#{projName}', '#{projName}')\"
"

fs.appendFileSync(".gitignore", "\n\nindex.#{platform}.js\n")

config.platforms[platform] =
host: "localhost"
modules: []

writeConfig(config)

log 'Compiling ClojureScript'
exec 'lein prod-build'
catch {message}
logErr message

openXcode = (name) ->
try
Expand Down Expand Up @@ -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'
Expand Down
7 changes: 6 additions & 1 deletion resources/cljs-reagent6/main_dev.cljs
Original file line number Diff line number Diff line change
@@ -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]))

Expand All @@ -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)
2 changes: 1 addition & 1 deletion resources/figwheel-bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
}
Expand Down
8 changes: 4 additions & 4 deletions resources/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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 [
Expand Down

0 comments on commit 303dea9

Please sign in to comment.