From 07da821bfda181a7ee750c12d73d09fbef87d0f3 Mon Sep 17 00:00:00 2001 From: James Ide Date: Mon, 3 Jun 2019 07:58:31 -0700 Subject: [PATCH] [react-native] Rewrite Haste imports in RN shims and add .fb.js extension (#15786) This commit is a follow-up to https://github.com/facebook/react/pull/15604, which explains more of the rationale behind moving React Native to path-based imports and the work needed in the React repository. In that linked PR, the generated renderers were updated but not the shims; this commit updates the shims. The problem is that FB needs a different copy of the built renderers than the OSS versions so we need a way for FB code to import different modules than in OSS. This was previously done with Haste, but with the removal of Haste from RN, we need another mechanism. Talking with cpojer, we are using a `.fb.js` extension that Metro can be configured to prioritize over `.js`. This commit generates FB's renderers with the `.fb.js` extension and OSS renderers with just `.js`. This way, FB can internally configure Metro to use the `.fb.js` implementations and OSS will use the `.js` ones, letting us swap out which implementation gets bundled. Test Plan: Generated the renderers and shims with `yarn build` and then verified that the generated shims don't contain any Haste-style imports. Copied the renderers and shims into RN manually and launched the RNTester app to verify it loads end-to-end. Added `.fb.js` to the extensions in `metro.config.js` and verified that the FB-specific bundles loaded. --- packages/shared/forks/ReactFeatureFlags.native-fb.js | 4 +++- scripts/flow/react-native-host-hooks.js | 5 +++++ scripts/rollup/packaging.js | 10 +++++++--- .../rollup/shims/react-native/NativeMethodsMixin.js | 4 ++-- scripts/rollup/shims/react-native/ReactFabric.js | 8 ++++---- .../ReactFeatureFlags.fb.js} | 0 scripts/rollup/shims/react-native/ReactNative.js | 6 +++--- .../react-native/createReactNativeComponentClass.js | 4 +++- scripts/rollup/validate/index.js | 6 +----- 9 files changed, 28 insertions(+), 19 deletions(-) rename scripts/rollup/shims/{react-native-fb/ReactFeatureFlags.js => react-native/ReactFeatureFlags.fb.js} (100%) diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 8b899da6d6..f84ecd0742 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -13,7 +13,9 @@ import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags'; import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-fb'; // Re-export dynamic flags from the fbsource version. -export const {debugRenderPhaseSideEffects} = require('ReactFeatureFlags'); +export const { + debugRenderPhaseSideEffects, +} = require('../shims/ReactFeatureFlags'); // The rest of the flags are static for better dead code elimination. export const enableUserTimingAPI = __DEV__; diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index 32a357120d..f90d1e4d94 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -157,3 +157,8 @@ declare module 'RTManager' { declare function completeUpdates(): void; } + +// shims/ReactFeatureFlags is generated by the packaging script +declare module '../shims/ReactFeatureFlags' { + declare export var debugRenderPhaseSideEffects: boolean; +} diff --git a/scripts/rollup/packaging.js b/scripts/rollup/packaging.js index d6ca3b937c..f94eaa5fa1 100644 --- a/scripts/rollup/packaging.js +++ b/scripts/rollup/packaging.js @@ -56,7 +56,7 @@ function getBundleOutputPaths(bundleType, filename, packageName) { case RN_OSS_PROFILING: switch (packageName) { case 'react-native-renderer': - return [`build/react-native/oss/${filename}`]; + return [`build/react-native/implementations/${filename}`]; default: throw new Error('Unknown RN package.'); } @@ -65,7 +65,12 @@ function getBundleOutputPaths(bundleType, filename, packageName) { case RN_FB_PROFILING: switch (packageName) { case 'react-native-renderer': - return [`build/react-native/fb/${filename}`]; + return [ + `build/react-native/implementations/${filename.replace( + /\.js$/, + '.fb.js' + )}`, + ]; default: throw new Error('Unknown RN package.'); } @@ -93,7 +98,6 @@ async function copyRNShims() { require.resolve('react-native-renderer/src/ReactNativeTypes.js'), 'build/react-native/shims/ReactNativeTypes.js' ), - asyncCopyTo(`${__dirname}/shims/react-native-fb`, 'build/react-native/fb'), ]); } diff --git a/scripts/rollup/shims/react-native/NativeMethodsMixin.js b/scripts/rollup/shims/react-native/NativeMethodsMixin.js index 857e298107..c50f379fde 100644 --- a/scripts/rollup/shims/react-native/NativeMethodsMixin.js +++ b/scripts/rollup/shims/react-native/NativeMethodsMixin.js @@ -12,9 +12,9 @@ const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, -} = require('ReactNative'); +} = require('./ReactNative'); -import type {NativeMethodsMixinType} from 'ReactNativeTypes'; +import type {NativeMethodsMixinType} from './ReactNativeTypes'; const {NativeMethodsMixin} = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; diff --git a/scripts/rollup/shims/react-native/ReactFabric.js b/scripts/rollup/shims/react-native/ReactFabric.js index 03691e23d1..8f6a708fd2 100644 --- a/scripts/rollup/shims/react-native/ReactFabric.js +++ b/scripts/rollup/shims/react-native/ReactFabric.js @@ -10,17 +10,17 @@ 'use strict'; -const BatchedBridge = require('BatchedBridge'); +import {BatchedBridge} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; // TODO @sema: Adjust types -import type {ReactNativeType} from 'ReactNativeTypes'; +import type {ReactNativeType} from './ReactNativeTypes'; let ReactFabric; if (__DEV__) { - ReactFabric = require('ReactFabric-dev'); + ReactFabric = require('../implementations/ReactFabric-dev'); } else { - ReactFabric = require('ReactFabric-prod'); + ReactFabric = require('../implementations/ReactFabric-prod'); } BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); diff --git a/scripts/rollup/shims/react-native-fb/ReactFeatureFlags.js b/scripts/rollup/shims/react-native/ReactFeatureFlags.fb.js similarity index 100% rename from scripts/rollup/shims/react-native-fb/ReactFeatureFlags.js rename to scripts/rollup/shims/react-native/ReactFeatureFlags.fb.js diff --git a/scripts/rollup/shims/react-native/ReactNative.js b/scripts/rollup/shims/react-native/ReactNative.js index 13a5985f9f..9f471e4107 100644 --- a/scripts/rollup/shims/react-native/ReactNative.js +++ b/scripts/rollup/shims/react-native/ReactNative.js @@ -10,14 +10,14 @@ 'use strict'; -import type {ReactNativeType} from 'ReactNativeTypes'; +import type {ReactNativeType} from './ReactNativeTypes'; let ReactNative; if (__DEV__) { - ReactNative = require('ReactNativeRenderer-dev'); + ReactNative = require('../implementations/ReactNativeRenderer-dev'); } else { - ReactNative = require('ReactNativeRenderer-prod'); + ReactNative = require('../implementations/ReactNativeRenderer-prod'); } module.exports = (ReactNative: ReactNativeType); diff --git a/scripts/rollup/shims/react-native/createReactNativeComponentClass.js b/scripts/rollup/shims/react-native/createReactNativeComponentClass.js index e9f5fc0f97..86a758d918 100644 --- a/scripts/rollup/shims/react-native/createReactNativeComponentClass.js +++ b/scripts/rollup/shims/react-native/createReactNativeComponentClass.js @@ -10,9 +10,11 @@ 'use strict'; +import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; + import type {ViewConfigGetter} from './ReactNativeTypes'; -const {register} = require('ReactNativeViewConfigRegistry'); +const {register} = ReactNativeViewConfigRegistry; /** * Creates a renderable ReactNative host component. diff --git a/scripts/rollup/validate/index.js b/scripts/rollup/validate/index.js index cb4a947626..2e7ce76bc0 100644 --- a/scripts/rollup/validate/index.js +++ b/scripts/rollup/validate/index.js @@ -60,11 +60,7 @@ const bundles = [ }, { format: 'rn', - filePatterns: [ - `./build/react-native/oss/*.js`, - `./build/react-native/fb/ReactFabric-*.js`, - `./build/react-native/fb/ReactNativeRenderer-*.js`, - ], + filePatterns: [`./build/react-native/implementations/*.js`], }, { format: 'umd',