Move DevTools integration into its own repo
Summary:
The way React DevTools integration was set up in RN was not entirely supported by the React team, and we had to disable it in c3b25c9059
so that we can move forward with enabling Fiber support in React Native.
Here, I am moving the DevTools client setup from RN repo to [React DevTools repo](https://github.com/facebook/react-devtools/blob/master/packages/react-devtools-core/README.md#requirereact-devtools-coreconnecttodevtoolsoptions) so that we can keep it in sync with the rest of React DevTools. This is also a part of a larger effort to consolidate DevTools code (https://github.com/facebook/react-devtools/issues/489). It allows us to remove the double injection of the hook, an lets us replace the `eval` hack with a regular dependency. The implementation [lives here now](https://github.com/facebook/react-devtools/blob/master/packages/react-devtools-core/src/backend.js).
This change re-enables Nuclide Inspector with React Native Stack reconciler and prepares it for compatibi
Closes https://github.com/facebook/react-native/pull/12316
Reviewed By: zertosh
Differential Revision: D4545322
Pulled By: gaearon
fbshipit-source-id: ab949916c1a92c6b41cd41e7e1edf9697a71de2e
This commit is contained in:
parent
b64de27a62
commit
934cd82941
|
@ -11,100 +11,24 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
var NativeModules = require('NativeModules');
|
||||
var Platform = require('Platform');
|
||||
if (__DEV__) {
|
||||
var AppState = require('AppState');
|
||||
var NativeModules = require('NativeModules');
|
||||
var Platform = require('Platform');
|
||||
var {connectToDevTools} = require('react-devtools-core');
|
||||
|
||||
function setupDevtools() {
|
||||
var messageListeners = [];
|
||||
var closeListeners = [];
|
||||
var hostname = 'localhost';
|
||||
if (Platform.OS === 'android' && NativeModules.AndroidConstants) {
|
||||
hostname = NativeModules.AndroidConstants.ServerHost.split(':')[0];
|
||||
}
|
||||
var port = window.__REACT_DEVTOOLS_PORT__ || 8097;
|
||||
var ws = new window.WebSocket('ws://' + hostname + ':' + port + '/devtools');
|
||||
// this is accessed by the eval'd backend code
|
||||
var FOR_BACKEND = { // eslint-disable-line no-unused-vars
|
||||
resolveRNStyle: require('flattenStyle'),
|
||||
wall: {
|
||||
listen(fn) {
|
||||
messageListeners.push(fn);
|
||||
},
|
||||
onClose(fn) {
|
||||
closeListeners.push(fn);
|
||||
},
|
||||
send(data) {
|
||||
ws.send(JSON.stringify(data));
|
||||
},
|
||||
connectToDevTools({
|
||||
isAppActive() {
|
||||
// Don't steal the DevTools from currently active app.
|
||||
return AppState.currentState !== 'background';
|
||||
},
|
||||
};
|
||||
ws.onclose = handleClose;
|
||||
ws.onerror = handleClose;
|
||||
ws.onopen = function () {
|
||||
tryToConnect();
|
||||
};
|
||||
|
||||
var hasClosed = false;
|
||||
function handleClose() {
|
||||
if (!hasClosed) {
|
||||
hasClosed = true;
|
||||
setTimeout(setupDevtools, 2000);
|
||||
closeListeners.forEach(fn => fn());
|
||||
}
|
||||
}
|
||||
|
||||
function tryToConnect() {
|
||||
ws.send('attach:agent');
|
||||
var _interval = setInterval(() => ws.send('attach:agent'), 500);
|
||||
ws.onmessage = evt => {
|
||||
if (evt.data.indexOf('eval:') === 0) {
|
||||
clearInterval(_interval);
|
||||
initialize(evt.data.slice('eval:'.length));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initialize(text) {
|
||||
try {
|
||||
// FOR_BACKEND is used by the eval'd code
|
||||
eval(text); // eslint-disable-line no-eval
|
||||
} catch (e) {
|
||||
console.error('Failed to eval: ' + e.message);
|
||||
return;
|
||||
}
|
||||
ws.onmessage = handleMessage;
|
||||
}
|
||||
|
||||
function handleMessage(evt) {
|
||||
// It's hard to handle JSON in a safe manner without inspecting it at
|
||||
// runtime, hence the any
|
||||
var data: any;
|
||||
try {
|
||||
data = JSON.parse(evt.data);
|
||||
} catch (e) {
|
||||
return console.error('failed to parse json: ' + evt.data);
|
||||
}
|
||||
// the devtools closed
|
||||
if (data.$close || data.$error) {
|
||||
closeListeners.forEach(fn => fn());
|
||||
tryToConnect();
|
||||
return;
|
||||
}
|
||||
if (data.$open) {
|
||||
return; // ignore
|
||||
}
|
||||
messageListeners.forEach(fn => {
|
||||
try {
|
||||
fn(data);
|
||||
} catch (e) {
|
||||
// jsc doesn't play so well with tracebacks that go into eval'd code,
|
||||
// so the stack trace here will stop at the `eval()` call. Getting the
|
||||
// message that caused the error is the best we can do for now.
|
||||
console.log(data);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Special case: Genymotion is running on a different host.
|
||||
host: (Platform.OS === 'android' && NativeModules.AndroidConstants) ?
|
||||
NativeModules.AndroidConstants.ServerHost.split(':')[0] :
|
||||
'localhost',
|
||||
// Read the optional global variable for backward compatibility.
|
||||
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
|
||||
port: window.__REACT_DEVTOOLS_PORT__,
|
||||
resolveRNStyle: require('flattenStyle'),
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = setupDevtools;
|
||||
|
|
|
@ -195,8 +195,7 @@ if (__DEV__) {
|
|||
// not when debugging in chrome
|
||||
// TODO(t12832058) This check is broken
|
||||
if (!window.document) {
|
||||
const setupDevtools = require('setupDevtools');
|
||||
setupDevtools();
|
||||
require('setupDevtools');
|
||||
}
|
||||
|
||||
require('RCTDebugComponentOwnership');
|
||||
|
|
|
@ -9,6 +9,7 @@ deps = [
|
|||
react_native_target('java/com/facebook/react/bridge:bridge'),
|
||||
react_native_target('java/com/facebook/react/common:common'),
|
||||
react_native_target('java/com/facebook/react/module/annotations:annotations'),
|
||||
react_native_target('java/com/facebook/react/modules/appstate:appstate'),
|
||||
react_native_target('java/com/facebook/react/modules/core:core'),
|
||||
react_native_target('java/com/facebook/react/modules/datepicker:datepicker'),
|
||||
react_native_target('java/com/facebook/react/modules/share:share'),
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.facebook.react.bridge.UiThreadUtil;
|
|||
import com.facebook.react.bridge.UnexpectedNativeTypeException;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
||||
import com.facebook.react.testing.FakeWebSocketModule;
|
||||
import com.facebook.react.testing.ReactIntegrationTestCase;
|
||||
|
@ -100,6 +101,7 @@ public class CatalystNativeJSToJavaParametersTestCase extends ReactIntegrationTe
|
|||
mCatalystInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(mRecordingTestModule)
|
||||
.addNativeModule(new AndroidInfoModule())
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addNativeModule(mUIManager)
|
||||
.addJSModule(TestJSToJavaParametersModule.class)
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.facebook.react.bridge.WritableArray;
|
|||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.testing.AssertModule;
|
||||
import com.facebook.react.testing.FakeWebSocketModule;
|
||||
import com.facebook.react.testing.ReactIntegrationTestCase;
|
||||
|
@ -77,6 +78,7 @@ public class CatalystNativeJavaToJSArgumentsTestCase extends ReactIntegrationTes
|
|||
|
||||
mInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(mAssertModule)
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addJSModule(TestJavaToJSArgumentsModule.class)
|
||||
.addNativeModule(mUIManager)
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.facebook.react.bridge.WritableArray;
|
|||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.testing.AssertModule;
|
||||
import com.facebook.react.testing.FakeWebSocketModule;
|
||||
|
@ -118,6 +119,7 @@ public class CatalystNativeJavaToJSReturnValuesTestCase extends ReactIntegration
|
|||
|
||||
mInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(mAssertModule)
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addJSModule(TestJavaToJSReturnValuesModule.class)
|
||||
.addNativeModule(mUIManager)
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.widget.TextView;
|
|||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.UIImplementation;
|
||||
|
@ -95,6 +96,7 @@ public class CatalystUIManagerTestCase extends ReactIntegrationTestCase {
|
|||
jsModule = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(uiManager)
|
||||
.addNativeModule(new AndroidInfoModule())
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addJSModule(UIManagerTestModule.class)
|
||||
.build()
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.facebook.react.testing.StringRecordingModule;
|
|||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
@ -61,6 +62,7 @@ public class JSLocaleTest extends ReactIntegrationTestCase {
|
|||
mInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(mStringRecordingModule)
|
||||
.addNativeModule(mUIManager)
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addJSModule(TestJSLocaleModule.class)
|
||||
.build();
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.facebook.react.ReactRootView;
|
|||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
||||
import com.facebook.react.uimanager.UIImplementation;
|
||||
import com.facebook.react.uimanager.UIImplementationProvider;
|
||||
|
@ -86,6 +87,7 @@ public class ProgressBarTestCase extends ReactIntegrationTestCase {
|
|||
mInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(mUIManager)
|
||||
.addNativeModule(new AndroidInfoModule())
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addJSModule(ProgressBarTestModule.class)
|
||||
.build();
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.facebook.react.ReactRootView;
|
|||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.modules.appstate.AppStateModule;
|
||||
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.UIImplementation;
|
||||
|
@ -67,6 +68,7 @@ public class ViewRenderingTestCase extends ReactIntegrationTestCase {
|
|||
mCatalystInstance = ReactTestHelper.catalystInstanceBuilder(this)
|
||||
.addNativeModule(uiManager)
|
||||
.addNativeModule(new AndroidInfoModule())
|
||||
.addNativeModule(new AppStateModule(getContext()))
|
||||
.addNativeModule(new FakeWebSocketModule())
|
||||
.addJSModule(ViewRenderingTestModule.class)
|
||||
.build();
|
||||
|
|
|
@ -69,7 +69,6 @@ function runServer(args, config, readyCallback) {
|
|||
|
||||
wsProxy = webSocketProxy.attachToServer(serverInstance, '/debugger-proxy');
|
||||
ms = messageSocket.attachToServer(serverInstance, '/message');
|
||||
webSocketProxy.attachToServer(serverInstance, '/devtools');
|
||||
inspectorProxy.attachToServer(serverInstance, '/inspector');
|
||||
readyCallback();
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
"plist": "^1.2.0",
|
||||
"promise": "^7.1.1",
|
||||
"react-clone-referenced-element": "^1.0.1",
|
||||
"react-devtools-core": "^2.0.8",
|
||||
"react-timer-mixin": "^0.13.2",
|
||||
"react-transform-hmr": "^1.0.4",
|
||||
"rebound": "^0.0.13",
|
||||
|
|
Loading…
Reference in New Issue