mirror of
https://github.com/status-im/re-natal.git
synced 2025-01-27 04:44:50 +00:00
make Figwheel work without the need of Debug in Chrome
- solution by https://github.com/decker405/figwheel-react-native - remove use-reload command. - adoptions to figwheel-bridge.js
This commit is contained in:
parent
91eac6fd2c
commit
927b5de7fe
25
README.md
25
README.md
@ -20,10 +20,10 @@ Generated project works in iOS and Android devices.
|
||||
## State
|
||||
- Same codebase for iOS and Android
|
||||
- Figwheel used for REPL and live coding.
|
||||
- Only works in "Debug in Chrome" mode
|
||||
- Works in iOS (tested using simulator).
|
||||
- Works in Android (tested on real device, encountered connection problem using Android simulator genymotion)
|
||||
- Works in Android (tested on real device, does not work on simulator yet)
|
||||
- You can reload app any time, no problem.
|
||||
- "Debug in Chrome" is not required anymore.
|
||||
- Optimizations :simple is used to compile "production" index.ios.js and index.android.js
|
||||
- [Unified way of using static images of rn 0.14](https://facebook.github.io/react-native/docs/images.html) works
|
||||
|
||||
@ -62,6 +62,7 @@ and then run your app from Xcode normally.
|
||||
|
||||
To run in Android, run your simulator first or connect device and:
|
||||
```
|
||||
$ adb reverse tcp:8081 tcp:8081
|
||||
$ react-native run-android
|
||||
```
|
||||
|
||||
@ -70,21 +71,13 @@ are compiled with `optimizations :simple`.
|
||||
Development in such mode is not fun because of slow compilation and long reload time.
|
||||
|
||||
Luckily, this can be improved by compiling with `optimizations :none` and using
|
||||
figwheel.
|
||||
Figwheel.
|
||||
|
||||
To start development in `optimizations :none` mode you have to start "Debug in Chrome"
|
||||
in your React Native application.
|
||||
|
||||
Then execute commands:
|
||||
To start development mode execute commands:
|
||||
```
|
||||
$ re-natal use-figwheel
|
||||
$ lein figwheel ios
|
||||
```
|
||||
or for usage without figwheel:
|
||||
```
|
||||
$ re-natal use-reload
|
||||
$ lein cljsbuild auto android
|
||||
```
|
||||
|
||||
This will generate index.ios.js and index.android.js which works with compiler mode`optimizations :none`.
|
||||
|
||||
@ -119,11 +112,17 @@ Do this with command:
|
||||
$ lein prod-build
|
||||
```
|
||||
It will clean and rebuild index.ios.js and index.android.js with `optimizations :simple`
|
||||
After this you can reload the app and exit "Debug in Chrome".
|
||||
|
||||
Having index.ios.js and index.android.js build this way, you should be able to
|
||||
follow the RN docs to proceed with the release.
|
||||
|
||||
## Problems with Android simulator
|
||||
Using Figwheel with android simulator is not working out of the box yet.
|
||||
Looks like the main reason for that is that requests to http://localhost:8081 fails because
|
||||
"localhost" is simulators own loopback interface and not the one of the host machine.
|
||||
According to [Emulator docs](http://developer.android.com/tools/devices/emulator.html#networkaddresses)
|
||||
instead of "localhost" a special IP: 10.0.2.2 should be used.
|
||||
|
||||
## Tips
|
||||
- Having `rlwrap` installed is optional but highly recommended since it makes
|
||||
the REPL a much nicer experience with arrow keys.
|
||||
|
@ -377,12 +377,12 @@ getDeviceUuids = ->
|
||||
getDeviceList().map (line) -> line.match(/\[(.+)\]/)[1]
|
||||
|
||||
|
||||
generateDevScripts = (method) ->
|
||||
generateDevScripts = () ->
|
||||
try
|
||||
fs.statSync '.re-natal'
|
||||
fs.writeFileSync 'index.ios.js', "require('react-native');require('figwheel-bridge')."+method+"('ios');"
|
||||
appName = readConfig().name
|
||||
fs.writeFileSync 'index.ios.js', "require('figwheel-bridge').start('" + appName + "','ios');"
|
||||
log 'index.ios.js was regenerated'
|
||||
fs.writeFileSync 'index.android.js', "require('react-native');require('figwheel-bridge')."+method+"('android');"
|
||||
fs.writeFileSync 'index.android.js', "require('figwheel-bridge').start('" + appName + "','android');"
|
||||
log 'index.android.js was regenerated'
|
||||
catch {message}
|
||||
logErr \
|
||||
@ -485,12 +485,7 @@ cli.command 'deps'
|
||||
cli.command 'use-figwheel'
|
||||
.description 'generate index.ios.js and index.android.js for development with figwheel'
|
||||
.action ->
|
||||
generateDevScripts("figwheel")
|
||||
|
||||
cli.command 'use-reload'
|
||||
.description 'generate index.ios.js and index.android.js for development using app reload'
|
||||
.action ->
|
||||
generateDevScripts("start")
|
||||
generateDevScripts()
|
||||
|
||||
cli.on '*', (command) ->
|
||||
logErr "unknown command #{command[0]}. See re-natal --help for valid commands"
|
||||
|
@ -4,5 +4,6 @@
|
||||
(enable-console-print!)
|
||||
|
||||
(core/init)
|
||||
(core/mount-root)
|
||||
|
||||
|
||||
|
@ -6,124 +6,198 @@
|
||||
|
||||
var CLOSURE_UNCOMPILED_DEFINES = null;
|
||||
|
||||
var React = require('react-native');
|
||||
|
||||
var config = {
|
||||
basePath: '',
|
||||
googBasePath: 'goog/'
|
||||
server: 'http://localhost:8081',
|
||||
basePath: "target/",
|
||||
googBasePath: 'goog/',
|
||||
splash: React.createClass({
|
||||
render: function () {
|
||||
var plainStyle = {flex: 1, alignItems: 'center', justifyContent: 'center'};
|
||||
return (
|
||||
<React.View style={plainStyle}>
|
||||
<React.Text>Waiting for Figwheel to load files.</React.Text>
|
||||
</React.View>
|
||||
);
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// Uninstall watchman???
|
||||
function importJs(src, success, error){
|
||||
if(typeof success !== 'function') { success = function(){}; }
|
||||
if(typeof error !== 'function') { error = function(){}; }
|
||||
var scriptQueue = [];
|
||||
var fileBasePath = null; // will be set dynamically
|
||||
var evaluate = eval; // This is needed, direct calls to eval does not work (RN packager???)
|
||||
|
||||
console.log('(Figwheel Bridge) Importing: ' + config.basePath + src);
|
||||
try {
|
||||
importScripts(config.basePath + src);
|
||||
success();
|
||||
} catch(e) {
|
||||
console.warn('Could not load: ' + config.basePath + src);
|
||||
console.error('Import error: ' + e);
|
||||
error();
|
||||
// evaluates js code ensuring proper ordering
|
||||
function customEval(url, javascript, success, error) {
|
||||
if (scriptQueue.length > 0) {
|
||||
if (scriptQueue[0] === url) {
|
||||
try {
|
||||
evaluate(javascript);
|
||||
console.info('Evaluated: ' + url);
|
||||
scriptQueue.shift();
|
||||
if (url.indexOf('jsloader') > -1) {
|
||||
shimJsLoader();
|
||||
}
|
||||
success();
|
||||
} catch (e) {
|
||||
console.error('Evaluation error in: ' + url);
|
||||
console.error(e);
|
||||
error();
|
||||
}
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
customEval(url, javascript, success, error)
|
||||
}, 5);
|
||||
}
|
||||
} else {
|
||||
console.error('Something bad happened...');
|
||||
error()
|
||||
}
|
||||
}
|
||||
function asyncImportScripts(path, success, error) {
|
||||
var url = config.server + '/' + path;
|
||||
|
||||
console.info('(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 loading script, please check your config setup.');
|
||||
console.error(error);
|
||||
return error();
|
||||
});
|
||||
}
|
||||
|
||||
// Async load of javascript files
|
||||
function importJs(src, success, error) {
|
||||
if (typeof success !== 'function') {
|
||||
success = function () {
|
||||
};
|
||||
}
|
||||
if (typeof error !== 'function') {
|
||||
error = function () {
|
||||
};
|
||||
}
|
||||
|
||||
var filePath = fileBasePath + '/' + src;
|
||||
|
||||
console.info('(importJs) Importing: ' + filePath);
|
||||
asyncImportScripts(filePath, success, error);
|
||||
}
|
||||
|
||||
|
||||
// Loads base goog js file then cljs_deps, goog.deps, core project cljs, and then figwheel
|
||||
// Also calls the function to shim goog.require and goog.net.jsLoader.load
|
||||
function loadApp(platform) {
|
||||
config.basePath = "/target/" + platform + "/";
|
||||
fileBasePath = config.basePath + platform;
|
||||
|
||||
if(typeof goog === "undefined") {
|
||||
if (typeof goog === "undefined") {
|
||||
console.log('Loading Closure base.');
|
||||
importJs('goog/base.js');
|
||||
shimBaseGoog();
|
||||
fakeLocalStorageAndDocument();
|
||||
importJs('cljs_deps.js');
|
||||
importJs('goog/deps.js');
|
||||
importJs('$PROJECT_NAME_UNDERSCORED$/'+platform+'/core.js');
|
||||
importJs('goog/base.js', function () {
|
||||
shimBaseGoog();
|
||||
fakeLocalStorageAndDocument();
|
||||
importJs('cljs_deps.js');
|
||||
importJs('goog/deps.js', function () {
|
||||
|
||||
console.log('Done loading Clojure app');
|
||||
// This is needed because of RN packager
|
||||
// seriously React packager? why.
|
||||
var googreq = goog.require;
|
||||
|
||||
googreq('figwheel.connect');
|
||||
googreq('env.' + platform + '.main');
|
||||
|
||||
console.log('Done loading Clojure app');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function startApp(platform) {
|
||||
if(typeof goog === "undefined") {
|
||||
function startApp(appName, platform) {
|
||||
React.AppRegistry.registerComponent(appName, () => config.splash);
|
||||
if (typeof goog === "undefined") {
|
||||
loadApp(platform);
|
||||
}
|
||||
console.log('Starting the app');
|
||||
eval("$PROJECT_NAME_UNDERSCORED$."+platform+".core.init()");
|
||||
}
|
||||
|
||||
// Loads base goog js file then cljs_deps, goog.deps, core project cljs, and then figwheel
|
||||
// Also calls the function to shim goog.require and goog.net.jsLoader.load
|
||||
function startWithFigwheel(platform) {
|
||||
if(typeof goog === "undefined") {
|
||||
startApp(platform);
|
||||
}
|
||||
importJs('figwheel/connect.js');
|
||||
|
||||
// goog.require('figwheel.connect');
|
||||
// goog.require('rn_test.core');
|
||||
shimJsLoader();
|
||||
|
||||
}
|
||||
|
||||
function shimBaseGoog(){
|
||||
// Goog fixes
|
||||
function shimBaseGoog() {
|
||||
console.info('Shimming goog functions.');
|
||||
goog.basePath = 'goog/';
|
||||
goog.writeScriptSrcNode = importJs;
|
||||
goog.writeScriptTag_ = function(src, opt_sourceText){
|
||||
goog.writeScriptTag_ = function (src, optSourceText) {
|
||||
importJs(src);
|
||||
return true;
|
||||
}
|
||||
goog.inHtmlDocument_ = function(){ return true; };
|
||||
};
|
||||
goog.inHtmlDocument_ = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
function fakeLocalStorageAndDocument() {
|
||||
window.localStorage = {};
|
||||
window.localStorage.getItem = function(){ return 'true'; };
|
||||
window.localStorage.setItem = function(){};
|
||||
window.localStorage.getItem = function () {
|
||||
return 'true';
|
||||
};
|
||||
window.localStorage.setItem = function () {
|
||||
};
|
||||
|
||||
window.document = {};
|
||||
window.document.body = {};
|
||||
window.document.body.dispatchEvent = function(){};
|
||||
window.document.createElement = function(){};
|
||||
window.document.body.dispatchEvent = function () {
|
||||
};
|
||||
window.document.createElement = function () {
|
||||
};
|
||||
|
||||
if (typeof window.location === 'undefined') {
|
||||
window.location = {};
|
||||
}
|
||||
console.debug = console.warn;
|
||||
window.addEventListener = function () {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Figwheel fixes
|
||||
// Used by figwheel - uses importScript to load JS rather than <script>'s
|
||||
function shimJsLoader(){
|
||||
goog.net.jsloader.load = function(uri, options) {
|
||||
function shimJsLoader() {
|
||||
console.info('==== Shimming jsloader ====');
|
||||
goog.net.jsloader.load = function (uri, options) {
|
||||
var deferred = {
|
||||
callbacks: [],
|
||||
errbacks: [],
|
||||
addCallback: function(cb){
|
||||
addCallback: function (cb) {
|
||||
deferred.callbacks.push(cb);
|
||||
},
|
||||
addErrback: function(cb){
|
||||
addErrback: function (cb) {
|
||||
deferred.errbacks.push(cb);
|
||||
},
|
||||
callAllCallbacks: function(){
|
||||
while(deferred.callbacks.length > 0){
|
||||
callAllCallbacks: function () {
|
||||
while (deferred.callbacks.length > 0) {
|
||||
deferred.callbacks.shift()();
|
||||
}
|
||||
},
|
||||
callAllErrbacks: function(){
|
||||
while(deferred.errbacks.length > 0){
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
start: startApp,
|
||||
figwheel : startWithFigwheel,
|
||||
load: loadApp
|
||||
start: startApp
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user