Created
September 29, 2016 15:10
-
-
Save aputs/2913fb9460d5e488e4ab5951054ed734 to your computer and use it in GitHub Desktop.
re-natal reagent figwheel repl with boot-clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#http://boot-clj.com | |
#Wed Sep 28 14:53:54 PHT 2016 | |
BOOT_CLOJURE_NAME=org.clojure/clojure | |
BOOT_CLOJURE_VERSION=1.9.0-alpha12 | |
BOOT_VERSION=2.6.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(set-env! | |
:source-paths #{"src"} | |
:dependencies | |
'[[org.clojure/clojure "1.9.0-alpha12" :scope "provided"] | |
[org.clojure/clojurescript "1.9.229" :scope "provided"] | |
[com.cemerick/piggieback "0.2.1" :scope "test"] | |
[org.clojure/tools.nrepl "0.2.12" :scope "test"] | |
[figwheel-sidecar "0.5.8" :scope "test"] | |
[proto-repl "0.3.1" :scope "test"] | |
[org.clojure/core.async "0.2.391"] | |
[reagent "0.6.0" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server]] | |
[datascript "0.15.3"] | |
[posh "0.5.4"] | |
(require | |
'clojure.tools.namespace.repl | |
'cemerick.piggieback | |
'[figwheel-sidecar.system :as sys] | |
'[com.stuartsierra.component :as component]) | |
(def system (component/system-map :figwheel-system (sys/figwheel-system (sys/fetch-config)))) | |
(deftask figwheel | |
[] | |
(repl :middleware '[cemerick.piggieback/wrap-cljs-repl] | |
:eval '(do | |
(alter-var-root #'system component/start) | |
(sys/cljs-repl (:figwheel-system system))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Originally taken from https://github.com/decker405/figwheel-react-native | |
* | |
* @providesModule figwheel-bridge | |
*/ | |
var CLOSURE_UNCOMPILED_DEFINES = null; | |
var debugEnabled = false; | |
var config = { | |
basePath: "target/", | |
googBasePath: 'goog/', | |
serverPort: 8081 | |
}; | |
var React = require('react'); | |
var ReactNative = require('react-native'); | |
var WebSocket = require('WebSocket'); | |
var self; | |
var scriptQueue = []; | |
var serverHost = null; // will be set dynamically | |
var fileBasePath = null; // will be set dynamically | |
var evaluate = eval; // This is needed, direct calls to eval does not work (RN packager???) | |
var externalModules = {}; | |
var evalListeners = [ // Functions to be called after each js file is loaded and evaluated | |
function (url) { | |
if (url.indexOf('jsloader') > -1) { | |
shimJsLoader(); | |
} | |
}, | |
function (url) { | |
if (url.indexOf('/figwheel/client/socket') > -1) { | |
setCorrectWebSocketImpl(); | |
} | |
}]; | |
var figwheelApp = function (platform, devHost) { | |
return React.createClass({ | |
getInitialState: function () { | |
return {loaded: false} | |
}, | |
render: function () { | |
if (!this.state.loaded) { | |
var plainStyle = {flex: 1, alignItems: 'center', justifyContent: 'center'}; | |
return ( | |
<ReactNative.View style={plainStyle}> | |
<ReactNative.Text>Waiting for Figwheel to load files.</ReactNative.Text> | |
</ReactNative.View> | |
); | |
} | |
return this.state.root; | |
}, | |
componentDidMount: function () { | |
var app = this; | |
if (typeof goog === "undefined") { | |
loadApp(platform, devHost, function (appRoot) { | |
app.setState({root: appRoot, loaded: true}) | |
}); | |
} | |
} | |
}) | |
}; | |
function logDebug(msg) { | |
if (debugEnabled) { | |
console.log(msg); | |
} | |
} | |
// evaluates js code ensuring proper ordering | |
function customEval(url, javascript, success, error) { | |
if (scriptQueue.length > 0) { | |
if (scriptQueue[0] === url) { | |
try { | |
evaluate(javascript); | |
logDebug('Evaluated: ' + url); | |
scriptQueue.shift(); | |
evalListeners.forEach(function (listener) { | |
listener(url) | |
}); | |
success(); | |
} catch (e) { | |
console.error(e); | |
error(); | |
} | |
} else { | |
setTimeout(function () { | |
customEval(url, javascript, success, error) | |
}, 5); | |
} | |
} else { | |
console.error('Something bad happened...'); | |
error() | |
} | |
} | |
var isChrome = function () { | |
return typeof importScripts === "function" | |
}; | |
function asyncImportScripts(url, success, error) { | |
logDebug('(asyncImportScripts) Importing: ' + url); | |
scriptQueue.push(url); | |
fetch(url) | |
.then(function (response) { | |
return response.text() | |
}) | |
.then(function (responseText) { | |
return customEval(url, responseText, success, error); | |
}) | |
.catch(function (error) { | |
console.error(error); | |
return error(); | |
}); | |
} | |
function syncImportScripts(url, success, error) { | |
try { | |
importScripts(url); | |
logDebug('Evaluated: ' + url); | |
evalListeners.forEach(function (listener) { | |
listener(url) | |
}); | |
success(); | |
} catch (e) { | |
console.error(e); | |
error() | |
} | |
} | |
// Loads js file sync if possible or async. | |
function importJs(src, success, error) { | |
if (typeof success !== 'function') { | |
success = function () { | |
}; | |
} | |
if (typeof error !== 'function') { | |
error = function () { | |
}; | |
} | |
var file = fileBasePath + '/' + src; | |
logDebug('(importJs) Importing: ' + file); | |
if (isChrome()) { | |
syncImportScripts(serverBaseUrl("localhost") + '/' + file, success, error); | |
} else { | |
asyncImportScripts(serverBaseUrl(serverHost) + '/' + file, success, error); | |
} | |
} | |
function interceptRequire() { | |
var oldRequire = window.require; | |
console.info("Shimming require"); | |
window.require = function (id) { | |
console.info("Requiring: " + id); | |
if (externalModules[id]) { | |
return externalModules[id]; | |
} | |
return oldRequire(id); | |
}; | |
} | |
function compileWarningsToYellowBox() { | |
var log = window.console.log; | |
var compileWarningRx = /Figwheel: Compile/; | |
var compileExceptionRx = /Figwheel: Compile Exception/; | |
var errorInFileRx = /Error on file/; | |
var isBuffering = false; | |
var compileExceptionBuffer = ""; | |
window.console.log = function (msg) { | |
log.apply(window.console, arguments); | |
if (compileExceptionRx.test(msg)) { // enter buffering mode to get all the messages for exception | |
isBuffering = true; | |
compileExceptionBuffer = msg + "\n"; | |
} else if (errorInFileRx.test(msg) && isBuffering) { // exit buffering mode and log buffered messages to YellowBox | |
isBuffering = false; | |
console.warn(compileExceptionBuffer + msg); | |
compileExceptionBuffer = ""; | |
} else if (isBuffering) { //log messages buffering mode | |
compileExceptionBuffer += msg + "\n"; | |
} else if (compileWarningRx.test(msg)) { | |
console.warn(msg); | |
} | |
}; | |
} | |
function serverBaseUrl(host) { | |
return "http://" + host + ":" + config.serverPort | |
} | |
function setCorrectWebSocketImpl() { | |
figwheel.client.socket.get_websocket_imp = function () { | |
return WebSocket; | |
}; | |
} | |
function loadApp(platform, devHost, onLoadCb) { | |
serverHost = devHost; | |
fileBasePath = config.basePath + platform; | |
// callback when app is ready to get the reloadable component | |
var mainJs = '/env/' + platform + '/main.js'; | |
evalListeners.push(function (url) { | |
if (url.indexOf(mainJs) > -1) { | |
onLoadCb(env[platform].main.root_el); | |
console.info('Done loading Clojure app'); | |
} | |
}); | |
if (typeof goog === "undefined") { | |
console.info('Loading Closure base.'); | |
interceptRequire(); | |
compileWarningsToYellowBox(); | |
importJs('goog/base.js', function () { | |
shimBaseGoog(); | |
importJs('cljs_deps.js'); | |
importJs('goog/deps.js', function () { | |
// This is needed because of RN packager | |
// seriously React packager? why. | |
var googreq = goog.require; | |
googreq('figwheel.connect.' + platform); | |
}); | |
}); | |
} | |
} | |
function startApp(appName, platform, devHost) { | |
ReactNative.AppRegistry.registerComponent( | |
appName, () => figwheelApp(platform, devHost)); | |
} | |
function withModules(moduleById) { | |
externalModules = moduleById; | |
return self; | |
} | |
// Goog fixes | |
function shimBaseGoog() { | |
console.info('Shimming goog functions.'); | |
goog.basePath = 'goog/'; | |
goog.writeScriptSrcNode = importJs; | |
goog.writeScriptTag_ = function (src, optSourceText) { | |
importJs(src); | |
return true; | |
}; | |
} | |
// Figwheel fixes | |
// Used by figwheel - uses importScript to load JS rather than <script>'s | |
function shimJsLoader() { | |
console.info('==== Shimming jsloader ===='); | |
goog.net.jsloader.load = function (uri, options) { | |
var deferred = { | |
callbacks: [], | |
errbacks: [], | |
addCallback: function (cb) { | |
deferred.callbacks.push(cb); | |
}, | |
addErrback: function (cb) { | |
deferred.errbacks.push(cb); | |
}, | |
callAllCallbacks: function () { | |
while (deferred.callbacks.length > 0) { | |
deferred.callbacks.shift()(); | |
} | |
}, | |
callAllErrbacks: function () { | |
while (deferred.errbacks.length > 0) { | |
deferred.errbacks.shift()(); | |
} | |
} | |
}; | |
// Figwheel needs this to be an async call, | |
// so that it can add callbacks to deferred | |
setTimeout(function () { | |
importJs(uri.getPath(), | |
deferred.callAllCallbacks, | |
deferred.callAllErrbacks); | |
}, 1); | |
return deferred; | |
}; | |
} | |
self = { | |
withModules: withModules, | |
start: startApp | |
}; | |
module.exports = self; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defproject nativeapp "0.1.0-SNAPSHOT" | |
:description "FIXME: write description" | |
: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-alpha12"] | |
[org.clojure/clojurescript "1.9.229"] | |
[org.clojure/core.async "0.2.391"] | |
[reagent "0.6.0" :exclusions [cljsjs/react cljsjs/react-dom cljsjs/react-dom-server]] | |
[datascript "0.15.3"] | |
[posh "0.5.4"] | |
:plugins [[lein-cljsbuild "1.1.4"] | |
[lein-figwheel "0.5.8"]] | |
:clean-targets ["target/" "index.ios.js" "index.android.js"] | |
:aliases {"prod-build" ^{:doc "Recompile code with prod profile."} | |
["do" "clean" | |
["with-profile" "prod" "cljsbuild" "once" "ios"] | |
["with-profile" "prod" "cljsbuild" "once" "android"]]} | |
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.8"] | |
[com.cemerick/piggieback "0.2.1"] | |
[org.clojure/test.check "0.9.0"]] | |
:source-paths ["src" "env/dev"] | |
:cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"] | |
:figwheel true | |
:compiler {:output-to "target/ios/not-used.js" | |
:main "env.ios.main" | |
:output-dir "target/ios" | |
:optimizations :none}} | |
:android {:source-paths ["src" "env/dev"] | |
:figwheel true | |
:compiler {:output-to "target/android/not-used.js" | |
:main "env.android.main" | |
:output-dir "target/android" | |
:optimizations :none}}}} | |
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}} | |
:prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"] | |
:compiler {:output-to "index.ios.js" | |
:main "env.ios.main" | |
:output-dir "target/ios" | |
:static-fns true | |
:optimize-constants true | |
:optimizations :simple | |
:closure-defines {"goog.DEBUG" false}}} | |
:android {:source-paths ["src" "env/prod"] | |
:compiler {:output-to "index.android.js" | |
:main "env.android.main" | |
:output-dir "target/android" | |
:static-fns true | |
:optimize-constants true | |
:optimizations :simple | |
:closure-defines {"goog.DEBUG" false}}}}}}}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment