mirror of
https://github.com/status-im/re-natal.git
synced 2025-02-05 09:13:24 +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
|
## State
|
||||||
- Same codebase for iOS and Android
|
- Same codebase for iOS and Android
|
||||||
- Figwheel used for REPL and live coding.
|
- Figwheel used for REPL and live coding.
|
||||||
- Only works in "Debug in Chrome" mode
|
|
||||||
- Works in iOS (tested using simulator).
|
- 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.
|
- 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
|
- 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
|
- [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:
|
To run in Android, run your simulator first or connect device and:
|
||||||
```
|
```
|
||||||
|
$ adb reverse tcp:8081 tcp:8081
|
||||||
$ react-native run-android
|
$ 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.
|
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
|
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"
|
To start development mode execute commands:
|
||||||
in your React Native application.
|
|
||||||
|
|
||||||
Then execute commands:
|
|
||||||
```
|
```
|
||||||
$ re-natal use-figwheel
|
$ re-natal use-figwheel
|
||||||
$ lein figwheel ios
|
$ 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`.
|
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
|
$ lein prod-build
|
||||||
```
|
```
|
||||||
It will clean and rebuild index.ios.js and index.android.js with `optimizations :simple`
|
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
|
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.
|
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
|
## Tips
|
||||||
- Having `rlwrap` installed is optional but highly recommended since it makes
|
- Having `rlwrap` installed is optional but highly recommended since it makes
|
||||||
the REPL a much nicer experience with arrow keys.
|
the REPL a much nicer experience with arrow keys.
|
||||||
|
@ -377,12 +377,12 @@ getDeviceUuids = ->
|
|||||||
getDeviceList().map (line) -> line.match(/\[(.+)\]/)[1]
|
getDeviceList().map (line) -> line.match(/\[(.+)\]/)[1]
|
||||||
|
|
||||||
|
|
||||||
generateDevScripts = (method) ->
|
generateDevScripts = () ->
|
||||||
try
|
try
|
||||||
fs.statSync '.re-natal'
|
appName = readConfig().name
|
||||||
fs.writeFileSync 'index.ios.js', "require('react-native');require('figwheel-bridge')."+method+"('ios');"
|
fs.writeFileSync 'index.ios.js', "require('figwheel-bridge').start('" + appName + "','ios');"
|
||||||
log 'index.ios.js was regenerated'
|
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'
|
log 'index.android.js was regenerated'
|
||||||
catch {message}
|
catch {message}
|
||||||
logErr \
|
logErr \
|
||||||
@ -485,12 +485,7 @@ cli.command 'deps'
|
|||||||
cli.command 'use-figwheel'
|
cli.command 'use-figwheel'
|
||||||
.description 'generate index.ios.js and index.android.js for development with figwheel'
|
.description 'generate index.ios.js and index.android.js for development with figwheel'
|
||||||
.action ->
|
.action ->
|
||||||
generateDevScripts("figwheel")
|
generateDevScripts()
|
||||||
|
|
||||||
cli.command 'use-reload'
|
|
||||||
.description 'generate index.ios.js and index.android.js for development using app reload'
|
|
||||||
.action ->
|
|
||||||
generateDevScripts("start")
|
|
||||||
|
|
||||||
cli.on '*', (command) ->
|
cli.on '*', (command) ->
|
||||||
logErr "unknown command #{command[0]}. See re-natal --help for valid commands"
|
logErr "unknown command #{command[0]}. See re-natal --help for valid commands"
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
(core/init)
|
(core/init)
|
||||||
|
(core/mount-root)
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,91 +6,164 @@
|
|||||||
|
|
||||||
var CLOSURE_UNCOMPILED_DEFINES = null;
|
var CLOSURE_UNCOMPILED_DEFINES = null;
|
||||||
|
|
||||||
|
var React = require('react-native');
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
basePath: '',
|
server: 'http://localhost:8081',
|
||||||
googBasePath: 'goog/'
|
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???
|
var scriptQueue = [];
|
||||||
function importJs(src, success, error){
|
var fileBasePath = null; // will be set dynamically
|
||||||
if(typeof success !== 'function') { success = function(){}; }
|
var evaluate = eval; // This is needed, direct calls to eval does not work (RN packager???)
|
||||||
if(typeof error !== 'function') { error = function(){}; }
|
|
||||||
|
|
||||||
console.log('(Figwheel Bridge) Importing: ' + config.basePath + src);
|
// evaluates js code ensuring proper ordering
|
||||||
|
function customEval(url, javascript, success, error) {
|
||||||
|
if (scriptQueue.length > 0) {
|
||||||
|
if (scriptQueue[0] === url) {
|
||||||
try {
|
try {
|
||||||
importScripts(config.basePath + src);
|
evaluate(javascript);
|
||||||
|
console.info('Evaluated: ' + url);
|
||||||
|
scriptQueue.shift();
|
||||||
|
if (url.indexOf('jsloader') > -1) {
|
||||||
|
shimJsLoader();
|
||||||
|
}
|
||||||
success();
|
success();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Could not load: ' + config.basePath + src);
|
console.error('Evaluation error in: ' + url);
|
||||||
console.error('Import error: ' + e);
|
console.error(e);
|
||||||
error();
|
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();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loads base goog js file then cljs_deps, goog.deps, core project cljs, and then figwheel
|
// Async load of javascript files
|
||||||
// Also calls the function to shim goog.require and goog.net.jsLoader.load
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function loadApp(platform) {
|
function loadApp(platform) {
|
||||||
config.basePath = "/target/" + platform + "/";
|
fileBasePath = config.basePath + platform;
|
||||||
|
|
||||||
if (typeof goog === "undefined") {
|
if (typeof goog === "undefined") {
|
||||||
console.log('Loading Closure base.');
|
console.log('Loading Closure base.');
|
||||||
importJs('goog/base.js');
|
importJs('goog/base.js', function () {
|
||||||
shimBaseGoog();
|
shimBaseGoog();
|
||||||
fakeLocalStorageAndDocument();
|
fakeLocalStorageAndDocument();
|
||||||
importJs('cljs_deps.js');
|
importJs('cljs_deps.js');
|
||||||
importJs('goog/deps.js');
|
importJs('goog/deps.js', function () {
|
||||||
importJs('$PROJECT_NAME_UNDERSCORED$/'+platform+'/core.js');
|
|
||||||
|
// 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');
|
console.log('Done loading Clojure app');
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startApp(platform) {
|
function startApp(appName, platform) {
|
||||||
|
React.AppRegistry.registerComponent(appName, () => config.splash);
|
||||||
if (typeof goog === "undefined") {
|
if (typeof goog === "undefined") {
|
||||||
loadApp(platform);
|
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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Goog fixes
|
||||||
function shimBaseGoog() {
|
function shimBaseGoog() {
|
||||||
|
console.info('Shimming goog functions.');
|
||||||
goog.basePath = 'goog/';
|
goog.basePath = 'goog/';
|
||||||
goog.writeScriptSrcNode = importJs;
|
goog.writeScriptSrcNode = importJs;
|
||||||
goog.writeScriptTag_ = function(src, opt_sourceText){
|
goog.writeScriptTag_ = function (src, optSourceText) {
|
||||||
importJs(src);
|
importJs(src);
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
goog.inHtmlDocument_ = function(){ return true; };
|
goog.inHtmlDocument_ = function () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function fakeLocalStorageAndDocument() {
|
function fakeLocalStorageAndDocument() {
|
||||||
window.localStorage = {};
|
window.localStorage = {};
|
||||||
window.localStorage.getItem = function(){ return 'true'; };
|
window.localStorage.getItem = function () {
|
||||||
window.localStorage.setItem = function(){};
|
return 'true';
|
||||||
|
};
|
||||||
|
window.localStorage.setItem = function () {
|
||||||
|
};
|
||||||
|
|
||||||
window.document = {};
|
window.document = {};
|
||||||
window.document.body = {};
|
window.document.body = {};
|
||||||
window.document.body.dispatchEvent = function(){};
|
window.document.body.dispatchEvent = function () {
|
||||||
window.document.createElement = 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
|
// Used by figwheel - uses importScript to load JS rather than <script>'s
|
||||||
function shimJsLoader() {
|
function shimJsLoader() {
|
||||||
|
console.info('==== Shimming jsloader ====');
|
||||||
goog.net.jsloader.load = function (uri, options) {
|
goog.net.jsloader.load = function (uri, options) {
|
||||||
var deferred = {
|
var deferred = {
|
||||||
callbacks: [],
|
callbacks: [],
|
||||||
@ -113,17 +186,18 @@ function shimJsLoader(){
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Figwheel needs this to be an async call, so that it can add callbacks to deferred
|
// Figwheel needs this to be an async call,
|
||||||
|
// so that it can add callbacks to deferred
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
importJs(uri.getPath(), deferred.callAllCallbacks, deferred.callAllErrbacks);
|
importJs(uri.getPath(),
|
||||||
|
deferred.callAllCallbacks,
|
||||||
|
deferred.callAllErrbacks);
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
return deferred;
|
return deferred;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
start: startApp,
|
start: startApp
|
||||||
figwheel : startWithFigwheel,
|
|
||||||
load: loadApp
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user