diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js new file mode 100644 index 0000000000000..63f75e83b7656 --- /dev/null +++ b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + */ + +import typeof * as ExportsType from './ReactFeatureFlags.native-fb-dynamic'; +import typeof * as DynamicFlagsType from 'ReactNativeInternalFeatureFlags'; + +// In xplat, these flags are controlled by GKs. Because most GKs have some +// population running in either mode, we should run our tests that way, too, +// +// Use __VARIANT__ to simulate a GK. The tests will be run twice: once +// with the __VARIANT__ set to `true`, and once set to `false`. +// +// TODO: __VARIANT__ isn't supported for React Native flags yet. You can set the +// flag here but it won't be set to `true` in any of our test runs. Need to +// update the test configuration. + +export const enablePersistentOffscreenHostContainer = __VARIANT__; + +// Flow magic to verify the exports of this file match the original version. +// eslint-disable-next-line no-unused-vars +type Check<_X, Y: _X, X: Y = _X> = null; +// eslint-disable-next-line no-unused-expressions +(null: Check); diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 8d0a2256ec7d2..f6ab60d3ed642 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -10,6 +10,14 @@ import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as ExportsType from './ReactFeatureFlags.native-fb'; +// Re-export dynamic flags from the internal module. Intentionally using * +// because this import is compiled to a `require` call. +import * as dynamicFlags from 'ReactNativeInternalFeatureFlags'; + +// We destructure each value before re-exporting to avoid a dynamic look-up on +// the exports object every time a flag is read. +export const {enablePersistentOffscreenHostContainer} = dynamicFlags; + // The rest of the flags are static for better dead code elimination. export const enableDebugTracing = false; export const enableSchedulingProfiler = false; @@ -60,8 +68,6 @@ export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableSyncDefaultUpdates = true; export const allowConcurrentByDefault = true; -// TODO: Import this from internal ReactNativeFeatureFlags instead -export const enablePersistentOffscreenHostContainer = __EXPERIMENTAL__; // Flow magic to verify the exports of this file match the original version. // eslint-disable-next-line no-unused-vars diff --git a/scripts/flow/config/flowconfig b/scripts/flow/config/flowconfig index ada7f2207be5c..2ace94c2d7cba 100644 --- a/scripts/flow/config/flowconfig +++ b/scripts/flow/config/flowconfig @@ -34,6 +34,7 @@ ./scripts/flow/react-devtools.js ./scripts/flow/react-native-host-hooks.js ./scripts/flow/react-relay-hooks.js +./scripts/flow/xplat.js [lints] untyped-type-import=error diff --git a/scripts/flow/xplat.js b/scripts/flow/xplat.js new file mode 100644 index 0000000000000..c013af3e125d8 --- /dev/null +++ b/scripts/flow/xplat.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +declare module 'ReactNativeInternalFeatureFlags' { + declare export var enablePersistentOffscreenHostContainer: boolean; +} diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index fb64c0e6e07f4..54c0552ba5649 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -79,7 +79,7 @@ const bundles = [ moduleType: ISOMORPHIC, entry: 'react', global: 'React', - externals: [], + externals: ['ReactNativeInternalFeatureFlags'], }, /******* Isomorphic Shared Subset *******/ @@ -105,7 +105,7 @@ const bundles = [ moduleType: ISOMORPHIC, entry: 'react/jsx-runtime', global: 'JSXRuntime', - externals: ['react'], + externals: ['react', 'ReactNativeInternalFeatureFlags'], }, /******* React JSX DEV Runtime *******/ @@ -124,7 +124,7 @@ const bundles = [ moduleType: ISOMORPHIC, entry: 'react/jsx-dev-runtime', global: 'JSXDEVRuntime', - externals: ['react'], + externals: ['react', 'ReactNativeInternalFeatureFlags'], }, /******* React Fetch Browser (experimental, new) *******/ @@ -372,6 +372,7 @@ const bundles = [ 'react', 'ReactFlightNativeRelayServerIntegration', 'JSResourceReferenceImpl', + 'ReactNativeInternalFeatureFlags', ], }, @@ -385,6 +386,7 @@ const bundles = [ 'react', 'ReactFlightNativeRelayClientIntegration', 'JSResourceReferenceImpl', + 'ReactNativeInternalFeatureFlags', ], }, @@ -432,7 +434,7 @@ const bundles = [ moduleType: RENDERER, entry: 'react-native-renderer', global: 'ReactNativeRenderer', - externals: ['react-native'], + externals: ['react-native', 'ReactNativeInternalFeatureFlags'], babel: opts => Object.assign({}, opts, { plugins: opts.plugins.concat([ @@ -462,7 +464,7 @@ const bundles = [ moduleType: RENDERER, entry: 'react-native-renderer/fabric', global: 'ReactFabric', - externals: ['react-native'], + externals: ['react-native', 'ReactNativeInternalFeatureFlags'], babel: opts => Object.assign({}, opts, { plugins: opts.plugins.concat([ @@ -499,7 +501,12 @@ const bundles = [ moduleType: RENDERER, entry: 'react-test-renderer', global: 'ReactTestRenderer', - externals: ['react', 'scheduler', 'scheduler/unstable_mock'], + externals: [ + 'react', + 'scheduler', + 'scheduler/unstable_mock', + 'ReactNativeInternalFeatureFlags', + ], babel: opts => Object.assign({}, opts, { plugins: opts.plugins.concat([ @@ -692,7 +699,7 @@ const bundles = [ moduleType: ISOMORPHIC, entry: 'scheduler', global: 'Scheduler', - externals: [], + externals: ['ReactNativeInternalFeatureFlags'], }, /******* React Scheduler Mock (experimental) *******/ @@ -710,7 +717,7 @@ const bundles = [ moduleType: ISOMORPHIC, entry: 'scheduler/unstable_mock', global: 'SchedulerMock', - externals: [], + externals: ['ReactNativeInternalFeatureFlags'], }, /******* React Scheduler Post Task (experimental) *******/ diff --git a/scripts/rollup/modules.js b/scripts/rollup/modules.js index b56f4231e2ef0..2461e28850cc0 100644 --- a/scripts/rollup/modules.js +++ b/scripts/rollup/modules.js @@ -21,6 +21,7 @@ const importSideEffects = Object.freeze({ 'react-fetch/node': HAS_NO_SIDE_EFFECTS_ON_IMPORT, 'react-dom': HAS_NO_SIDE_EFFECTS_ON_IMPORT, url: HAS_NO_SIDE_EFFECTS_ON_IMPORT, + ReactNativeInternalFeatureFlags: HAS_NO_SIDE_EFFECTS_ON_IMPORT, }); // Bundles exporting globals that other modules rely on. @@ -31,6 +32,7 @@ const knownGlobals = Object.freeze({ 'react-interactions/events/tap': 'ReactEventsTap', scheduler: 'Scheduler', 'scheduler/unstable_mock': 'SchedulerMock', + ReactNativeInternalFeatureFlags: 'ReactNativeInternalFeatureFlags', }); // Given ['react'] in bundle externals, returns { 'react': 'React' }.