Repository: facebook/react
Pull request: [DevTools] Standalone registers logger and reports logs under feature flag

## Summary

This commit implements an event logger for the standalone DevTools (`react-devtools-core/standalone`), which will report events that are logged from the DevTools runtime to an iframe that knows how to process those events. Note that this will **only happen when the `enableLogger` feature flag is enabled**, which will only be enabled for internal (fb-only) builds of DevTools.

## How did you test this change?

- yarn flow
- yarn test
- yarn test-build-devtools
- built standalone app with `enableLogger` feature flag enabled and verified that logger was registered and events were correctly communicated to iframe that loads an internal endpoint.


Changed files:
filename: packages/react-devtools-core/src/standalone.js
patch: @@ -23,6 +23,7 @@ import {
   getShowInlineWarningsAndErrors,
   getHideConsoleLogsInStrictMode,
 } from 'react-devtools-shared/src/utils';
+import {registerDevToolsEventLogger} from 'react-devtools-shared/src/registerDevToolsEventLogger';
 import {Server} from 'ws';
 import {join} from 'path';
 import {readFileSync} from 'fs';
@@ -255,16 +256,23 @@ function connectToSocket(socket: WebSocket) {
   };
 }
 
-type ServerOptions = {
+type ServerOptions = {|
   key?: string,
   cert?: string,
-};
+|};
+
+type LoggerOptions = {|
+  surface?: ?string,
+|};
 
 function startServer(
   port?: number = 8097,
   host?: string = 'localhost',
   httpsOptions?: ServerOptions,
+  loggerOptions?: LoggerOptions,
 ) {
+  registerDevToolsEventLogger(loggerOptions?.surface ?? 'standalone');
+
   const useHttps = !!httpsOptions;
   const httpServer = useHttps
     ? require('https').createServer(httpsOptions)

filename: packages/react-devtools-core/webpack.standalone.js
patch: @@ -30,6 +30,8 @@ const __DEV__ = NODE_ENV === 'development';
 
 const DEVTOOLS_VERSION = getVersionString();
 
+const LOGGING_URL = process.env.LOGGING_URL || null;
+
 const featureFlagTarget =
   process.env.FEATURE_FLAG_TARGET || 'core/standalone-oss';
 
@@ -82,6 +84,7 @@ module.exports = {
       'process.env.DEVTOOLS_PACKAGE': `"react-devtools-core"`,
       'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
       'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
+      'process.env.LOGGING_URL': `"${LOGGING_URL}"`,
       'process.env.NODE_ENV': `"${NODE_ENV}"`,
       'process.env.DARK_MODE_DIMMED_WARNING_COLOR': `"${DARK_MODE_DIMMED_WARNING_COLOR}"`,
       'process.env.DARK_MODE_DIMMED_ERROR_COLOR': `"${DARK_MODE_DIMMED_ERROR_COLOR}"`,

filename: packages/react-devtools-extensions/src/main.js
patch: @@ -6,6 +6,7 @@ import Bridge from 'react-devtools-shared/src/bridge';
 import Store from 'react-devtools-shared/src/devtools/store';
 import {getBrowserName, getBrowserTheme} from './utils';
 import {LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY} from 'react-devtools-shared/src/constants';
+import {registerDevToolsEventLogger} from 'react-devtools-shared/src/registerDevToolsEventLogger';
 import {
   getAppendComponentStack,
   getBreakOnConsoleErrors,
@@ -20,7 +21,6 @@ import {
 } from 'react-devtools-shared/src/storage';
 import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
 import {__DEBUG__} from 'react-devtools-shared/src/constants';
-import {registerExtensionsEventLogger} from './registerExtensionsEventLogger';
 import {logEvent} from 'react-devtools-shared/src/Logger';
 
 const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY =
@@ -89,7 +89,7 @@ function createPanelIfReactLoaded() {
 
       const tabId = chrome.devtools.inspectedWindow.tabId;
 
-      registerExtensionsEventLogger();
+      registerDevToolsEventLogger('extension');
 
       function initBridgeAndStore() {
         const port = chrome.runtime.connect({

filename: packages/react-devtools-shared/src/config/DevToolsFeatureFlags.core-fb.js
patch: @@ -16,7 +16,7 @@
 export const enableProfilerChangedHookIndices = true;
 export const isInternalFacebookBuild = true;
 export const enableNamedHooksFeature = true;
-export const enableLogger = false;
+export const enableLogger = true;
 export const consoleManagedByDevToolsDuringStrictMode = false;
 
 /************************************************************************

filename: packages/react-devtools-shared/src/registerDevToolsEventLogger.js
patch: @@ -14,38 +14,39 @@ import {enableLogger} from 'react-devtools-feature-flags';
 
 let loggingIFrame = null;
 let missedEvents = [];
-function logEvent(event: LogEvent) {
-  if (enableLogger) {
-    if (loggingIFrame != null) {
-      loggingIFrame.contentWindow.postMessage(
-        {
-          source: 'react-devtools-logging',
-          event: event,
-          context: {
-            surface: 'extension',
+
+export function registerDevToolsEventLogger(surface: string) {
+  function logEvent(event: LogEvent) {
+    if (enableLogger) {
+      if (loggingIFrame != null) {
+        loggingIFrame.contentWindow.postMessage(
+          {
+            source: 'react-devtools-logging',
+            event: event,
+            context: {
+              surface,
+            },
           },
-        },
-        '*',
-      );
-    } else {
-      missedEvents.push(event);
+          '*',
+        );
+      } else {
+        missedEvents.push(event);
+      }
     }
   }
-}
 
-function handleLoggingIFrameLoaded(iframe) {
-  if (loggingIFrame != null) {
-    return;
-  }
+  function handleLoggingIFrameLoaded(iframe) {
+    if (loggingIFrame != null) {
+      return;
+    }
 
-  loggingIFrame = iframe;
-  if (missedEvents.length > 0) {
-    missedEvents.forEach(logEvent);
-    missedEvents = [];
+    loggingIFrame = iframe;
+    if (missedEvents.length > 0) {
+      missedEvents.forEach(logEvent);
+      missedEvents = [];
+    }
   }
-}
 
-export function registerExtensionsEventLogger() {
   // If logger is enabled, register a logger that captures logged events
   // and render iframe where the logged events will be reported to
   if (enableLogger) {