Sitelet https://github.com/react/react/pull/9626
Skip to content

ReactNative flat renderer bundles - #9626

Merged
bvaughn merged 30 commits into
react:masterfrom
bvaughn:react-native-flat-bundles
May 24, 2017
Merged

bvaughn merged 30 commits into
react:masterfrom
bvaughn:react-native-flat-bundles

Conversation

@bvaughn

@bvaughn bvaughn commented May 8, 2017 •

Copy link
Copy Markdown
Contributor

Introduces ReactNative flat renderer bundles.

There's more that could be done to improve consistency and sharing between the www and fbsource sync scripts. Given the size and duration of this PR I'd prefer to defer that work to a follow-up issue, #9763.

Building and syncing ReactNative flat renderer

This PR introduces an optional flag to the Rollup build scripts that enables syncing the built ReactNative renderer (and its Flow types and shims) to fbsource.

# Build ReactNative flat bundles
yarn build -- --type=RN

# Build bundles and sync (to default location)
yarn build -- --type=RN --sync-fbsource

# Build bundles and sync (to custom location)
yarn build -- --type=RN --sync-fbsource=/path/to/fbsource/

Changes

Rollup changes

  • Updated the Rollup build script to strip Haste @providesModule headers for RN_* builds.
  • Updated Rollup build script to add @noflow header to flat bundle to tell Flow not to try to infer types. (We'll have to use explicit types instead.) This is necessary to avoid causing huge memory and CPU uses in Flow.
  • Added a new REACT_NATIVE_USE_FIBER env variable to prevent a mismatch of stack+fiber components at runtime.
    • ReactNativeFeatureFlags uses this env variable to enable tests to cover both versions.
    • The Rollup build script uses this variable as well to support proper bundles.
  • Packaging script copies PooledClass to fbsource rather than including it in the RN renderer bundle based on PR feedback.
  • Packaging script copies ReactTypes and ReactNativeTypes files as well to avoid Flow inferring the types (which is super slow / impossible).
  • New sync-fbsource flag added to enable copying the built RN bundle (and shims) to fbsource (cc @trueadm).

Flat renderer bundle

  • Added __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED object to ReactNative for objects required by fbsource.
  • Added shims for modules directly required in fbsource that read from the new secret property.
  • Re-organized code to avoid circular dependencies that would break Rollup:
    • Move NativeRenderer (the thing returned from ReactFiberReconciler) out of ReactNativeFiber and into its own package, ReactNativeFiberRenderer. (This way the fiber version of findNodeHandle can access NativeRenderer.findHostInstance without having to require all of ReactNativeFiber.)
    • Fork findNodeHandle internally (based on feature flag) rather than relying on injecting. (This is only temporary, until stack has been deprecated.) This will ease the requirement that ReactNative be loaded before findNodeHandle can be guaranteed to be functional.
    • takeSnapshot uses new forked findNodeHandler wrappers (rather than ReactNative.findNodeHandle) and avoids requiring ReactNative directly.
  • Collocated externally exposed ReactTypes and ReactNativeTypes into single files to be synced to fbsource automatically since types can no longer be inferred. (This mostly involved moving a few types around and changing their imports.) These types are used internally as well to ensure they stay in sync with the implementations.

Miscellaneous

  • Addressed a TODO in NativeMethodsMixin and ReactNativeFiberHostComponent to correctly share the same underlying Flow type between them.

Brian Vaughn added 12 commits May 5, 2017 10:32
Hopefully this is sufficient to work around Rollup circular dependency problems. (To be seen in subsequent commits...)
This allowed me to remove the ReactNative -> findNodeHandle injections, which should in turn allow me to require a fully-functional findNodeHandle without going through ReactNative. This will hopefully allow ReactNativeBaseomponent to avoid a circular dependency.
…ndle

Instead it uses the new, renderer-specific wrappers (eg findNodeHandleFiberWrapper and findNodeHandleStackWrapper) to ensure the returned value is numeric (or null). This avoids a circular dependency that would trip up Rollup.
…r than ReactNative

This works around a potential circular dependency that would break the Rollup build
@gaearon

gaearon commented May 9, 2017 •

Copy link
Copy Markdown
Contributor

Updated the Rollup builds script to strip Haste @providesModule headers for RN_* builds. (Should we do this for FB_* builds as well?)

Can we just remove them from source? RN was the last thing relying on them.

Comment thread scripts/rollup/build.js Outdated
// needs to happen after strip env
commonjs(getCommonJsConfig(bundleType)),
uglify(
uglifyConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it time to switch to named arguments here?

* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactErrorUtils
* @providesModule SyntheticEvent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to expose SyntheticEvent?

NativeMethodsMixin: require('NativeMethodsMixin'),

// Used by react-native-github/Libraries/ components
PooledClass: require('PooledClass'), // Components/Touchable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we copy and paste PooledClass into RN repo? It is relatively small and completely isolated.
I'd like to avoid treating it as part of React's contract, and be able to safely change or remove it.

ReactGlobalSharedState: require('ReactGlobalSharedState'), // Systrace
ReactNativeComponentTree: require('ReactNativeComponentTree'), // InspectorUtils, ScrollResponder
ReactNativePropRegistry: require('ReactNativePropRegistry'), // flattenStyle, Stylesheet
ReactPerf: require('ReactPerf'), // ReactPerfStallHandler, RCTRenderingPerf

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we put ReactPerf and ReactDebugTool imports under __DEV__?
I think they are currently only imported from DEV-only modules in RN.

ReactGlobalSharedState: require('ReactGlobalSharedState'), // Systrace
ReactNativeComponentTree: require('ReactNativeComponentTree'), // InspectorUtils, ScrollResponder
ReactNativePropRegistry: require('ReactNativePropRegistry'), // flattenStyle, Stylesheet
ReactPerf: require('ReactPerf'), // ReactPerfStallHandler, RCTRenderingPerf

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question about DEV here.


__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
// Used for Flow types
SyntheticEvent: require('SyntheticEvent'),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is wrong. You don't need to expose SyntheticEvent for Flow types. SyntheticEvent is a global in Flow (yes, Flow can be weird).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, this is on the Quip doc checklist. Initially I saw SE was being required a dozen or so places internally but then realized it was a built-in type and just haven't ticked off that item yet. Thanks for pointing it out though! 😁

@bvaughn

bvaughn commented May 9, 2017

Copy link
Copy Markdown
Contributor Author

Updated the Rollup builds script to strip Haste @providesModule headers for RN_* builds. (Should we do this for FB_* builds as well?)

Can we just remove them from source? RN was the last thing relying on them.

No. Our Jest tests rely on them.

@gaearon

gaearon commented May 9, 2017

Copy link
Copy Markdown
Contributor

Oh. I wonder if there's any way to tell Jest to just use filenames? I thought that was the plan for www—curious if Jest already supports it via some obscure switch.

@bvaughn

bvaughn commented May 9, 2017

Copy link
Copy Markdown
Contributor Author

Maybe. Would be nice. Could always do in a follow-up :D

@gaearon

gaearon commented May 9, 2017

Copy link
Copy Markdown
Contributor

Sounds good. 😄

Brian Vaughn added 3 commits May 10, 2017 11:10
This shouldn't have been declared as an external. This was causing it to be inserted as a side-effects require before RN was exported, causing a circular dep that broke the bundle.
Comment thread scripts/rollup/build.js Outdated

function setUseFiberEnvVariable(useFiber) {
return {
'process.env.ROLLUP_USE_FIBER': useFiber,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have two versions of FeatureFlags, one with Fiber enabled and other with it disabled? And use aliasing to feed it either one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't that leave the same problems I was trying to solve by injecting it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't understand. They would still be specified at the build time, just without a need to look at process.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Maybe I misunderstood what you were suggesting them (and I actually don't know after all). Could you give a more concrete example?

This is kind of a hacky solution, but it is temporary. It works around the fact that ReactNativeFeatureFlag values need to be set at build time in order to avoid a mismatch between runtime flag values. DOM avoids the need to do this by using injection but Native is not able to use this same approach due to circular dependency issues.
@bvaughn
bvaughn force-pushed the react-native-flat-bundles branch from a12dfc8 to e97da7f Compare May 11, 2017 17:09
@bvaughn
bvaughn force-pushed the react-native-flat-bundles branch from affc0bc to b158443 Compare May 12, 2017 21:29
…and PooledClass from SECRET exports. Converted Rollup helper function to use named params.
@bvaughn
bvaughn force-pushed the react-native-flat-bundles branch from b158443 to 0553103 Compare May 12, 2017 21:40
@bvaughn
bvaughn force-pushed the react-native-flat-bundles branch from dfc4688 to 9f59c4c Compare May 23, 2017 16:04
Brian Vaughn added 3 commits May 23, 2017 22:25
…roblems

When Flow tries to infer such a large file, it consumes massive amounts of CPU/RAM and can often lead to programs crashing. It is better for such large files to use .flow.js types instead.
@bvaughn
bvaughn force-pushed the react-native-flat-bundles branch from 535c543 to fe00c57 Compare May 24, 2017 10:20
@bvaughn
bvaughn requested review from acdlite, gaearon and trueadm May 24, 2017 11:45
@bvaughn

bvaughn commented May 24, 2017

Copy link
Copy Markdown
Contributor Author

Let's go over this PR? 😁

@bvaughn bvaughn changed the title React native flat bundles [WIP] React native flat bundles May 24, 2017
@bvaughn bvaughn changed the title React native flat bundles ReactNative flat renderer bundles May 24, 2017

@trueadm trueadm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bvaughn
bvaughn merged commit c22b94f into react:master May 24, 2017
@bvaughn
bvaughn deleted the react-native-flat-bundles branch May 24, 2017 16:06
@bvaughn

bvaughn commented May 24, 2017

Copy link
Copy Markdown
Contributor Author

Thanks for the review @trueadm !

mrizwanashiq pushed a commit to mrizwanashiq/react that referenced this pull request Jun 25, 2026
* Split ReactNativeFiber into separate ReactNativeFiberRenderer module
Hopefully this is sufficient to work around Rollup circular dependency problems. (To be seen in subsequent commits...)

* Split findNodeHandle into findNodeHandleFiber + findNodeHandleStack
This allowed me to remove the ReactNative -> findNodeHandle injections, which should in turn allow me to require a fully-functional findNodeHandle without going through ReactNative. This will hopefully allow ReactNativeBaseomponent to avoid a circular dependency.

* Un-forked findNodeHandle in favor of just inlining the findNode function impl

* takeSnapshot no longer requires/depends-on ReactNative for findNodeHandle
Instead it uses the new, renderer-specific wrappers (eg findNodeHandleFiberWrapper and findNodeHandleStackWrapper) to ensure the returned value is numeric (or null). This avoids a circular dependency that would trip up Rollup.

* NativeMethodsMixin requires findNodeHandler wrapper(s) directly rather than ReactNative
This works around a potential circular dependency that would break the Rollup build

* Add RN_* build targets to hash-finle-name check

* Strip @providesModule annotations from headers for RN_* builds

* Added process.env.REACT_NATIVE_USE_FIBER to ReactNativeFeatureFlags
This is kind of a hacky solution, but it is temporary. It works around the fact that ReactNativeFeatureFlag values need to be set at build time in order to avoid a mismatch between runtime flag values. DOM avoids the need to do this by using injection but Native is not able to use this same approach due to circular dependency issues.

* Moved a couple of SECRET exports to dev-only. Removed SyntheticEvent and PooledClass from SECRET exports. Converted Rollup helper function to use named params.

* Split NativeMethodsMixins interface and object-type

* Add @noflow header to flat-bundle template to avoid triggering Flow problems
When Flow tries to infer such a large file, it consumes massive amounts of CPU/RAM and can often lead to programs crashing. It is better for such large files to use .flow.js types instead.

* NativeMethodsMixin and ReactNativeFiberHostComponent now share the same Flow type

* Collocated (externally exposed) ReactTypes and ReactNativeTypes into single files to be synced to fbsource. ReactNativeFiber and ReactNativeStack use ReactNativeType Flow type

* Build script syncs RN types and PooledClass automatically

* Added optional sync-RN step to Rollup build script

* Added results.json for new RN bundles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants