@samitouri / QOS-React / commits / 95f4603e4f

[react-devtools-cdt-mcp] Throw on import from unsupported environment (#36975)

This add an additional validation that the package is imported in a browser-like environment. If not, we should be explicit with the user and throw an error.

Ruslan Lesiutin committed Jul 16, 2026 at 14:42 UTC 95f4603e4f8d28c4094a5bd99509af297abb1cb6
2 files changed +38 -1
packages/react-devtools-cdt-mcp/src/__tests__/DevToolsCdtMcp-test.js
+24
@@ -94,6 +94,30 @@ describe('react-devtools-cdt-mcp', () => {
94 expect(globalThis.__dtmcp).toBeUndefined();
95 });
96
97 + it('throws when the auto entry is imported outside an event target', () => {
98 + const originalAddEventListener = globalThis.addEventListener;
99 + const originalRemoveEventListener = globalThis.removeEventListener;
100 +
101 + unregister();
102 + delete globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
103 + jest.resetModules();
104 +
105 + try {
106 + // $FlowFixMe[cannot-write]
107 + globalThis.addEventListener = undefined;
108 + // $FlowFixMe[cannot-write]
109 + globalThis.removeEventListener = undefined;
110 +
111 + expect(() => require('../index')).toThrow(
112 + 'react-devtools-cdt-mcp must be imported in a browser-like environment',
113 + );
114 + expect(globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__).toBeUndefined();
115 + } finally {
116 + globalThis.addEventListener = originalAddEventListener;
117 + globalThis.removeEventListener = originalRemoveEventListener;
118 + }
119 + });
120 +
121 it('builds a "react" tool group exposing every facade tool', () => {
122 expect(toolGroup.name).toBe('react');
123 expect(typeof toolGroup.description).toBe('string');
packages/react-devtools-cdt-mcp/src/index.js
+14 -1
@@ -11,6 +11,19 @@ import {register} from './DevToolsCdtMcp';
11
12 // Side effect: install the facade (before React) and register the React tool
13 // group for chrome-devtools-mcp. Import this module before React.
14 -register();
14 +if (
15 + typeof window !== 'undefined' &&
16 + typeof window.addEventListener === 'function' &&
17 + typeof window.removeEventListener === 'function'
18 +) {
19 + register();
20 +} else {
21 + // eslint-disable-next-line react-internal/prod-error-codes
22 + throw new Error(
23 + 'react-devtools-cdt-mcp must be imported in a browser-like environment ' +
24 + 'before React initializes. Use a client-only entry point, or the manual ' +
25 + 'entry point for custom targets.',
26 + );
27 +}
28
29 export * from './DevToolsCdtMcp';