Skip to content

Commit

Permalink
Import dynamic RN flags from external module
Browse files Browse the repository at this point in the history
Internal feature flags that we wish to control with a GK can now be
imported from an external module, which I've called
"ReactNativeInternalFeatureFlags".

We'll need to add this module to the downstream repo.

We can't yet use this in our tests, because we don't have a test
configuration that runs against the React Native feature flags fork. We
should set up that up the same way we did for www.
  • Loading branch information
acdlite committed Aug 4, 2021
1 parent 2fb2dbb commit 1137854
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 10 deletions.
29 changes: 29 additions & 0 deletions packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js
Original file line number Diff line number Diff line change
@@ -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<ExportsType, DynamicFlagsType>);
10 changes: 8 additions & 2 deletions packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions scripts/flow/config/flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions scripts/flow/xplat.js
Original file line number Diff line number Diff line change
@@ -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;
}
23 changes: 15 additions & 8 deletions scripts/rollup/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const bundles = [
moduleType: ISOMORPHIC,
entry: 'react',
global: 'React',
externals: [],
externals: ['ReactNativeInternalFeatureFlags'],
},

/******* Isomorphic Shared Subset *******/
Expand All @@ -105,7 +105,7 @@ const bundles = [
moduleType: ISOMORPHIC,
entry: 'react/jsx-runtime',
global: 'JSXRuntime',
externals: ['react'],
externals: ['react', 'ReactNativeInternalFeatureFlags'],
},

/******* React JSX DEV Runtime *******/
Expand All @@ -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) *******/
Expand Down Expand Up @@ -372,6 +372,7 @@ const bundles = [
'react',
'ReactFlightNativeRelayServerIntegration',
'JSResourceReferenceImpl',
'ReactNativeInternalFeatureFlags',
],
},

Expand All @@ -385,6 +386,7 @@ const bundles = [
'react',
'ReactFlightNativeRelayClientIntegration',
'JSResourceReferenceImpl',
'ReactNativeInternalFeatureFlags',
],
},

Expand Down Expand Up @@ -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([
Expand Down Expand Up @@ -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([
Expand Down Expand Up @@ -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([
Expand Down Expand Up @@ -692,7 +699,7 @@ const bundles = [
moduleType: ISOMORPHIC,
entry: 'scheduler',
global: 'Scheduler',
externals: [],
externals: ['ReactNativeInternalFeatureFlags'],
},

/******* React Scheduler Mock (experimental) *******/
Expand All @@ -710,7 +717,7 @@ const bundles = [
moduleType: ISOMORPHIC,
entry: 'scheduler/unstable_mock',
global: 'SchedulerMock',
externals: [],
externals: ['ReactNativeInternalFeatureFlags'],
},

/******* React Scheduler Post Task (experimental) *******/
Expand Down
2 changes: 2 additions & 0 deletions scripts/rollup/modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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' }.
Expand Down

0 comments on commit 1137854

Please sign in to comment.