From 705268dcd16779b1f51f234cebaa588d761202ce Mon Sep 17 00:00:00 2001 From: Eugene Choi <4eugenechoi@gmail.com> Date: Thu, 9 Apr 2026 12:14:54 -0400 Subject: [PATCH] Fix require('ReactFeatureFlags') in eslint-plugin-react-hooks www build (#36243) PR #35951 added FB_WWW_DEV builds for eslint-plugin-react-hooks to get www-specific feature flag values. However, the FB_WWW build uses the full ReactFeatureFlags.www.js fork, which contains: const dynamicFeatureFlags = require('ReactFeatureFlags'); This is a www Haste module that only exists in the www runtime. Rollup can't tree-shake CJS require() calls (they're assumed side-effectful), so the bare require('ReactFeatureFlags') survives in the build output even though the eslint plugin only uses the static eprh_* exports. When the built artifact is synced to www at scripts/lint/eslint/rules/eslint-plugin-react-hooks/index.js, Node.js fails with "Cannot find module 'ReactFeatureFlags'" because Haste modules aren't available in the Node.js lint environment. Create a dedicated fork (ReactFeatureFlags.eslint-plugin.www.js) that exports only the static eprh_* flags with www values, without the require('ReactFeatureFlags') dependency. Wire it up in forks.js for the eslint-plugin-react-hooks entry point. Co-authored-by: Eugene Choi --- .../ReactFeatureFlags.eslint-plugin.www.js | 24 +++++++++++++++++++ .../shared/forks/ReactFeatureFlags.www.js | 9 ++++--- scripts/rollup/forks.js | 8 +++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 packages/shared/forks/ReactFeatureFlags.eslint-plugin.www.js diff --git a/packages/shared/forks/ReactFeatureFlags.eslint-plugin.www.js b/packages/shared/forks/ReactFeatureFlags.eslint-plugin.www.js new file mode 100644 index 000000000000..b7df325b06f2 --- /dev/null +++ b/packages/shared/forks/ReactFeatureFlags.eslint-plugin.www.js @@ -0,0 +1,24 @@ +/** + * 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 + */ + +// This fork provides www-specific feature flag values for +// eslint-plugin-react-hooks without pulling in the full +// ReactFeatureFlags.www.js fork. The full fork imports dynamic flags +// via require('ReactFeatureFlags'), which is a www Haste module that +// doesn't exist in Node.js environments where the ESLint plugin runs. +// +// Only eprh_* flags are needed by the ESLint plugin. + +export const eprh_enableUseKeyedStateCompilerLint: boolean = true; +export const eprh_enableVerboseNoSetStateInEffectCompilerLint: boolean = true; +export const eprh_enableExhaustiveEffectDependenciesCompilerLint: + | 'off' + | 'all' + | 'extra-only' + | 'missing-only' = 'extra-only'; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index c38c32a9e865..4b42d7811b87 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -114,13 +114,16 @@ export const enableFragmentRefsInstanceHandles: boolean = true; export const enableOptimisticKey: boolean = false; -export const eprh_enableUseKeyedStateCompilerLint: boolean = true; -export const eprh_enableVerboseNoSetStateInEffectCompilerLint: boolean = true; +// These flags are only used by eslint-plugin-react-hooks, which has its own +// fork at ReactFeatureFlags.eslint-plugin.www.js with the www-specific values. +// Edit that file to change the www values for these flags. +export const eprh_enableUseKeyedStateCompilerLint: boolean = false; +export const eprh_enableVerboseNoSetStateInEffectCompilerLint: boolean = false; export const eprh_enableExhaustiveEffectDependenciesCompilerLint: | 'off' | 'all' | 'extra-only' - | 'missing-only' = 'extra-only'; + | 'missing-only' = 'off'; // Flow magic to verify the exports of this file match the original version. ((((null: any): ExportsType): FeatureFlagsType): ExportsType); diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index 33c7c96abbc0..2120b370ad34 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -163,6 +163,14 @@ const forks = Object.freeze({ `Unexpected entry (${entry}) and bundleType (${bundleType})` ); } + case 'eslint-plugin-react-hooks/src/index.ts': + switch (bundleType) { + case FB_WWW_DEV: + case FB_WWW_PROD: + case FB_WWW_PROFILING: + return './packages/shared/forks/ReactFeatureFlags.eslint-plugin.www.js'; + } + return null; case 'react-test-renderer': switch (bundleType) { case RN_FB_DEV: