Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions build.boot
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

(set-env! :resource-paths #{"src" "resources"}
:dependencies '[[pandeiro/boot-http "0.7.1-SNAPSHOT" :scope "test"]
[com.cemerick/url "0.1.1"]
Expand All @@ -8,14 +7,14 @@
(partial map (fn [[k v]] [k (cond-> v (#{"clojars"} k) (assoc :username (System/getenv "CLOJARS_USER"),
:password (System/getenv "CLOJARS_PASS")))])))

(def +version+ "0.3-rc1337")
(def +version+ "0.4-SNAPSHOT")

(task-options!
pom {:project 'boot-react-native/boot-react-native
pom {:project 'org.clojars.vikeri/boot-react-native
:version +version+
:description "Boot tasks to integrate ClojureScript boot tasks (reload, repl, cljs-build) with React Native packager"
:url "https://github.com/mjmeintjes/boot-react-native"
:scm {:url "https://github.com/mjmeintjes/boot-react-native"}
:url "https://github.com/vikeri/boot-react-native"
:scm {:url "https://github.com/vikeri/boot-react-native"}
:license {"Eclipse Public License"
"http://www.eclipse.org/legal/epl-v10.html"}})

Expand Down
3 changes: 3 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.DS_Store
.js-modules.edn
figwheel_server.log
env/dev/env/dev.cljs
17 changes: 6 additions & 11 deletions example/app/init.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/

'use strict';

// global.window = {};

// hack: get reagent to find ReactNative.render as ReactDOM.render
global.ReactDOM = require('react-native');

require('./build/main.js');
// cljsbuild adds a preamble mentioning goog so hack around it
window.goog = {
provide() {},
require() {},
};
require('./target/env/index.js');
296 changes: 296 additions & 0 deletions example/app/js/figwheel-bridge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
/*
* 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 () {
console.log("RENDERING", this.state.loaded, ReactNative.View);
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 () {
console.log("DID MOUNT");
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;

// callback when app is ready to get the reloadable component
var mainJs = '/env/main.js';
evalListeners.push(function (url) {
if (url.indexOf(mainJs) > -1) {
onLoadCb(env.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.build_main');
});
});
}
}

function startApp(appName, platform, devHost) {
console.log("Regging comp", appName);
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;
4 changes: 2 additions & 2 deletions example/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "~15.4.0-rc.4",
"react": "16.0.0-alpha.6",
"react-dom": "15.3.1",
"react-native": "0.42.0"
"react-native": "0.44.0"
}
}
Loading