Move feature flag definitions to JS file instead of JSON (#42815)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42815

Feature flags were originally defined in a JSON file for easier interoperability but we're only using the definitions in JS anyway, so having the definitions in a JS file is more flexible (e.g.: adding comments).

Changelog: [internal]

Reviewed By: huntie

Differential Revision: D53351483

fbshipit-source-id: 23fe0a3898b4facf2f2cf9645f78c45d78937f31
This commit is contained in:
Rubén Norte
2024-02-05 11:02:48 -08:00
committed by Facebook GitHub Bot
parent dbbec3452f
commit 5030f4e015
25 changed files with 173 additions and 142 deletions
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<f4268973a38ba972e68474cc31bab5a7>>
* @generated SignedSource<<f5d5bb65068bb515d33da8bff665dfd2>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<5b653e8a53f557ffc0f46b3e81e99bed>>
* @generated SignedSource<<d4ece56f9329579346fbfe08f7681632>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<47be3dbe5558f720a6c61742f2c63bf8>>
* @generated SignedSource<<41a2646126f7f448be8c8397b1698a4a>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<70c19d5bb1e0c09f52b89b4bb3645b9d>>
* @generated SignedSource<<fc15c71267f1bf2f65c4f3877599c4c7>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<7ba0cb94c10989838250252fa06768a0>>
* @generated SignedSource<<77fc4d6577fc0e2e9a0500cc762bba77>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b0f60718eedab65390ebfb7864a10a27>>
* @generated SignedSource<<49a63388fa661d81b9cec735ac705bd0>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<dab6daf99192f983b7c8ad7633b43a33>>
* @generated SignedSource<<e570b62b4a208b2526169361c3a6be6a>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c2a4da926b870497f76c03c8f97199e2>>
* @generated SignedSource<<356873b4021fcfe9a2afa79417813975>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<feb0342515d10b3519675cd91efa65dc>>
* @generated SignedSource<<40972962362d704915fe7c851ef6a545>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<879b0c096c4a2e9692a5e133bdfd8809>>
* @generated SignedSource<<f8b92fe90e60292ea2f88a4659e3fd50>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<6ccf42209dea35cd5c6ac9eb882c2ef7>>
* @generated SignedSource<<c43f5dfe4a0e12da0595071319c91e63>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<252f46e2c95e08d1180f656c870087b7>>
* @generated SignedSource<<c0d0f4bb2eb2dbf385d56f58444fb16a>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<ef51a5a7152e6f4fe0556b17aec2c0c2>>
* @generated SignedSource<<0f2ef778c97b1928fde0245008015227>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b61bc487a077e9e1dc6ab2b176fd72cb>>
* @generated SignedSource<<4de1ed8503548f440c1a0e4f903c80c7>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b39abca7a1fcce7ae124565cfc619d04>>
* @generated SignedSource<<f97b884f948b3ebf00df11b30cfe3ea4>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<72abac7cc75e65bf1ded596033637050>>
* @generated SignedSource<<f2bbc5a034e11e11190da7f5ea289b7c>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<64ea070fb82bd703eb617dcf64c6a7d1>>
* @generated SignedSource<<19dba0cacd4599408a2adeeeb1dce6f2>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,14 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<994628655312f57c8ab774e9f119eb18>>
* @generated SignedSource<<4ce1b29660d13ea8dfe09777d9907f3f>>
*/
/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -11,39 +11,25 @@ everywhere.
## Definition
The source of truth for the definition of the flags is the file `ReactNativeFeatureFlags.json`
in this directory. That JSON file should have the following structure:
The source of truth for the definition of the flags is the file
`ReactNativeFeatureFlags.config.js` in this directory.
```flow
type Config = {
common: FeatureFlagsList,
jsOnly: FeatureFlagsList,
};
type FeatureFlagsList = {
[flagName: string]: {
description: string,
defaultValue: boolean | number | string,
},
};
```
Example:
```json
{
"common": {
"enableMicrotasks": {
"description": "Enable the use of microtasks in the JS runtime.",
"defaultValue": false
Example contents:
```javascript
module.exports = {
common: {
enableMicrotasks: {
description: 'Enable the use of microtasks in the JS runtime.',
defaultValue: false
}
},
"jsOnly": {
"enableAccessToHostTreeInFabric": {
"description": "Enables access to the host tree in Fabric using DOM-compatible APIs.",
"defaultValue": false
jsOnly: {
enableAccessToHostTreeInFabric: {
description: 'Enables access to the host tree in Fabric using DOM-compatible APIs.',
defaultValue: false
}
}
}
};
```
After any changes to this definitions, the code that provides access to them
@@ -52,6 +38,16 @@ repository.
## Access
You can access the common feature flags from anywhere in your application using
the `ReactNativeFeatureFlags` interface (available in C++/Objective-C++,
Kotlin/Java and JavaScript). JS-only feature flags can only be accessed from
JavaScript.
**Accessing feature flags should be considered fast for all use cases**.
Feature flags are cached at every layer, which prevents having to go through JNI
when accessing the values from Kotlin and through JSI when accessing the values
from JavaScript.
### C++ / Objective-C
```c++
@@ -90,6 +86,15 @@ if (ReactNativeFeatureFlags.enableAccessToHostTreeInFabric()) {
## Customization
Feature flags provide the default values defined in the configuration unless
overrides are applied at the application level. Overrides for common feature
flags can only be defined in native, while overrides for JS-ony flags can only
be defined in JavaScript.
Overrides must be applied before any of the available feature flags has been
accessed. This prevents having inconsistent behavior during the lifecycle of the
application.
### C++/Objective-C
```c++
@@ -0,0 +1,97 @@
/**
* Copyright (c) Meta Platforms, Inc. and 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
* @format
*/
import type {FeatureFlagDefinitions} from './types';
const definitions: FeatureFlagDefinitions = {
common: {
// This is only used in unit tests for the feature flags system.
commonTestFlag: {
description: 'Common flag for testing. Do NOT modify.',
defaultValue: false,
},
useModernRuntimeScheduler: {
description:
'When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.',
defaultValue: false,
},
enableMicrotasks: {
description:
'Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).',
defaultValue: false,
},
batchRenderingUpdatesInEventLoop: {
description:
'When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.',
defaultValue: false,
},
enableSpannableBuildingUnification: {
description:
'Uses new, deduplicated logic for constructing Android Spannables from text fragments',
defaultValue: false,
},
enableCustomDrawOrderFabric: {
description:
'When enabled, Fabric will use customDrawOrder in ReactViewGroup (similar to old architecture).',
defaultValue: false,
},
enableFixForClippedSubviewsCrash: {
description:
'Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix',
defaultValue: false,
},
},
jsOnly: {
// This is only used in unit tests for the feature flags system.
jsOnlyTestFlag: {
description: 'JS-only flag for testing. Do NOT modify.',
defaultValue: false,
},
isLayoutAnimationEnabled: {
description:
'Function used to enable / disabled Layout Animations in React Native.',
defaultValue: true,
},
animatedShouldDebounceQueueFlush: {
description:
'Enables an experimental flush-queue debouncing in Animated.js.',
defaultValue: false,
},
animatedShouldUseSingleOp: {
description:
'Enables an experimental mega-operation for Animated.js that replaces many calls to native with a single call into native, to reduce JSI/JNI traffic.',
defaultValue: false,
},
enableAccessToHostTreeInFabric: {
description:
'Enables access to the host tree in Fabric using DOM-compatible APIs.',
defaultValue: false,
},
shouldUseAnimatedObjectForTransform: {
description:
'Enables use of AnimatedObject for animating transform values.',
defaultValue: false,
},
shouldUseSetNativePropsInFabric: {
description: 'Enables use of setNativeProps in JS driven animations.',
defaultValue: true,
},
shouldUseRemoveClippedSubviewsAsDefaultOnIOS: {
description:
'removeClippedSubviews prop will be used as the default in FlatList on iOS to match Android',
defaultValue: false,
},
},
};
export default definitions;
@@ -1,66 +0,0 @@
{
"common": {
"commonTestFlag": {
"description": "Common flag for testing. Do NOT modify.",
"defaultValue": false
},
"useModernRuntimeScheduler": {
"description": "When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.",
"defaultValue": false
},
"enableMicrotasks": {
"description": "Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).",
"defaultValue": false
},
"batchRenderingUpdatesInEventLoop": {
"description": "When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.",
"defaultValue": false
},
"enableSpannableBuildingUnification": {
"description": "Uses new, deduplicated logic for constructing Android Spannables from text fragments",
"defaultValue": false
},
"enableCustomDrawOrderFabric": {
"description": "When enabled, Fabric will use customDrawOrder in ReactViewGroup (similar to old architecture).",
"defaultValue": false
},
"enableFixForClippedSubviewsCrash": {
"description": "Attempt at fixing a crash related to subview clipping on Android. This is a kill switch for the fix",
"defaultValue": false
}
},
"jsOnly": {
"jsOnlyTestFlag": {
"description": "JS-only flag for testing. Do NOT modify.",
"defaultValue": false
},
"isLayoutAnimationEnabled": {
"description": "Function used to enable / disabled Layout Animations in React Native.",
"defaultValue": true
},
"animatedShouldDebounceQueueFlush": {
"description": "Enables an experimental flush-queue debouncing in Animated.js.",
"defaultValue": false
},
"animatedShouldUseSingleOp": {
"description": "Enables an experimental mega-operation for Animated.js that replaces many calls to native with a single call into native, to reduce JSI/JNI traffic.",
"defaultValue": false
},
"enableAccessToHostTreeInFabric": {
"description": "Enables access to the host tree in Fabric using DOM-compatible APIs.",
"defaultValue": false
},
"shouldUseAnimatedObjectForTransform": {
"description": "Enables use of AnimatedObject for animating transform values.",
"defaultValue": false
},
"shouldUseSetNativePropsInFabric": {
"description": "Enables use of setNativeProps in JS driven animations.",
"defaultValue": true
},
"shouldUseRemoveClippedSubviewsAsDefaultOnIOS": {
"description": "removeClippedSubviews prop will be used as the default in FlatList on iOS to match Android",
"defaultValue": false
}
}
}
+2 -7
View File
@@ -9,7 +9,7 @@
*/
import generateFiles from './generateFiles';
import fs from 'fs';
import featureFlagDefinitions from './ReactNativeFeatureFlags.config';
import path from 'path';
const REACT_NATIVE_PACKAGE_ROOT = path.join(__dirname, '..', '..');
@@ -17,12 +17,7 @@ const REACT_NATIVE_PACKAGE_ROOT = path.join(__dirname, '..', '..');
export default function update(verifyUnchanged: boolean): void {
generateFiles(
{
featureFlagDefinitions: JSON.parse(
fs.readFileSync(
path.join(__dirname, 'ReactNativeFeatureFlags.json'),
'utf8',
),
),
featureFlagDefinitions,
jsPath: path.join(
REACT_NATIVE_PACKAGE_ROOT,
'src',
+1 -1
View File
@@ -44,7 +44,7 @@ export const DO_NOT_MODIFY_COMMENT = `/**
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<2ca87dc970592f66d83f4799c4047c9b>>
* @generated SignedSource<<c1164fd870a4f1540d9b8c956af2b678>>
* @flow strict-local
*/
@@ -12,7 +12,7 @@
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b6bac87d45019ecb8a3ca1ff43c2f912>>
* @generated SignedSource<<52b25f675aa8d5ae45941f0ee951358a>>
* @flow strict-local
*/
@@ -12,7 +12,7 @@
* IMPORTANT: Do NOT modify this file directly.
*
* To change the definition of the flags, edit
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json.
* packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js.
*
* To regenerate this code, run the following script from the repo root:
* yarn featureflags-update