@samitouri / QOS-React / commits / 1c5a639c37

Require the isomorphic React instead of internals from renderers (#7473)

This is needed for flat builds. It also lets us get rid of a bunch of special cases in the build scripts. It also allow us to just copy the source files into React Native instead of having to build first to resolve the special cases.

Sebastian Markbåge committed Aug 11, 2016 at 18:56 UTC 1c5a639c37039a9c60752980dfee168129b76b32
23 files changed +79 -89
flow/react-native-host-hooks.js
+3 -1
@@ -40,4 +40,6 @@ declare module 'UIManager' {
40 declare function setChildren() : void;
41 declare function updateView() : void;
42 }
43 -declare module 'View' { }
43 +declare module 'View' {
44 + declare var exports : typeof ReactComponent;
45 +}
grunt/config/browserify.js
+1 -6
@@ -19,13 +19,8 @@ var SECRET_INTERNALS_NAME = 'React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_
19 var shimSharedModulesFiles = {
20 './ReactCurrentOwner': SECRET_INTERNALS_NAME + '.ReactCurrentOwner',
21 './ReactComponentTreeHook': SECRET_INTERNALS_NAME + '.ReactComponentTreeHook',
22 - // The methods we used here are exposed on the main React export.
23 - // TODO: Change all renderer code to require the isomorphic React directly
24 - // instead of these internals.
22 + // Use the global, anywhere we require React
23 './React': 'React',
26 - './ReactElement': 'React',
27 - './ReactPropTypes': 'React.PropTypes',
28 - './ReactChildren': 'React.Children',
24 };
25
26 // We can access these as absolute or relative. We need to shim both.
gulpfile.js
+2 -11
@@ -111,20 +111,11 @@ var moduleMapReact = Object.assign(
111 );
112
113 var rendererSharedState = {
114 + // Alias
115 + React: 'react/lib/React',
116 // Shared state
117 ReactCurrentOwner: 'react/lib/ReactCurrentOwner',
118 ReactComponentTreeHook: 'react/lib/ReactComponentTreeHook',
117 -
118 - // TODO: Move to shared since these are actually shared and can be copied.
119 - ReactPropTypeLocations: 'react/lib/ReactPropTypeLocations',
120 - ReactPropTypesSecret: 'react/lib/ReactPropTypesSecret',
121 - checkReactTypeSpec: 'react/lib/checkReactTypeSpec',
122 -
123 - // TODO: Update the source to just use the React module.
124 - React: 'react/lib/React',
125 - ReactElement: 'react/lib/ReactElement',
126 - ReactPropTypes: 'react/lib/ReactPropTypes',
127 - ReactChildren: 'react/lib/ReactChildren',
119 };
120
121 var moduleMapReactDOM = Object.assign(
src/isomorphic/classic/element/ReactElement.js
+1 -7
@@ -17,11 +17,7 @@ var warning = require('warning');
17 var canDefineProperty = require('canDefineProperty');
18 var hasOwnProperty = Object.prototype.hasOwnProperty;
19
20 -// The Symbol used to tag the ReactElement type. If there is no native Symbol
21 -// nor polyfill, then a plain number is used for performance.
22 -var REACT_ELEMENT_TYPE =
23 - (typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
24 - 0xeac7;
20 +var REACT_ELEMENT_TYPE = require('ReactElementSymbol');
21
22 var RESERVED_PROPS = {
23 key: true,
@@ -406,6 +402,4 @@ ReactElement.isValidElement = function(object) {
402 );
403 };
404
409 -ReactElement.REACT_ELEMENT_TYPE = REACT_ELEMENT_TYPE;
410 -
405 module.exports = ReactElement;
src/renderers/dom/client/ReactMount.js
+3 -3
@@ -13,12 +13,12 @@
13
14 var DOMLazyTree = require('DOMLazyTree');
15 var DOMProperty = require('DOMProperty');
16 +var React = require('React');
17 var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
18 var ReactCurrentOwner = require('ReactCurrentOwner');
19 var ReactDOMComponentTree = require('ReactDOMComponentTree');
20 var ReactDOMContainerInfo = require('ReactDOMContainerInfo');
21 var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
21 -var ReactElement = require('ReactElement');
22 var ReactFeatureFlags = require('ReactFeatureFlags');
23 var ReactInstanceMap = require('ReactInstanceMap');
24 var ReactInstrumentation = require('ReactInstrumentation');
@@ -388,7 +388,7 @@ var ReactMount = {
388 _renderSubtreeIntoContainer: function(parentComponent, nextElement, container, callback) {
389 ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render');
390 invariant(
391 - ReactElement.isValidElement(nextElement),
391 + React.isValidElement(nextElement),
392 'ReactDOM.render(): Invalid component element.%s',
393 (
394 typeof nextElement === 'string' ?
@@ -415,7 +415,7 @@ var ReactMount = {
415 'for your app.'
416 );
417
418 - var nextWrappedElement = ReactElement.createElement(
418 + var nextWrappedElement = React.createElement(
419 TopLevelWrapper,
420 { child: nextElement }
421 );
src/renderers/dom/client/wrappers/LinkedValueUtils.js
+2 -2
@@ -11,7 +11,7 @@
11
12 'use strict';
13
14 -var ReactPropTypes = require('ReactPropTypes');
14 +var React = require('React');
15 var ReactPropTypeLocations = require('ReactPropTypeLocations');
16 var ReactPropTypesSecret = require('ReactPropTypesSecret');
17
@@ -84,7 +84,7 @@ var propTypes = {
84 'set either `onChange` or `readOnly`.'
85 );
86 },
87 - onChange: ReactPropTypes.func,
87 + onChange: React.PropTypes.func,
88 };
89
90 var loggedTypeFailures = {};
src/renderers/dom/client/wrappers/ReactDOMOption.js
+2 -2
@@ -11,7 +11,7 @@
11
12 'use strict';
13
14 -var ReactChildren = require('ReactChildren');
14 +var React = require('React');
15 var ReactDOMComponentTree = require('ReactDOMComponentTree');
16 var ReactDOMSelect = require('ReactDOMSelect');
17
@@ -23,7 +23,7 @@ function flattenChildren(children) {
23
24 // Flatten children and warn if they aren't strings or numbers;
25 // invalid types are ignored.
26 - ReactChildren.forEach(children, function(child) {
26 + React.Children.forEach(children, function(child) {
27 if (child == null) {
28 return;
29 }
src/renderers/dom/server/ReactServerRendering.js
+3 -3
@@ -10,9 +10,9 @@
10 */
11 'use strict';
12
13 +var React = require('React');
14 var ReactDOMContainerInfo = require('ReactDOMContainerInfo');
15 var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
15 -var ReactElement = require('ReactElement');
16 var ReactInstrumentation = require('ReactInstrumentation');
17 var ReactMarkupChecksum = require('ReactMarkupChecksum');
18 var ReactReconciler = require('ReactReconciler');
@@ -80,7 +80,7 @@ function renderToStringImpl(element, makeStaticMarkup) {
80 */
81 function renderToString(element) {
82 invariant(
83 - ReactElement.isValidElement(element),
83 + React.isValidElement(element),
84 'renderToString(): You must pass a valid ReactElement.'
85 );
86 return renderToStringImpl(element, false);
@@ -93,7 +93,7 @@ function renderToString(element) {
93 */
94 function renderToStaticMarkup(element) {
95 invariant(
96 - ReactElement.isValidElement(element),
96 + React.isValidElement(element),
97 'renderToStaticMarkup(): You must pass a valid ReactElement.'
98 );
99 return renderToStringImpl(element, true);
src/renderers/native/ReactNative.js
+1 -2
@@ -16,7 +16,6 @@
16 var ReactNativeComponentTree = require('ReactNativeComponentTree');
17 var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');
18
19 -var ReactElement = require('ReactElement');
19 var ReactNativeMount = require('ReactNativeMount');
20 var ReactUpdates = require('ReactUpdates');
21
@@ -25,7 +24,7 @@ var findNodeHandle = require('findNodeHandle');
24 ReactNativeDefaultInjection.inject();
25
26 var render = function(
28 - element: ReactElement,
27 + element: ReactElement<any>,
28 mountInto: number,
29 callback?: ?(() => void)
30 ): ?ReactComponent<any, any, any> {
src/renderers/native/ReactNativeDefaultInjection.js
+2 -2
@@ -22,9 +22,9 @@ require('InitializeJavaScriptAppEngine');
22 var EventPluginHub = require('EventPluginHub');
23 var EventPluginUtils = require('EventPluginUtils');
24 var RCTEventEmitter = require('RCTEventEmitter');
25 +var React = require('React');
26 var ReactComponentEnvironment = require('ReactComponentEnvironment');
27 var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
27 -var ReactElement = require('ReactElement');
28 var ReactEmptyComponent = require('ReactEmptyComponent');
29 var ReactNativeBridgeEventPlugin = require('ReactNativeBridgeEventPlugin');
30 var ReactHostComponent = require('ReactHostComponent');
@@ -83,7 +83,7 @@ function inject() {
83 // Can't import View at the top because it depends on React to make its composite
84 var View = require('View');
85 return new ReactSimpleEmptyComponent(
86 - ReactElement.createElement(View, {
86 + React.createElement(View, {
87 collapsable: true,
88 style: { position: 'absolute' },
89 }),
src/renderers/native/ReactNativeMount.js
+7 -12
@@ -11,7 +11,7 @@
11 */
12 'use strict';
13
14 -var ReactElement = require('ReactElement');
14 +var React = require('React');
15 var ReactInstrumentation = require('ReactInstrumentation');
16 var ReactNativeContainerInfo = require('ReactNativeContainerInfo');
17 var ReactNativeTagHandles = require('ReactNativeTagHandles');
@@ -35,9 +35,9 @@ if (__DEV__) {
35 TopLevelWrapper.displayName = 'TopLevelWrapper';
36 }
37 TopLevelWrapper.prototype.render = function() {
38 - // this.props is actually a ReactElement
39 - return this.props;
38 + return this.props.child;
39 };
40 +TopLevelWrapper.isReactTopLevelWrapper = true;
41
42 /**
43 * Mounts this component and inserts it into the DOM.
@@ -99,25 +99,20 @@ var ReactNativeMount = {
99 * @param {containerTag} containerView Handle to native view tag
100 */
101 renderComponent: function(
102 - nextElement: ReactElement,
102 + nextElement: ReactElement<*>,
103 containerTag: number,
104 callback?: ?(() => void)
105 ): ?ReactComponent<any, any, any> {
106 - var nextWrappedElement = new ReactElement(
106 + var nextWrappedElement = React.createElement(
107 TopLevelWrapper,
108 - null,
109 - null,
110 - null,
111 - null,
112 - null,
113 - nextElement
108 + { child: nextElement }
109 );
110
111 var topRootNodeID = containerTag;
112 var prevComponent = ReactNativeMount._instancesByContainerID[topRootNodeID];
113 if (prevComponent) {
114 var prevWrappedElement = prevComponent._currentElement;
120 - var prevElement = prevWrappedElement.props;
115 + var prevElement = prevWrappedElement.props.child;
116 if (shouldUpdateReactComponent(prevElement, nextElement)) {
117 ReactUpdateQueue.enqueueElementInternal(prevComponent, nextWrappedElement, emptyObject);
118 if (callback) {
src/renderers/shared/fiber/ReactChildFiber.js
+1 -3
@@ -18,9 +18,7 @@ import type { PriorityLevel } from 'ReactPriorityLevel';
18
19 import type { ReactNodeList } from 'ReactTypes';
20
21 -var {
22 - REACT_ELEMENT_TYPE,
23 -} = require('ReactElement');
21 +var REACT_ELEMENT_TYPE = require('ReactElementSymbol');
22 var {
23 REACT_COROUTINE_TYPE,
24 REACT_YIELD_TYPE,
src/renderers/shared/fiber/ReactFiber.js
+2 -3
@@ -26,8 +26,6 @@ var {
26 YieldComponent,
27 } = ReactTypeOfWork;
28
29 -var ReactElement = require('ReactElement');
30 -
29 var {
30 NoWork,
31 } = require('ReactPriorityLevel');
@@ -201,7 +199,8 @@ exports.createHostContainerFiber = function() {
199 return fiber;
200 };
201
204 -exports.createFiberFromElement = function(element : ReactElement, priorityLevel : PriorityLevel) {
202 +exports.createFiberFromElement = function(element : ReactElement<*>, priorityLevel : PriorityLevel) {
203 +// $FlowFixMe: ReactElement.key is currently defined as ?string but should be defined as null | string in Flow.
204 const fiber = createFiberFromElementType(element.type, element.key);
205 fiber.pendingProps = element.props;
206 fiber.pendingWorkPriority = priorityLevel;
src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
+4 -4
@@ -11,9 +11,9 @@
11
12 'use strict';
13
14 +var React = require('React');
15 var ReactComponentEnvironment = require('ReactComponentEnvironment');
16 var ReactCurrentOwner = require('ReactCurrentOwner');
16 -var ReactElement = require('ReactElement');
17 var ReactErrorUtils = require('ReactErrorUtils');
18 var ReactInstanceMap = require('ReactInstanceMap');
19 var ReactInstrumentation = require('ReactInstrumentation');
@@ -49,7 +49,7 @@ StatelessComponent.prototype.render = function() {
49 function warnIfInvalidElement(Component, element) {
50 if (__DEV__) {
51 warning(
52 - element === null || element === false || ReactElement.isValidElement(element),
52 + element === null || element === false || React.isValidElement(element),
53 '%s(...): A valid React element (or null) must be returned. You may have ' +
54 'returned undefined, an array or some other invalid object.',
55 Component.displayName || Component.name || 'Component'
@@ -229,7 +229,7 @@ var ReactCompositeComponentMixin = {
229 invariant(
230 inst === null ||
231 inst === false ||
232 - ReactElement.isValidElement(inst),
232 + React.isValidElement(inst),
233 '%s(...): A valid React element (or null) must be returned. You may have ' +
234 'returned undefined, an array or some other invalid object.',
235 Component.displayName || Component.name || 'Component'
@@ -1145,7 +1145,7 @@ var ReactCompositeComponentMixin = {
1145 invariant(
1146 // TODO: An `isValidNode` function would probably be more appropriate
1147 renderedComponent === null || renderedComponent === false ||
1148 - ReactElement.isValidElement(renderedComponent),
1148 + React.isValidElement(renderedComponent),
1149 '%s.render(): A valid React element (or null) must be returned. You may have ' +
1150 'returned undefined, an array or some other invalid object.',
1151 this.getName() || 'ReactCompositeComponent'
src/renderers/shared/stack/reconciler/ReactNodeTypes.js
+2 -2
@@ -14,7 +14,7 @@
14
15 type ReactNodeType = 0 | 1 | 2;
16
17 -var ReactElement = require('ReactElement');
17 +var React = require('React');
18
19 var invariant = require('invariant');
20
@@ -26,7 +26,7 @@ var ReactNodeTypes = {
26 getType: function(node: ReactElement<any>): ReactNodeType {
27 if (node === null || node === false) {
28 return ReactNodeTypes.EMPTY;
29 - } else if (ReactElement.isValidElement(node)) {
29 + } else if (React.isValidElement(node)) {
30 if (typeof node.type === 'function') {
31 return ReactNodeTypes.COMPOSITE;
32 } else {
src/renderers/testing/ReactTestMount.js
+7 -17
@@ -11,7 +11,7 @@
11 */
12 'use strict';
13
14 -var ReactElement = require('ReactElement');
14 +var React = require('React');
15 var ReactReconciler = require('ReactReconciler');
16 var ReactUpdates = require('ReactUpdates');
17
@@ -31,9 +31,9 @@ if (__DEV__) {
31 TopLevelWrapper.displayName = 'TopLevelWrapper';
32 }
33 TopLevelWrapper.prototype.render = function() {
34 - // this.props is actually a ReactElement
35 - return this.props;
34 + return this.props.child;
35 };
36 +TopLevelWrapper.isReactTopLevelWrapper = true;
37
38 /**
39 * Mounts this component and inserts it into the DOM.
@@ -88,14 +88,9 @@ ReactTestInstance.prototype.update = function(nextElement) {
88 this._component,
89 "ReactTestRenderer: .update() can't be called after unmount."
90 );
91 - var nextWrappedElement = new ReactElement(
91 + var nextWrappedElement = React.createElement(
92 TopLevelWrapper,
93 - null,
94 - null,
95 - null,
96 - null,
97 - null,
98 - nextElement
93 + { child: nextElement }
94 );
95 var component = this._component;
96 ReactUpdates.batchedUpdates(function() {
@@ -139,14 +134,9 @@ var ReactTestMount = {
134 render: function(
135 nextElement: ReactElement
136 ): ?ReactElement<any, any, any> {
142 - var nextWrappedElement = new ReactElement(
137 + var nextWrappedElement = React.createElement(
138 TopLevelWrapper,
144 - null,
145 - null,
146 - null,
147 - null,
148 - null,
149 - nextElement
139 + { child: nextElement }
140 );
141
142 var instance = instantiateReactComponent(nextWrappedElement, false);
src/shared/types/ReactPropTypeLocationNames.js renamed
src/shared/types/ReactPropTypeLocations.js renamed
src/shared/types/ReactPropTypesSecret.js renamed
src/shared/types/checkReactTypeSpec.js renamed
src/shared/utils/ReactElementSymbol.js new
+20
@@ -0,0 +1,20 @@
1 +/**
2 + * Copyright 2014-present, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @providesModule ReactElementSymbol
10 + */
11 +
12 +'use strict';
13 +
14 +// The Symbol used to tag the ReactElement type. If there is no native Symbol
15 +// nor polyfill, then a plain number is used for performance.
16 +var REACT_ELEMENT_TYPE =
17 + (typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
18 + 0xeac7;
19 +
20 +module.exports = REACT_ELEMENT_TYPE;
src/shared/utils/traverseAllChildren.js
+10 -2
@@ -12,7 +12,7 @@
12 'use strict';
13
14 var ReactCurrentOwner = require('ReactCurrentOwner');
15 -var ReactElement = require('ReactElement');
15 +var REACT_ELEMENT_TYPE = require('ReactElementSymbol');
16
17 var getIteratorFn = require('getIteratorFn');
18 var invariant = require('invariant');
@@ -22,6 +22,12 @@ var warning = require('warning');
22 var SEPARATOR = '.';
23 var SUBSEPARATOR = ':';
24
25 +/**
26 + * This is inlined from ReactElement since this file is shared between
27 + * isomorphic and renderers. We could extract this to a
28 + *
29 + */
30 +
31 /**
32 * TODO: Test that a single child and an array with one item have the same key
33 * pattern.
@@ -71,7 +77,9 @@ function traverseAllChildrenImpl(
77 if (children === null ||
78 type === 'string' ||
79 type === 'number' ||
74 - ReactElement.isValidElement(children)) {
80 + // The following is inlined from ReactElement. This means we can optimize
81 + // some checks. React Fiber also inlines this logic for similar purposes.
82 + (type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE)) {
83 callback(
84 traverseContext,
85 children,
src/test/ReactTestUtils.js
+6 -7
@@ -19,7 +19,6 @@ var React = require('React');
19 var ReactDefaultInjection = require('ReactDefaultInjection');
20 var ReactDOM = require('ReactDOM');
21 var ReactDOMComponentTree = require('ReactDOMComponentTree');
22 -var ReactElement = require('ReactElement');
22 var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
23 var ReactCompositeComponent = require('ReactCompositeComponent');
24 var ReactInstanceMap = require('ReactInstanceMap');
@@ -61,7 +60,7 @@ function findAllInRenderedTreeInternal(inst, test) {
60 );
61 }
62 } else if (
64 - ReactElement.isValidElement(currentElement) &&
63 + React.isValidElement(currentElement) &&
64 typeof currentElement.type === 'function'
65 ) {
66 ret = ret.concat(
@@ -92,12 +91,12 @@ var ReactTestUtils = {
91 },
92
93 isElement: function(element) {
95 - return ReactElement.isValidElement(element);
94 + return React.isValidElement(element);
95 },
96
97 isElementOfType: function(inst, convenienceConstructor) {
98 return (
100 - ReactElement.isValidElement(inst) &&
99 + React.isValidElement(inst) &&
100 inst.type === convenienceConstructor
101 );
102 },
@@ -108,7 +107,7 @@ var ReactTestUtils = {
107
108 isDOMComponentElement: function(inst) {
109 return !!(inst &&
111 - ReactElement.isValidElement(inst) &&
110 + React.isValidElement(inst) &&
111 !!inst.tagName);
112 },
113
@@ -136,7 +135,7 @@ var ReactTestUtils = {
135 },
136
137 isCompositeComponentElement: function(inst) {
139 - if (!ReactElement.isValidElement(inst)) {
138 + if (!React.isValidElement(inst)) {
139 return false;
140 }
141 // We check the prototype of the type that will get mounted, not the
@@ -440,7 +439,7 @@ ReactShallowRenderer.prototype.render = function(element, context) {
439 ReactDefaultInjection.inject();
440
441 invariant(
443 - ReactElement.isValidElement(element),
442 + React.isValidElement(element),
443 'ReactShallowRenderer render(): Invalid component element.%s',
444 typeof element === 'function' ?
445 ' Instead of passing a component class, make sure to instantiate ' +