Skip to content

Commit

Permalink
[react-native] Rewrite Haste imports in RN shims and add .fb.js exten…
Browse files Browse the repository at this point in the history
…sion (facebook#15786)

This commit is a follow-up to facebook#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.
  • Loading branch information
ide authored and cpojer committed Jun 3, 2019
1 parent a383c46 commit 07da821
Show file tree
Hide file tree
Showing 9 changed files with 28 additions and 19 deletions.
4 changes: 3 additions & 1 deletion packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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__;
Expand Down
5 changes: 5 additions & 0 deletions scripts/flow/react-native-host-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
10 changes: 7 additions & 3 deletions scripts/rollup/packaging.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.');
}
Expand All @@ -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.');
}
Expand Down Expand Up @@ -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'),
]);
}

Expand Down
4 changes: 2 additions & 2 deletions scripts/rollup/shims/react-native/NativeMethodsMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
8 changes: 4 additions & 4 deletions scripts/rollup/shims/react-native/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions scripts/rollup/shims/react-native/ReactNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 1 addition & 5 deletions scripts/rollup/validate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit 07da821

Please sign in to comment.