[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.
This commit is contained in:
James Ide
2019-06-03 07:58:31 -07:00
committed by Christoph Nakazawa
parent a383c46788
commit 07da821bfd
9 changed files with 28 additions and 19 deletions
@@ -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__;
+5
View File
@@ -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;
}
+7 -3
View File
@@ -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'),
]);
}
+2 -2
View File
@@ -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;
+4 -4
View File
@@ -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);
+3 -3
View File
@@ -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);
@@ -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.
+1 -5
View File
@@ -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',