From 94e8c4eb63323cc8fb3da3cb34ec4662547f3d3a Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Wed, 27 Mar 2024 12:28:45 +0100 Subject: [PATCH] Use RNIDE prefix instead of rnp for all global variables and custom commands (#40) This PR renames global variables and commants we'd prefixed with "rnp" to be prefixed with "RNIDE". This way they will clearly indicate what projects they are associated with in case of some errors users may see. We are also adding prefix for the navigation integration global method `global.__RNIDE_register_navigation_plugin` as well as adding `global.__RNIDE_enabled` variable to indicate when the app runs inside of the IDE (to be used by external integrations) --- .../vscode-extension/lib/babel_transformer.js | 6 ++--- .../lib/expo_router_plugin.js | 4 ++-- .../vscode-extension/lib/metro_helpers.js | 4 ++-- packages/vscode-extension/lib/preview.js | 4 ++-- packages/vscode-extension/lib/runtime.js | 13 ++++++---- packages/vscode-extension/lib/wrapper.js | 24 +++++++++---------- .../src/debugging/DebugAdapter.ts | 10 ++++---- .../src/project/deviceSession.ts | 12 +++++----- .../vscode-extension/src/project/metro.ts | 4 ++-- .../vscode-extension/src/project/project.ts | 14 +++++------ 10 files changed, 49 insertions(+), 46 deletions(-) diff --git a/packages/vscode-extension/lib/babel_transformer.js b/packages/vscode-extension/lib/babel_transformer.js index 17df07708..a1f40fd8b 100644 --- a/packages/vscode-extension/lib/babel_transformer.js +++ b/packages/vscode-extension/lib/babel_transformer.js @@ -23,12 +23,12 @@ disablePlugin("@babel/plugin-transform-react-jsx-development"); function transformWrapper({ filename, src, plugins, ...rest }) { const { transform } = require(ORIGINAL_TRANSFORMER_PATH); if (filename.endsWith("node_modules/react-native/Libraries/Core/InitializeCore.js")) { - src = `${src};require("__rnp_lib__/runtime.js");`; + src = `${src};require("__RNIDE_lib__/runtime.js");`; } else if (filename.endsWith("node_modules/expo-router/entry.js")) { // expo-router v2 integration - src = `${src};require("__rnp_lib__/expo_router_plugin.js");`; + src = `${src};require("__RNIDE_lib__/expo_router_plugin.js");`; } else if (filename.endsWith("node_modules/react-native-ide/index.js")) { - src = `${src};preview = require("__rnp_lib__/preview.js").preview;`; + src = `${src};preview = require("__RNIDE_lib__/preview.js").preview;`; } const newPlugins = [ diff --git a/packages/vscode-extension/lib/expo_router_plugin.js b/packages/vscode-extension/lib/expo_router_plugin.js index 5c000fe65..146d86f89 100644 --- a/packages/vscode-extension/lib/expo_router_plugin.js +++ b/packages/vscode-extension/lib/expo_router_plugin.js @@ -40,5 +40,5 @@ function useRouterPluginMainHook({ onNavigationChange }) { }; } -global.__register_navigation_plugin && - global.__register_navigation_plugin("expo-router", { mainHook: useRouterPluginMainHook }); +global.__RNIDE_register_navigation_plugin && + global.__RNIDE_register_navigation_plugin("expo-router", { mainHook: useRouterPluginMainHook }); diff --git a/packages/vscode-extension/lib/metro_helpers.js b/packages/vscode-extension/lib/metro_helpers.js index cf8b8c3b7..287d25bb4 100644 --- a/packages/vscode-extension/lib/metro_helpers.js +++ b/packages/vscode-extension/lib/metro_helpers.js @@ -59,7 +59,7 @@ function adaptMetroConfig(config) { // Currently used for runtime and wrapper functionalities config.resolver.extraNodeModules = { ...config.resolver.extraNodeModules, - __rnp_lib__: extensionLib, + __RNIDE_lib__: extensionLib, }; // This code is needed to properly resolve modules @@ -92,7 +92,7 @@ function metroServerReadyHandler(originalOnReadyHandler) { process.env.EXPO_PACKAGER_PROXY_URL = process.env.EXPO_MANIFEST_PROXY_URL = `http://localhost:${port}`; originalOnReadyHandler && originalOnReadyHandler(server, ...args); - process.stdout.write(JSON.stringify({ type: "rnp_initialize_done", port })); + process.stdout.write(JSON.stringify({ type: "RNIDE_initialize_done", port })); process.stdout.write("\n"); }; } diff --git a/packages/vscode-extension/lib/preview.js b/packages/vscode-extension/lib/preview.js index 393aa53cc..2564c04b1 100644 --- a/packages/vscode-extension/lib/preview.js +++ b/packages/vscode-extension/lib/preview.js @@ -1,7 +1,7 @@ require("expo-router/entry"); const { AppRegistry, View } = require("react-native"); -global.__rnp_previews ||= new Map(); +global.__RNIDE_previews ||= new Map(); function stringifyProps(obj) { const keyValuePairs = []; @@ -26,7 +26,7 @@ export function preview(component) { {component} ); } - global.__rnp_previews.set(name, { + global.__RNIDE_previews.set(name, { appKey: name, name: component.type.name, props: stringifyProps(component.props), diff --git a/packages/vscode-extension/lib/runtime.js b/packages/vscode-extension/lib/runtime.js index 761d4789f..b916dc985 100644 --- a/packages/vscode-extension/lib/runtime.js +++ b/packages/vscode-extension/lib/runtime.js @@ -5,14 +5,14 @@ const AppRegistry = require("react-native/Libraries/ReactNative/AppRegistry"); const parseErrorStack = require("react-native/Libraries/Core/Devtools/parseErrorStack"); -function __rnpBreakOnError(error, isFatal) { +function __RNIDE_breakOnError(error, isFatal) { // the below variables are accessed from the debugger and hence are necessary despite being unused in the code const message = error.message; const stack = parseErrorStack(error.stack); debugger; } -global.ErrorUtils.setGlobalHandler(__rnpBreakOnError); +global.ErrorUtils.setGlobalHandler(__RNIDE_breakOnError); global.__fbDisableExceptionsManager = true; @@ -30,10 +30,13 @@ console.warn = wrapConsole(console.warn); console.error = wrapConsole(console.error); console.info = wrapConsole(console.info); -global.__register_navigation_plugin = function (name, plugin) { - require("__rnp_lib__/wrapper.js").registerNavigationPlugin(name, plugin); +// This variable can be used by external integrations to detect if they are running in the IDE +global.__RNIDE_enabled = true; + +global.__RNIDE_register_navigation_plugin = function (name, plugin) { + require("__RNIDE_lib__/wrapper.js").registerNavigationPlugin(name, plugin); }; AppRegistry.setWrapperComponentProvider((appParameters) => { - return require("__rnp_lib__/wrapper.js").PreviewAppWrapper; + return require("__RNIDE_lib__/wrapper.js").PreviewAppWrapper; }); diff --git a/packages/vscode-extension/lib/wrapper.js b/packages/vscode-extension/lib/wrapper.js index cdcaa609f..bad7112a1 100644 --- a/packages/vscode-extension/lib/wrapper.js +++ b/packages/vscode-extension/lib/wrapper.js @@ -29,7 +29,7 @@ export function PreviewAppWrapper({ children, ...rest }) { const handleNavigationChange = useCallback((navigationDescriptor) => { navigationHistory.set(navigationDescriptor.id, navigationDescriptor); agent && - agent._bridge.send("rnp_navigationChanged", { + agent._bridge.send("RNIDE_navigationChanged", { displayName: navigationDescriptor.name, id: navigationDescriptor.id, }); @@ -69,7 +69,7 @@ export function PreviewAppWrapper({ children, ...rest }) { }); } - agent._bridge.addListener("rnp_openPreview", (payload) => { + agent._bridge.addListener("RNIDE_openPreview", (payload) => { openPreview(payload.previewId); }); @@ -83,13 +83,13 @@ export function PreviewAppWrapper({ children, ...rest }) { } } - agent._bridge.addListener("rnp_openUrl", (payload) => { + agent._bridge.addListener("RNIDE_openUrl", (payload) => { closePreview(); const url = payload.url; Linking.openURL(url); }); - agent._bridge.addListener("rnp_openNavigation", (payload) => { + agent._bridge.addListener("RNIDE_openNavigation", (payload) => { if (isPreviewUrl(payload.id)) { openPreview(payload.id); return; @@ -99,7 +99,7 @@ export function PreviewAppWrapper({ children, ...rest }) { navigationDescriptor && requestNavigationChange(navigationDescriptor); }); - agent._bridge.addListener("rnp_inspect", (payload) => { + agent._bridge.addListener("RNIDE_inspect", (payload) => { const { width, height } = Dimensions.get("screen"); getInspectorDataForViewAtPoint( mainContainerRef.current, @@ -116,7 +116,7 @@ export function PreviewAppWrapper({ children, ...rest }) { const hierarchy = viewData.hierarchy.map((item) => { return { name: item.name, source: item.getInspectorData().source }; }); - agent._bridge.send("rnp_inspectData", { + agent._bridge.send("RNIDE_inspectData", { id: payload.id, frame: scaledFrame, hierarchy, @@ -125,7 +125,7 @@ export function PreviewAppWrapper({ children, ...rest }) { ); }); - agent._bridge.addListener("rnp_editorFileChanged", (payload) => { + agent._bridge.addListener("RNIDE_editorFileChanged", (payload) => { const newRoute = handleActiveFileChange(payload.filename, payload.followEnabled); newRoute && push(newRoute); }); @@ -133,10 +133,10 @@ export function PreviewAppWrapper({ children, ...rest }) { LogBox.uninstall(); const LoadingView = require("react-native/Libraries/Utilities/LoadingView"); LoadingView.showMessage = (message) => { - agent._bridge.send("rnp_fastRefreshStarted"); + agent._bridge.send("RNIDE_fastRefreshStarted"); }; LoadingView.hide = () => { - agent._bridge.send("rnp_fastRefreshComplete"); + agent._bridge.send("RNIDE_fastRefreshComplete"); }; // console.reportErrorsAsExceptions = false; @@ -162,15 +162,15 @@ export function PreviewAppWrapper({ children, ...rest }) { const sceneName = SceneTracker.getActiveScene().name; if (!appReadyEventSent.current) { appReadyEventSent.current = true; - agent._bridge.send("rnp_appReady", { + agent._bridge.send("RNIDE_appReady", { appKey: sceneName, navigationPlugins: navigationPlugins.map((plugin) => plugin.name), }); } const isRunningPreview = isPreviewUrl(sceneName); if (isRunningPreview) { - const preview = (global.__rnp_previews || new Map()).get(sceneName); - agent._bridge.send("rnp_navigationChanged", { + const preview = (global.__RNIDE_previews || new Map()).get(sceneName); + agent._bridge.send("RNIDE_navigationChanged", { displayName: `preview:${preview.name}`, // TODO: make names unique if there are multiple previews of the same component id: sceneName, }); diff --git a/packages/vscode-extension/src/debugging/DebugAdapter.ts b/packages/vscode-extension/src/debugging/DebugAdapter.ts index 9ea521158..5578376cc 100644 --- a/packages/vscode-extension/src/debugging/DebugAdapter.ts +++ b/packages/vscode-extension/src/debugging/DebugAdapter.ts @@ -175,7 +175,7 @@ export class DebugAdapter extends DebugSession { outputEvent = new OutputEvent(output + "\n", typeToCategory(message.params.type)); } this.sendEvent(outputEvent); - this.sendEvent(new Event("rnp_consoleLog", { category: outputEvent.body.category })); + this.sendEvent(new Event("RNIDE_consoleLog", { category: outputEvent.body.category })); } private findOriginalPosition( @@ -261,7 +261,7 @@ export class DebugAdapter extends DebugSession { this.pausedDAPtoCDPObjectIdMap = new Map(); if ( message.params.reason === "other" && - message.params.callFrames[0].functionName === "__rnpBreakOnError" + message.params.callFrames[0].functionName === "__RNIDE_breakOnError" ) { // this is a workaround for an issue with hermes which does not provide a full stack trace // when it pauses due to the uncaught exception. Instead, we trigger debugger pause from exception @@ -311,7 +311,7 @@ export class DebugAdapter extends DebugSession { ); this.pausedStackFrames = stackFrames; this.sendEvent(new StoppedEvent("exception", this.threads[0].id, errorMessage)); - this.sendEvent(new Event("rnp_paused", { reason: "exception", isFatal: isFatal })); + this.sendEvent(new Event("RNIDE_paused", { reason: "exception", isFatal: isFatal })); } else { this.pausedStackFrames = message.params.callFrames.map((cdpFrame: any, index: number) => { const cdpLocation = cdpFrame.location; @@ -333,7 +333,7 @@ export class DebugAdapter extends DebugSession { (cdpFrame: any) => cdpFrame.scopeChain ); this.sendEvent(new StoppedEvent("breakpoint", this.threads[0].id, "Yollo")); - this.sendEvent(new Event("rnp_paused")); + this.sendEvent(new Event("RNIDE_paused")); } } @@ -563,7 +563,7 @@ export class DebugAdapter extends DebugSession { ): Promise { await this.sendCDPMessage("Debugger.resume", { terminateOnResume: false }); this.sendResponse(response); - this.sendEvent(new Event("rnp_continued")); + this.sendEvent(new Event("RNIDE_continued")); } protected async nextRequest( diff --git a/packages/vscode-extension/src/project/deviceSession.ts b/packages/vscode-extension/src/project/deviceSession.ts index a950e63bb..e27981f40 100644 --- a/packages/vscode-extension/src/project/deviceSession.ts +++ b/packages/vscode-extension/src/project/deviceSession.ts @@ -34,7 +34,7 @@ export class DeviceSession implements Disposable { async start(deviceSettings: DeviceSettings, progressCallback: ProgressCallback) { const waitForAppReady = new Promise((res) => { const listener = (event: string, payload: any) => { - if (event === "rnp_appReady") { + if (event === "RNIDE_appReady") { this.devtools?.removeListener(listener); res(); } @@ -112,25 +112,25 @@ export class DeviceSession implements Disposable { public inspectElementAt(xRatio: number, yRatio: number, callback: (inspecData: any) => void) { const id = this.inspectCallID++; const listener = (event: string, payload: any) => { - if (event === "rnp_inspectData" && payload.id === id) { + if (event === "RNIDE_inspectData" && payload.id === id) { this.devtools?.removeListener(listener); callback(payload); } }; this.devtools?.addListener(listener); - this.devtools.send("rnp_inspect", { x: xRatio, y: yRatio, id }); + this.devtools.send("RNIDE_inspect", { x: xRatio, y: yRatio, id }); } public openNavigation(id: string) { - this.devtools.send("rnp_openNavigation", { id }); + this.devtools.send("RNIDE_openNavigation", { id }); } public startPreview(previewId: string) { - this.devtools.send("rnp_openPreview", { previewId }); + this.devtools.send("RNIDE_openPreview", { previewId }); } public onActiveFileChange(filename: string, followEnabled: boolean) { - this.devtools.send("rnp_editorFileChanged", { filename, followEnabled }); + this.devtools.send("RNIDE_editorFileChanged", { filename, followEnabled }); } public async changeDeviceSettings(settings: DeviceSettings) { diff --git a/packages/vscode-extension/src/project/metro.ts b/packages/vscode-extension/src/project/metro.ts index 6bb5db39d..09cf80b9f 100644 --- a/packages/vscode-extension/src/project/metro.ts +++ b/packages/vscode-extension/src/project/metro.ts @@ -35,7 +35,7 @@ type MetroEvent = totalFileCount: number; } | { - type: "rnp_initialize_done"; + type: "RNIDE_initialize_done"; port: number; } | { @@ -177,7 +177,7 @@ export class Metro implements Disposable { } switch (event.type) { - case "rnp_initialize_done": + case "RNIDE_initialize_done": this._port = event.port; Logger.info(`Metro started on port ${this._port}`); resolve(); diff --git a/packages/vscode-extension/src/project/project.ts b/packages/vscode-extension/src/project/project.ts index fe1b5b5ac..7c136b459 100644 --- a/packages/vscode-extension/src/project/project.ts +++ b/packages/vscode-extension/src/project/project.ts @@ -163,23 +163,23 @@ export class Project implements Disposable, MetroDelegate, ProjectInterface { } this.devtools.addListener((event, payload) => { switch (event) { - case "rnp_appReady": + case "RNIDE_appReady": Logger.debug("App ready"); if (this.reloadingMetro) { this.reloadingMetro = false; this.updateProjectState({ status: "running" }); } break; - case "rnp_navigationChanged": + case "RNIDE_navigationChanged": this.eventEmitter.emit("navigationChanged", { displayName: payload.displayName, id: payload.id, }); break; - case "rnp_fastRefreshStarted": + case "RNIDE_fastRefreshStarted": this.updateProjectState({ status: "refreshing" }); break; - case "rnp_fastRefreshComplete": + case "RNIDE_fastRefreshComplete": if (this.projectState.status === "starting") return; if (this.projectState.status === "incrementalBundleError") return; if (this.projectState.status === "runtimeError") return; @@ -193,10 +193,10 @@ export class Project implements Disposable, MetroDelegate, ProjectInterface { this.debugSessionListener?.dispose(); this.debugSessionListener = debug.onDidReceiveDebugSessionCustomEvent((event) => { switch (event.event) { - case "rnp_consoleLog": + case "RNIDE_consoleLog": this.eventEmitter.emit("log", event.body); break; - case "rnp_paused": + case "RNIDE_paused": if (event.body?.reason === "exception") { // if we know that incrmental bundle error happened, we don't want to change the status if (this.projectState.status === "incrementalBundleError") return; @@ -206,7 +206,7 @@ export class Project implements Disposable, MetroDelegate, ProjectInterface { } commands.executeCommand("workbench.view.debug"); break; - case "rnp_continued": + case "RNIDE_continued": this.updateProjectState({ status: "running" }); break; }