Skip to content

Commit 730b540

Browse files
committed
Stop exporting dev-only methods production builds
1 parent 028c8e6 commit 730b540

File tree

10 files changed

+166
-39
lines changed

10 files changed

+166
-39
lines changed

packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -779,13 +779,10 @@ function runActTests(render, unmount, rerender) {
779779
});
780780
}
781781
});
782-
describe('throw in prod mode', () => {
783-
// @gate !__DEV__
784-
it('warns if you try to use act() in prod mode', () => {
785-
expect(() => act(() => {})).toThrow(
786-
'act(...) is not supported in production builds of React',
787-
);
788-
});
782+
783+
// @gate !__DEV__
784+
it('is not available in prod mode', () => {
785+
expect(() => act(() => {})).toThrow('act is not a function');
789786
});
790787
});
791788
}

packages/react-reconciler/src/__tests__/ReactIsomorphicAct-test.js

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ describe('isomorphic act()', () => {
5050
return text;
5151
}
5252

53+
// @gate !__DEV__
54+
it('is not exported in production builds', () => {
55+
expect(React).not.toHaveProperty('act');
56+
});
57+
5358
// @gate __DEV__
5459
it('bypasses queueMicrotask', async () => {
5560
const root = ReactNoop.createRoot();

packages/react-reconciler/src/__tests__/ReactOwnerStacks-test.js

+5
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ describe('ReactOwnerStacks', () => {
3131
);
3232
}
3333

34+
// @gate !__DEV__ || !enableOwnerStacks
35+
it('is not exported in production buids', () => {
36+
expect(React).not.toHaveProperty('captureOwnerStack');
37+
});
38+
3439
// @gate __DEV__ && enableOwnerStacks
3540
it('can get the component owner stacks during rendering in dev', async () => {
3641
let stack;
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
import {enableOwnerStacks} from 'shared/ReactFeatureFlags';
10+
import {captureOwnerStack as captureOwnerStackImpl} from './src/ReactClient';
11+
12+
export {
13+
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
14+
__COMPILER_RUNTIME,
15+
cache,
16+
Children,
17+
cloneElement,
18+
Component,
19+
createContext,
20+
createElement,
21+
createRef,
22+
experimental_useEffectEvent,
23+
experimental_useResourceEffect,
24+
forwardRef,
25+
Fragment,
26+
isValidElement,
27+
lazy,
28+
memo,
29+
Profiler,
30+
PureComponent,
31+
startTransition,
32+
StrictMode,
33+
Suspense,
34+
unstable_Activity,
35+
unstable_getCacheForType,
36+
unstable_LegacyHidden,
37+
unstable_Scope,
38+
unstable_SuspenseList,
39+
unstable_TracingMarker,
40+
unstable_useCacheRefresh,
41+
use,
42+
useActionState,
43+
useCallback,
44+
useContext,
45+
useDebugValue,
46+
useDeferredValue,
47+
useEffect,
48+
useId,
49+
useImperativeHandle,
50+
useInsertionEffect,
51+
useLayoutEffect,
52+
useMemo,
53+
useOptimistic,
54+
useReducer,
55+
useRef,
56+
useState,
57+
useSyncExternalStore,
58+
useTransition,
59+
version,
60+
act, // DEV-only
61+
} from './src/ReactClient';
62+
63+
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';
64+
65+
// export for backwards compatibility during upgrade
66+
export {useMemoCache as unstable_useMemoCache} from './src/ReactHooks';
67+
68+
// export to match the name of the OSS function typically exported from
69+
// react/compiler-runtime
70+
export {useMemoCache as c} from './src/ReactHooks';
71+
72+
// Only export captureOwnerStack in development.
73+
let captureOwnerStack: ?() => null | string;
74+
if (enableOwnerStacks) {
75+
captureOwnerStack = captureOwnerStackImpl;
76+
}
77+
78+
// DEV-only
79+
export {captureOwnerStack};

packages/react/index.fb.js

-11
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
* @flow
88
*/
99

10-
import {enableOwnerStacks} from 'shared/ReactFeatureFlags';
11-
import {captureOwnerStack as captureOwnerStackImpl} from './src/ReactClient';
1210
export {
1311
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
1412
__COMPILER_RUNTIME,
15-
act,
1613
cache,
1714
Children,
1815
cloneElement,
@@ -68,11 +65,3 @@ export {useMemoCache as unstable_useMemoCache} from './src/ReactHooks';
6865
// export to match the name of the OSS function typically exported from
6966
// react/compiler-runtime
7067
export {useMemoCache as c} from './src/ReactHooks';
71-
72-
// Only export captureOwnerStack in development.
73-
let captureOwnerStack: ?() => null | string;
74-
if (__DEV__ && enableOwnerStacks) {
75-
captureOwnerStack = captureOwnerStackImpl;
76-
}
77-
78-
export {captureOwnerStack};

packages/react/index.js

-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ export type ElementRef<C> = React$ElementRef<C>;
2323
export type Config<Props, DefaultProps> = React$Config<Props, DefaultProps>;
2424
export type ChildrenArray<+T> = $ReadOnlyArray<ChildrenArray<T>> | T;
2525

26-
// Export all exports so that they're available in tests.
27-
// We can't use export * from in Flow for some reason.
2826
export {
2927
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
3028
__COMPILER_RUNTIME,
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
export {
11+
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
12+
__COMPILER_RUNTIME,
13+
Children,
14+
Component,
15+
Fragment,
16+
Profiler,
17+
PureComponent,
18+
StrictMode,
19+
Suspense,
20+
cloneElement,
21+
createContext,
22+
createElement,
23+
createRef,
24+
use,
25+
forwardRef,
26+
isValidElement,
27+
lazy,
28+
memo,
29+
cache,
30+
unstable_useCacheRefresh,
31+
startTransition,
32+
useId,
33+
useCallback,
34+
useContext,
35+
useDebugValue,
36+
useDeferredValue,
37+
useEffect,
38+
useImperativeHandle,
39+
useInsertionEffect,
40+
useLayoutEffect,
41+
useMemo,
42+
useReducer,
43+
useOptimistic,
44+
useRef,
45+
useState,
46+
useSyncExternalStore,
47+
useTransition,
48+
useActionState,
49+
version,
50+
act, // DEV-only
51+
} from './src/ReactClient';

packages/react/index.stable.js

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
export {
1111
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
1212
__COMPILER_RUNTIME,
13-
act,
1413
Children,
1514
Component,
1615
Fragment,

scripts/jest/setupHostConfigs.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ function resolveEntryFork(resolvedEntry, isFBBundle) {
4343
}
4444

4545
resolvedEntry = nodePath.join(resolvedEntry, '..', entrypoint);
46-
const developmentEntry = resolvedEntry.replace('.js', '.development.js');
47-
if (fs.existsSync(developmentEntry)) {
48-
return developmentEntry;
46+
const devEntry = resolvedEntry.replace('.js', '.development.js');
47+
if (__DEV__ && fs.existsSync(devEntry)) {
48+
return devEntry;
4949
}
5050
if (fs.existsSync(resolvedEntry)) {
5151
return resolvedEntry;
@@ -60,13 +60,20 @@ function resolveEntryFork(resolvedEntry, isFBBundle) {
6060
__EXPERIMENTAL__ ? '.modern.fb.js' : '.classic.fb.js'
6161
);
6262
const devFBEntry = resolvedFBEntry.replace('.js', '.development.js');
63-
if (fs.existsSync(devFBEntry)) {
63+
if (__DEV__ && fs.existsSync(devFBEntry)) {
6464
return devFBEntry;
6565
}
6666
if (fs.existsSync(resolvedFBEntry)) {
6767
return resolvedFBEntry;
6868
}
6969
const resolvedGenericFBEntry = resolvedEntry.replace('.js', '.fb.js');
70+
const devGenericFBEntry = resolvedGenericFBEntry.replace(
71+
'.js',
72+
'.development.js'
73+
);
74+
if (__DEV__ && fs.existsSync(devGenericFBEntry)) {
75+
return devGenericFBEntry;
76+
}
7077
if (fs.existsSync(resolvedGenericFBEntry)) {
7178
return resolvedGenericFBEntry;
7279
}
@@ -77,14 +84,14 @@ function resolveEntryFork(resolvedEntry, isFBBundle) {
7784
__EXPERIMENTAL__ ? '.experimental.js' : '.stable.js'
7885
);
7986
const devForkedEntry = resolvedForkedEntry.replace('.js', '.development.js');
80-
if (fs.existsSync(devForkedEntry)) {
87+
if (__DEV__ && fs.existsSync(devForkedEntry)) {
8188
return devForkedEntry;
8289
}
8390
if (fs.existsSync(resolvedForkedEntry)) {
8491
return resolvedForkedEntry;
8592
}
8693
const plainDevEntry = resolvedEntry.replace('.js', '.development.js');
87-
if (fs.existsSync(plainDevEntry)) {
94+
if (__DEV__ && fs.existsSync(plainDevEntry)) {
8895
return plainDevEntry;
8996
}
9097
// Just use the plain .js one.

scripts/rollup/build.js

+9-12
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ function shouldSkipBundle(bundle, bundleType) {
571571
return false;
572572
}
573573

574-
function resolveEntryFork(resolvedEntry, isFBBundle) {
574+
function resolveEntryFork(resolvedEntry, isFBBundle, isDev) {
575575
// Pick which entry point fork to use:
576576
// .modern.fb.js
577577
// .classic.fb.js
@@ -586,23 +586,20 @@ function resolveEntryFork(resolvedEntry, isFBBundle) {
586586
'.js',
587587
__EXPERIMENTAL__ ? '.modern.fb.js' : '.classic.fb.js'
588588
);
589-
const developmentFBEntry = resolvedFBEntry.replace(
590-
'.js',
591-
'.development.js'
592-
);
593-
if (fs.existsSync(developmentFBEntry)) {
594-
return developmentFBEntry;
589+
const devFBEntry = resolvedFBEntry.replace('.js', '.development.js');
590+
if (isDev && fs.existsSync(devFBEntry)) {
591+
return devFBEntry;
595592
}
596593
if (fs.existsSync(resolvedFBEntry)) {
597594
return resolvedFBEntry;
598595
}
599596
const resolvedGenericFBEntry = resolvedEntry.replace('.js', '.fb.js');
600-
const developmentGenericFBEntry = resolvedGenericFBEntry.replace(
597+
const devGenericFBEntry = resolvedGenericFBEntry.replace(
601598
'.js',
602599
'.development.js'
603600
);
604-
if (fs.existsSync(developmentGenericFBEntry)) {
605-
return developmentGenericFBEntry;
601+
if (isDev && fs.existsSync(devGenericFBEntry)) {
602+
return devGenericFBEntry;
606603
}
607604
if (fs.existsSync(resolvedGenericFBEntry)) {
608605
return resolvedGenericFBEntry;
@@ -614,7 +611,7 @@ function resolveEntryFork(resolvedEntry, isFBBundle) {
614611
__EXPERIMENTAL__ ? '.experimental.js' : '.stable.js'
615612
);
616613
const devForkedEntry = resolvedForkedEntry.replace('.js', '.development.js');
617-
if (fs.existsSync(devForkedEntry)) {
614+
if (isDev && fs.existsSync(devForkedEntry)) {
618615
return devForkedEntry;
619616
}
620617
if (fs.existsSync(resolvedForkedEntry)) {
@@ -633,7 +630,7 @@ async function createBundle(bundle, bundleType) {
633630

634631
const {isFBWWWBundle, isFBRNBundle} = getBundleTypeFlags(bundleType);
635632

636-
let resolvedEntry = resolveEntryFork(
633+
const resolvedEntry = resolveEntryFork(
637634
require.resolve(bundle.entry),
638635
isFBWWWBundle || isFBRNBundle,
639636
!isProductionBundleType(bundleType)

0 commit comments

Comments
 (0)