-
Notifications
You must be signed in to change notification settings - Fork 46.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flat bundle using Rollup #7178
Flat bundle using Rollup #7178
Conversation
This is pretty awesome! What kind of features does rollup have? Are we missing out on anything that doesn't get applied due to some pattern we use? |
That's really great @keyanzhang. Considering the |
@sebmarkbage I think if we switch to ES6 modules in our code base and have more named imports/exports, Rollup could shake the tree with a better granularity. My Babel pass can only change |
@STRML I'm no Rollup expert but seems it does both DCE and tree shaking (which is great). If you take a look at here you'll see that In our code base, |
Yeah, it can't know for sure if the exported object is modified at some point or uses Great to hear DCE + tree shaking means getting rid of the "require in a constant branch" hack. Really impressive stuff. |
Yeah, its DCE + tree shaking is really impressive. Here's an unminified production build bundled by Rollup: https://gist.github.com/keyanzhang/1dff99f6f54bcf9d4e3cc92ab407c41e (Note: |
@keyanzhang if you haven't seen it already, there's a Rollup plugin that will handle |
Thanks @ericf. I've tried that but it wraps modules and keeps individual |
I added 2 commits that DEV on some dev-only usage and side-effects. By doing this we can further remove @sebmarkbage I think we can have a mechanism that checks for these things first. We could consider adding more target flags like Moreover, 5ee5a97 is an example that shows the benefit of using named exports. All the usages of With these changes we can keep our production file size under 40k. Running "compare_size:files" (compare_size) task
raw gz Sizes
1199 641 build/react-dom-server.js
734 445 build/react-dom-server.min.js
1180 632 build/react-dom.js
715 436 build/react-dom.min.js
774615 173498 build/react-with-addons.js
176031 51851 build/react-with-addons.min.js
695941 157031 build/react.js
+ 597033 142815 build/react.rollup.dev.js
156814 46530 build/react.min.js
+ 132667 39971 build/react.rollup.prod.js |
Been playing with it for a bit, I think there are 2 approaches that we could choose from. Comments and feedback are more than welcome! 1. Switch to use ES6 modules in React's code base
2. Use the Babel transform trick as presented in this PR
|
FYI, React Native supports es6 modules :) |
Doesn't really matter if RN supports es6 modules since we'd need to compile to CommonJS for npm regardless, which is where RN gets React from anyway. |
@spicyj @vjeux does RN require React internals (like Another question is how far do we want to go on this. A low hanging fruit is to replace Browserify with Rollup -- that means we only make Or, we use our bundled file in npm -- as @zpao mentioned in #6351 (comment), we'll have "a single entry point that does the dev check, requiring & re-exporting either the min or dev version". |
I think there are 2 distinct steps (as you noted) and we should consider them separately for now. |
@zpao How about we use the babel trick for now and only replace Browserify with Rollup? |
@keyanzhang Can you try this on top of #7164 to see the effect? |
@sebmarkbage Sure. However I'm not sure what's a good way to lazily load (i.e., those getters) modules that depend on DOM internals since we can't have non-top-level requires. Could you give me some suggestions? |
@keyanzhang One thing you could do initially, is just ignore them for now or fallback to browserify. Those are only used in DEV and only the production build is really interesting. |
- move implementation of dev-only modules under a __DEV__ block. this ensures good DCE result for webpack/browserify users and FB's packager. - an explicit 'Dev' postfix is added to their module names modules renamed: - ReactElementValidator.js -> ReactElementValidatorDev.js - ReactComponentTreeDevtool.js -> ReactComponentTreeDevtoolDev.js - validateDOMNesting.js -> validateDOMNestingDev.js - ReactDOMDebugTool.js -> ReactDOMDebugToolDev.js - ReactDOMNullInputValuePropDevtool.js -> ReactDOMNullInputValuePropDevtoolDev.js - ReactDOMUnknownPropertyDevtool.js -> ReactDOMUnknownPropertyDevtoolDev.js - ReactDebugTool.js -> ReactDebugToolDev.js - ReactInstrumentation.js -> ReactInstrumentationDev.js - ReactPerf.js -> ReactPerfDev.js - ReactChildrenMutationWarningDevtool.js -> ReactChildrenMutationWarningDevtoolDev.js - ReactHostOperationHistoryDevtool.js -> ReactHostOperationHistoryDevtoolDev.js - ReactInvalidSetStateWarningDevTool.js -> ReactInvalidSetStateWarningDevToolDev.js - canDefineProperty.js -> canDefinePropertyDev.js
This PR is ready for review! Introducing a regression for webpack/Browserify users isn't great. After talking to @spicyj and @gaearon we decided to find all dev-only modules and hide their implementations under We also added a
As a side note, Size comparision: Running "compare_size:files" (compare_size) task
raw gz Sizes
1199 641 build/react-dom-server.js
734 445 build/react-dom-server.min.js
1180 632 build/react-dom.js
715 436 build/react-dom.min.js
+674209 158589 build/react-with-addons.js
-782976 175169 build/react-with-addons.js
+150724 44871 build/react-with-addons.min.js
-161325 47892 build/react-with-addons.min.js
+605887 144004 build/react.js
-704268 158059 build/react.js
+134184 40402 build/react.min.js
-149721 44593 build/react.min.js I tested with https://github.com/erikras/react-redux-universal-hot-example again and the webpack build was 2K smaller comparing with master (564K -> 562K). |
return val; | ||
}; | ||
|
||
var ReactPerfDev = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gaearon would you take a look at this? ReactPerf
is the only dev-only module that we publicly expose and it was refactored to make sure the public API doesn't break.
Sorry for the delay 😓 A few things…
Otherwise, still looks fine. |
diff --git a/404.html b/404.html new file mode 100644 index 0000000..5fd4569 --- /dev/null +++ b/404.html @@ -0,0 +1,4 @@ +--- +permalink: /404.html +--- +{% include_relative index.html %} diff --git a/bundle.js b/bundle.js index 9658bdb..ad96c92 100644 --- a/bundle.js +++ b/bundle.js @@ -50,25 +50,17 @@ var _react2 = _interopRequireDefault(_react); - var _reactDom = __webpack_require__(34); + var _reactDom = __webpack_require__(32); var _reactDom2 = _interopRequireDefault(_reactDom); - var _reactRedux = __webpack_require__(172); + var _reactRedux = __webpack_require__(178); - var _reactRouter = __webpack_require__(196); + var _router = __webpack_require__(216); - var _App = __webpack_require__(257); + var _router2 = _interopRequireDefault(_router); - var _NewBook = __webpack_require__(467); - - var _EditBook = __webpack_require__(486); - - var _ViewBook = __webpack_require__(487); - - var _ImportExport = __webpack_require__(489); - - var _store = __webpack_require__(496); + var _store = __webpack_require__(620); var _store2 = _interopRequireDefault(_store); @@ -77,18 +69,7 @@ _reactDom2.default.render(_react2.default.createElement( _reactRedux.Provider, { store: _store2.default }, - _react2.default.createElement( - _reactRouter.Router, - { history: _reactRouter.hashHistory }, - _react2.default.createElement( - _reactRouter.Route, - { path: '/', component: _App.AppContainer }, - _react2.default.createElement(_reactRouter.Route, { path: 'new(/:type)', component: _NewBook.NewBookContainer }), - _react2.default.createElement(_reactRouter.Route, { path: 'view/:uuid', component: _ViewBook.ViewBookContainer }), - _react2.default.createElement(_reactRouter.Route, { path: 'edit/:uuid', component: _EditBook.EditBookContainer }), - _react2.default.createElement(_reactRouter.Route, { path: 'io', component: _ImportExport.ImportExportContainer }) - ) - ) + (0, _router2.default)() ), document.getElementById('app')); /***/ }, @@ -112,7 +93,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule React */ 'use strict'; @@ -120,15 +100,15 @@ var _assign = __webpack_require__(4); var ReactChildren = __webpack_require__(5); - var ReactComponent = __webpack_require__(17); - var ReactPureComponent = __webpack_require__(20); - var ReactClass = __webpack_require__(21); - var ReactDOMFactories = __webpack_require__(26); + var ReactComponent = __webpack_require__(18); + var ReactPureComponent = __webpack_require__(21); + var ReactClass = __webpack_require__(22); + var ReactDOMFactories = __webpack_require__(24); var ReactElement = __webpack_require__(9); - var ReactPropTypes = __webpack_require__(31); - var ReactVersion = __webpack_require__(32); + var ReactPropTypes = __webpack_require__(29); + var ReactVersion = __webpack_require__(30); - var onlyChild = __webpack_require__(33); + var onlyChild = __webpack_require__(31); var warning = __webpack_require__(11); var createElement = ReactElement.createElement; @@ -136,7 +116,7 @@ var cloneElement = ReactElement.cloneElement; if (process.env.NODE_ENV !== 'production') { - var ReactElementValidator = __webpack_require__(27); + var ReactElementValidator = __webpack_require__(25); createElement = ReactElementValidator.createElement; createFactory = ReactElementValidator.createFactory; cloneElement = ReactElementValidator.cloneElement; @@ -482,7 +462,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactChildren */ 'use strict'; @@ -491,7 +470,7 @@ var ReactElement = __webpack_require__(9); var emptyFunction = __webpack_require__(12); - var traverseAllChildren = __webpack_require__(14); + var traverseAllChildren = __webpack_require__(15); var twoArgumentPooler = PooledClass.twoArgumentPooler; var fourArgumentPooler = PooledClass.fourArgumentPooler; @@ -522,8 +501,8 @@ PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); function forEachSingleChild(bookKeeping, child, name) { - var func = bookKeeping.func; - var context = bookKeeping.context; + var func = bookKeeping.func, + context = bookKeeping.context; func.call(context, child, bookKeeping.count++); } @@ -575,10 +554,10 @@ PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler); function mapSingleChildIntoContext(bookKeeping, child, childKey) { - var result = bookKeeping.result; - var keyPrefix = bookKeeping.keyPrefix; - var func = bookKeeping.func; - var context = bookKeeping.context; + var result = bookKeeping.result, + keyPrefix = bookKeeping.keyPrefix, + func = bookKeeping.func, + context = bookKeeping.context; var mappedChild = func.call(context, child, bookKeeping.count++); @@ -678,7 +657,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule PooledClass + * */ 'use strict'; @@ -738,17 +717,6 @@ } }; - var fiveArgumentPooler = function (a1, a2, a3, a4, a5) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4, a5); - return instance; - } else { - return new Klass(a1, a2, a3, a4, a5); - } - }; - var standardReleaser = function (instance) { var Klass = this; !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; @@ -771,6 +739,8 @@ * @param {Function} pooler Customizable pooler. */ var addPoolingTo = function (CopyConstructor, pooler) { + // Casting as any so that flow ignores the actual implementation and trusts + // it to match the type we declared var NewKlass = CopyConstructor; NewKlass.instancePool = []; NewKlass.getPooled = pooler || DEFAULT_POOLER; @@ -786,8 +756,7 @@ oneArgumentPooler: oneArgumentPooler, twoArgumentPooler: twoArgumentPooler, threeArgumentPooler: threeArgumentPooler, - fourArgumentPooler: fourArgumentPooler, - fiveArgumentPooler: fiveArgumentPooler + fourArgumentPooler: fourArgumentPooler }; module.exports = PooledClass; @@ -805,7 +774,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule reactProdInvariant * */ 'use strict'; @@ -864,12 +832,18 @@ * will remain to ensure logic does not differ in production. */ - function invariant(condition, format, a, b, c, d, e, f) { - if (process.env.NODE_ENV !== 'production') { + var validateFormat = function validateFormat(format) {}; + + if (process.env.NODE_ENV !== 'production') { + validateFormat = function validateFormat(format) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } - } + }; + } + + function invariant(condition, format, a, b, c, d, e, f) { + validateFormat(format); if (!condition) { var error; @@ -904,7 +878,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactElement */ 'use strict'; @@ -917,9 +890,7 @@ var canDefineProperty = __webpack_require__(13); var hasOwnProperty = Object.prototype.hasOwnProperty; - // The Symbol used to tag the ReactElement type. If there is no native Symbol - // nor polyfill, then a plain number is used for performance. - var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; + var REACT_ELEMENT_TYPE = __webpack_require__(14); var RESERVED_PROPS = { key: true, @@ -1023,7 +994,6 @@ // This can be replaced with a WeakMap once they are implemented in // commonly used development environments. element._store = {}; - var shadowChildren = Array.isArray(props.children) ? props.children.slice(0) : props.children; // To make comparing ReactElements easier for testing purposes, we make // the validation flag non-enumerable (where possible, which should @@ -1043,12 +1013,6 @@ writable: false, value: self }); - Object.defineProperty(element, '_shadowChildren', { - configurable: false, - enumerable: false, - writable: false, - value: shadowChildren - }); // Two elements created in two different places should be considered // equal for testing purposes and therefore we hide it from enumeration. Object.defineProperty(element, '_source', { @@ -1060,7 +1024,6 @@ } else { element._store.validated = false; element._self = self; - element._shadowChildren = shadowChildren; element._source = source; } if (Object.freeze) { @@ -1115,6 +1078,11 @@ for (var i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 2]; } + if (process.env.NODE_ENV !== 'production') { + if (Object.freeze) { + Object.freeze(childArray); + } + } props.children = childArray; } @@ -1241,8 +1209,6 @@ return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; }; - ReactElement.REACT_ELEMENT_TYPE = REACT_ELEMENT_TYPE; - module.exports = ReactElement; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) @@ -1258,7 +1224,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactCurrentOwner + * */ 'use strict'; @@ -1269,7 +1235,6 @@ * The current owner is the component who should own any components that are * currently being constructed. */ - var ReactCurrentOwner = { /** @@ -1409,7 +1374,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule canDefineProperty + * */ 'use strict'; @@ -1417,6 +1382,7 @@ var canDefineProperty = false; if (process.env.NODE_ENV !== 'production') { try { + // $FlowFixMe https://github.com/facebook/flow/issues/285 Object.defineProperty({}, 'x', { get: function () {} }); canDefineProperty = true; } catch (x) { @@ -1429,6 +1395,30 @@ /***/ }, /* 14 */ +/***/ function(module, exports) { + + /** + * Copyright 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * + */ + + 'use strict'; + + // The Symbol used to tag the ReactElement type. If there is no native Symbol + // nor polyfill, then a plain number is used for performance. + + var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; + + module.exports = REACT_ELEMENT_TYPE; + +/***/ }, +/* 15 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -1439,7 +1429,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule traverseAllChildren */ 'use strict'; @@ -1447,17 +1436,23 @@ var _prodInvariant = __webpack_require__(7); var ReactCurrentOwner = __webpack_require__(10); - var ReactElement = __webpack_require__(9); + var REACT_ELEMENT_TYPE = __webpack_require__(14); - var getIteratorFn = __webpack_require__(15); + var getIteratorFn = __webpack_require__(16); var invariant = __webpack_require__(8); - var KeyEscapeUtils = __webpack_require__(16); + var KeyEscapeUtils = __webpack_require__(17); var warning = __webpack_require__(11); var SEPARATOR = '.'; var SUBSEPARATOR = ':'; /** + * This is inlined from ReactElement since this file is shared between + * isomorphic and renderers. We could extract this to a + * + */ + + /** * TODO: Test that a single child and an array with one item have the same key * pattern. */ @@ -1498,7 +1493,10 @@ children = null; } - if (children === null || type === 'string' || type === 'number' || ReactElement.isValidElement(children)) { + if (children === null || type === 'string' || type === 'number' || + // The following is inlined from ReactElement. This means we can optimize + // some checks. React Fiber also inlines this logic for similar purposes. + type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) { callback(traverseContext, children, // If it's the only child, treat the name as if it was wrapped in an array // so that it's consistent if the number of children grows. @@ -1601,7 +1599,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 15 */ +/* 16 */ /***/ function(module, exports) { /** @@ -1612,7 +1610,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule getIteratorFn * */ @@ -1647,7 +1644,7 @@ module.exports = getIteratorFn; /***/ }, -/* 16 */ +/* 17 */ /***/ function(module, exports) { /** @@ -1658,7 +1655,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule KeyEscapeUtils * */ @@ -1711,7 +1707,7 @@ module.exports = KeyEscapeUtils; /***/ }, -/* 17 */ +/* 18 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -1722,17 +1718,16 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactComponent */ 'use strict'; var _prodInvariant = __webpack_require__(7); - var ReactNoopUpdateQueue = __webpack_require__(18); + var ReactNoopUpdateQueue = __webpack_require__(19); var canDefineProperty = __webpack_require__(13); - var emptyObject = __webpack_require__(19); + var emptyObject = __webpack_require__(20); var invariant = __webpack_require__(8); var warning = __webpack_require__(11); @@ -1835,7 +1830,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 18 */ +/* 19 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -1846,7 +1841,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactNoopUpdateQueue */ 'use strict'; @@ -1937,7 +1931,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 19 */ +/* 20 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -1962,7 +1956,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 20 */ +/* 21 */ /***/ function(module, exports, __webpack_require__) { /** @@ -1973,17 +1967,16 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactPureComponent */ 'use strict'; var _assign = __webpack_require__(4); - var ReactComponent = __webpack_require__(17); - var ReactNoopUpdateQueue = __webpack_require__(18); + var ReactComponent = __webpack_require__(18); + var ReactNoopUpdateQueue = __webpack_require__(19); - var emptyObject = __webpack_require__(19); + var emptyObject = __webpack_require__(20); /** * Base class helpers for the updating state of a component. @@ -2009,7 +2002,7 @@ module.exports = ReactPureComponent; /***/ }, -/* 21 */ +/* 22 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -2020,7 +2013,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactClass */ 'use strict'; @@ -2028,44 +2020,27 @@ var _prodInvariant = __webpack_require__(7), _assign = __webpack_require__(4); - var ReactComponent = __webpack_require__(17); + var ReactComponent = __webpack_require__(18); var ReactElement = __webpack_require__(9); - var ReactPropTypeLocations = __webpack_require__(22); - var ReactPropTypeLocationNames = __webpack_require__(24); - var ReactNoopUpdateQueue = __webpack_require__(18); + var ReactPropTypeLocationNames = __webpack_require__(23); + var ReactNoopUpdateQueue = __webpack_require__(19); - var emptyObject = __webpack_require__(19); + var emptyObject = __webpack_require__(20); var invariant = __webpack_require__(8); - var keyMirror = __webpack_require__(23); - var keyOf = __webpack_require__(25); var warning = __webpack_require__(11); - var MIXINS_KEY = keyOf({ mixins: null }); + var MIXINS_KEY = 'mixins'; + + // Helper function to allow the creation of anonymous functions which do not + // have .name set to the name of the variable being assigned to. + function identity(fn) { + return fn; + } /** * Policies that describe methods in `ReactClassInterface`. */ - var SpecPolicy = keyMirror({ - /** - * These methods may be defined only once by the class specification or mixin. - */ - DEFINE_ONCE: null, - /** - * These methods may be defined by both the class specification and mixins. - * Subsequent definitions will be chained. These methods must return void. - */ - DEFINE_MANY: null, - /** - * These methods are overriding the base class. - */ - OVERRIDE_BASE: null, - /** - * These methods are similar to DEFINE_MANY, except we assume they return - * objects. We try to merge the keys of the return values of all the mixed in - * functions. If there is a key conflict we throw. - */ - DEFINE_MANY_MERGED: null - }); + var injectedMixins = []; @@ -2099,7 +2074,7 @@ * @type {array} * @optional */ - mixins: SpecPolicy.DEFINE_MANY, + mixins: 'DEFINE_MANY', /** * An object containing properties and methods that should be defined on @@ -2108,7 +2083,7 @@ * @type {object} * @optional */ - statics: SpecPolicy.DEFINE_MANY, + statics: 'DEFINE_MANY', /** * Definition of prop types for this component. @@ -2116,7 +2091,7 @@ * @type {object} * @optional */ - propTypes: SpecPolicy.DEFINE_MANY, + propTypes: 'DEFINE_MANY', /** * Definition of context types for this component. @@ -2124,7 +2099,7 @@ * @type {object} * @optional */ - contextTypes: SpecPolicy.DEFINE_MANY, + contextTypes: 'DEFINE_MANY', /** * Definition of context types this component sets for its children. @@ -2132,7 +2107,7 @@ * @type {object} * @optional */ - childContextTypes: SpecPolicy.DEFINE_MANY, + childContextTypes: 'DEFINE_MANY', // ==== Definition methods ==== @@ -2146,7 +2121,7 @@ * @return {object} * @optional */ - getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, + getDefaultProps: 'DEFINE_MANY_MERGED', /** * Invoked once before the component is mounted. The return value will be used @@ -2162,13 +2137,13 @@ * @return {object} * @optional */ - getInitialState: SpecPolicy.DEFINE_MANY_MERGED, + getInitialState: 'DEFINE_MANY_MERGED', /** * @return {object} * @optional */ - getChildContext: SpecPolicy.DEFINE_MANY_MERGED, + getChildContext: 'DEFINE_MANY_MERGED', /** * Uses props from `this.props` and state from `this.state` to render the @@ -2186,7 +2161,7 @@ * @nosideeffects * @required */ - render: SpecPolicy.DEFINE_ONCE, + render: 'DEFINE_ONCE', // ==== Delegate methods ==== @@ -2197,7 +2172,7 @@ * * @optional */ - componentWillMount: SpecPolicy.DEFINE_MANY, + componentWillMount: 'DEFINE_MANY', /** * Invoked when the component has been mounted and has a DOM representation. @@ -2209,7 +2184,7 @@ * @param {DOMElement} rootNode DOM element representing the component. * @optional */ - componentDidMount: SpecPolicy.DEFINE_MANY, + componentDidMount: 'DEFINE_MANY', /** * Invoked before the component receives new props. @@ -2230,7 +2205,7 @@ * @param {object} nextProps * @optional */ - componentWillReceiveProps: SpecPolicy.DEFINE_MANY, + componentWillReceiveProps: 'DEFINE_MANY', /** * Invoked while deciding if the component should be updated as a result of @@ -2252,7 +2227,7 @@ * @return {boolean} True if the component should update. * @optional */ - shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, + shouldComponentUpdate: 'DEFINE_ONCE', /** * Invoked when the component is about to update due to a transition from @@ -2269,7 +2244,7 @@ * @param {ReactReconcileTransaction} transaction * @optional */ - componentWillUpdate: SpecPolicy.DEFINE_MANY, + componentWillUpdate: 'DEFINE_MANY', /** * Invoked when the component's DOM representation has been updated. @@ -2283,7 +2258,7 @@ * @param {DOMElement} rootNode DOM element representing the component. * @optional */ - componentDidUpdate: SpecPolicy.DEFINE_MANY, + componentDidUpdate: 'DEFINE_MANY', /** * Invoked when the component is about to be removed from its parent and have @@ -2296,7 +2271,7 @@ * * @optional */ - componentWillUnmount: SpecPolicy.DEFINE_MANY, + componentWillUnmount: 'DEFINE_MANY', // ==== Advanced methods ==== @@ -2310,7 +2285,7 @@ * @internal * @overridable */ - updateComponent: SpecPolicy.OVERRIDE_BASE + updateComponent: 'OVERRIDE_BASE' }; @@ -2336,13 +2311,13 @@ }, childContextTypes: function (Constructor, childContextTypes) { if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, childContextTypes, ReactPropTypeLocations.childContext); + validateTypeDef(Constructor, childContextTypes, 'childContext'); } Constructor.childContextTypes = _assign({}, Constructor.childContextTypes, childContextTypes); }, contextTypes: function (Constructor, contextTypes) { if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, contextTypes, ReactPropTypeLocations.context); + validateTypeDef(Constructor, contextTypes, 'context'); } Constructor.contextTypes = _assign({}, Constructor.contextTypes, contextTypes); }, @@ -2359,7 +2334,7 @@ }, propTypes: function (Constructor, propTypes) { if (process.env.NODE_ENV !== 'production') { - validateTypeDef(Constructor, propTypes, ReactPropTypeLocations.prop); + validateTypeDef(Constructor, propTypes, 'prop'); } Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes); }, @@ -2368,7 +2343,6 @@ }, autobind: function () {} }; - // noop function validateTypeDef(Constructor, typeDef, location) { for (var propName in typeDef) { if (typeDef.hasOwnProperty(propName)) { @@ -2384,12 +2358,12 @@ // Disallow overriding of base class methods unless explicitly allowed. if (ReactClassMixin.hasOwnProperty(name)) { - !(specPolicy === SpecPolicy.OVERRIDE_BASE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override `%s` from your class specification. Ensure that your method names do not overlap with React methods.', name) : _prodInvariant('73', name) : void 0; + !(specPolicy === 'OVERRIDE_BASE') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to override `%s` from your class specification. Ensure that your method names do not overlap with React methods.', name) : _prodInvariant('73', name) : void 0; } // Disallow defining methods more than once unless explicitly allowed. if (isAlreadyDefined) { - !(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : _prodInvariant('74', name) : void 0; + !(specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClassInterface: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : _prodInvariant('74', name) : void 0; } } @@ -2455,13 +2429,13 @@ var specPolicy = ReactClassInterface[name]; // These cases should already be caught by validateMethodOverride. - !(isReactClassMethod && (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s when mixing in component specs.', specPolicy, name) : _prodInvariant('77', specPolicy, name) : void 0; + !(isReactClassMethod && (specPolicy === 'DEFINE_MANY_MERGED' || specPolicy === 'DEFINE_MANY')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s when mixing in component specs.', specPolicy, name) : _prodInvariant('77', specPolicy, name) : void 0; // For methods which are defined more than once, call the existing // methods before calling the new property, merging if appropriate. - if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { + if (specPolicy === 'DEFINE_MANY_MERGED') { proto[name] = createMergedResultFunction(proto[name], property); - } else if (specPolicy === SpecPolicy.DEFINE_MANY) { + } else if (specPolicy === 'DEFINE_MANY') { proto[name] = createChainedFunction(proto[name], property); } } else { @@ -2656,7 +2630,10 @@ * @public */ createClass: function (spec) { - var Constructor = function (props, context, updater) { + // To keep our warnings more understandable, we'll use a little hack here to + // ensure that Constructor.name !== 'Constructor'. This makes sure we don't + // unnecessarily identify a class without displayName as 'Constructor'. + var Constructor = identity(function (props, context, updater) { // This constructor gets overridden by mocks. The argument is used // by mocks to assert on what gets mounted. @@ -2691,7 +2668,7 @@ !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : _prodInvariant('82', Constructor.displayName || 'ReactCompositeComponent') : void 0; this.state = initialState; - }; + }); Constructor.prototype = new ReactClassComponent(); Constructor.prototype.constructor = Constructor; Constructor.prototype.__reactAutoBindPairs = []; @@ -2747,90 +2724,10 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 22 */ -/***/ function(module, exports, __webpack_require__) { - - /** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactPropTypeLocations - */ - - 'use strict'; - - var keyMirror = __webpack_require__(23); - - var ReactPropTypeLocations = keyMirror({ - prop: null, - context: null, - childContext: null - }); - - module.exports = ReactPropTypeLocations; - -/***/ }, /* 23 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @typechecks static-only - */ - - 'use strict'; - - var invariant = __webpack_require__(8); - - /** - * Constructs an enumeration with keys equal to their value. - * - * For example: - * - * var COLORS = keyMirror({blue: null, red: null}); - * var myColor = COLORS.blue; - * var isColorValid = !!COLORS[myColor]; - * - * The last line could not be performed if the values of the generated enum were - * not equal to their keys. - * - * Input: {key1: val1, key2: val2} - * Output: {key1: key1, key2: key2} - * - * @param {object} obj - * @return {object} - */ - var keyMirror = function keyMirror(obj) { - var ret = {}; - var key; - !(obj instanceof Object && !Array.isArray(obj)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'keyMirror(...): Argument must be an object.') : invariant(false) : void 0; - for (key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - ret[key] = key; - } - return ret; - }; - - module.exports = keyMirror; - /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) - -/***/ }, -/* 24 */ -/***/ function(module, exports, __webpack_require__) { - - /* WEBPACK VAR INJECTION */(function(process) {/** * Copyright 2013-present, Facebook, Inc. * All rights reserved. * @@ -2838,7 +2735,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactPropTypeLocationNames + * */ 'use strict'; @@ -2857,46 +2754,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 25 */ -/***/ function(module, exports) { - - "use strict"; - - /** - * Copyright (c) 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - - /** - * Allows extraction of a minified key. Let's the build system minify keys - * without losing the ability to dynamically use key strings as values - * themselves. Pass in an object with a single key/val pair and it will return - * you the string key of that single record. Suppose you want to grab the - * value for a key 'className' inside of an object. Key/val minification may - * have aliased that key to be 'xa12'. keyOf({className: null}) will return - * 'xa12' in that case. Resolve keys you want to use once at startup time, then - * reuse those resolutions. - */ - var keyOf = function keyOf(oneKeyObj) { - var key; - for (key in oneKeyObj) { - if (!oneKeyObj.hasOwnProperty(key)) { - continue; - } - return key; - } - return null; - }; - - module.exports = keyOf; - -/***/ }, -/* 26 */ +/* 24 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -2907,7 +2765,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactDOMFactories */ 'use strict'; @@ -2921,7 +2778,7 @@ */ var createDOMFactory = ReactElement.createFactory; if (process.env.NODE_ENV !== 'production') { - var ReactElementValidator = __webpack_require__(27); + var ReactElementValidator = __webpack_require__(25); createDOMFactory = ReactElementValidator.createFactory; } @@ -3072,7 +2929,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 27 */ +/* 25 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -3083,7 +2940,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactElementValidator */ /** @@ -3096,14 +2952,13 @@ 'use strict'; var ReactCurrentOwner = __webpack_require__(10); - var ReactComponentTreeHook = __webpack_require__(28); + var ReactComponentTreeHook = __webpack_require__(26); var ReactElement = __webpack_require__(9); - var ReactPropTypeLocations = __webpack_require__(22); - var checkReactTypeSpec = __webpack_require__(29); + var checkReactTypeSpec = __webpack_require__(27); var canDefineProperty = __webpack_require__(13); - var getIteratorFn = __webpack_require__(15); + var getIteratorFn = __webpack_require__(16); var warning = __webpack_require__(11); function getDeclarationErrorAddendum() { @@ -3227,7 +3082,7 @@ } var name = componentClass.displayName || componentClass.name; if (componentClass.propTypes) { - checkReactTypeSpec(componentClass.propTypes, element.props, ReactPropTypeLocations.prop, name, element, null); + checkReactTypeSpec(componentClass.propTypes, element.props, 'prop', name, element, null); } if (typeof componentClass.getDefaultProps === 'function') { process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : void 0; @@ -3241,7 +3096,14 @@ // We warn in this case but don't throw. We expect the element creation to // succeed and there will likely be errors in render. if (!validType) { - process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()) : void 0; + if (typeof type !== 'function' && typeof type !== 'string') { + var info = ''; + if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { + info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.'; + } + info += getDeclarationErrorAddendum(); + process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', type == null ? type : typeof type, info) : void 0; + } } var element = ReactElement.createElement.apply(this, arguments); @@ -3306,7 +3168,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 28 */ +/* 26 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -3317,7 +3179,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactComponentTreeHook + * */ 'use strict'; @@ -3360,113 +3222,96 @@ // Set.prototype.keys Set.prototype != null && typeof Set.prototype.keys === 'function' && isNative(Set.prototype.keys); - var itemMap; - var rootIDSet; - - var itemByKey; - var rootByKey; + var setItem; + var getItem; + var removeItem; + var getItemIDs; + var addRoot; + var removeRoot; + var getRootIDs; if (canUseCollections) { - itemMap = new Map(); - rootIDSet = new Set(); - } else { - itemByKey = {}; - rootByKey = {}; - } - - var unmountedIDs = []; - - // Use non-numeric keys to prevent V8 performance issues: - // https://github.com/facebook/react/pull/7232 - function getKeyFromID(id) { - return '.' + id; - } - function getIDFromKey(key) { - return parseInt(key.substr(1), 10); - } + var itemMap = new Map(); + var rootIDSet = new Set(); - function get(id) { - if (canUseCollections) { + setItem = function (id, item) { + itemMap.set(id, item); + }; + getItem = function (id) { return itemMap.get(id); - } else { - var key = getKeyFromID(id); - return itemByKey[key]; - } - } - - function remove(id) { - if (canUseCollections) { + }; + removeItem = function (id) { itemMap['delete'](id); - } else { - var key = getKeyFromID(id); - delete itemByKey[key]; - } - } + }; + getItemIDs = function () { + return Array.from(itemMap.keys()); + }; - function create(id, element, parentID) { - var item = { - element: element, - parentID: parentID, - text: null, - childIDs: [], - isMounted: false, - updateCount: 0 + addRoot = function (id) { + rootIDSet.add(id); + }; + removeRoot = function (id) { + rootIDSet['delete'](id); }; + getRootIDs = function () { + return Array.from(rootIDSet.keys()); + }; + } else { + var itemByKey = {}; + var rootByKey = {}; - if (canUseCollections) { - itemMap.set(id, item); - } else { + // Use non-numeric keys to prevent V8 performance issues: + // https://github.com/facebook/react/pull/7232 + var getKeyFromID = function (id) { + return '.' + id; + }; + var getIDFromKey = function (key) { + return parseInt(key.substr(1), 10); + }; + + setItem = function (id, item) { var key = getKeyFromID(id); itemByKey[key] = item; - } - } + }; + getItem = function (id) { + var key = getKeyFromID(id); + return itemByKey[key]; + }; + removeItem = function (id) { + var key = getKeyFromID(id); + delete itemByKey[key]; + }; + getItemIDs = function () { + return Object.keys(itemByKey).map(getIDFromKey); + }; - function addRoot(id) { - if (canUseCollections) { - rootIDSet.add(id); - } else { + addRoot = function (id) { var key = getKeyFromID(id); rootByKey[key] = true; - } - } - - function removeRoot(id) { - if (canUseCollections) { - rootIDSet['delete'](id); - } else { + }; + removeRoot = function (id) { var key = getKeyFromID(id); delete rootByKey[key]; - } - } - - function getRegisteredIDs() { - if (canUseCollections) { - return Array.from(itemMap.keys()); - } else { - return Object.keys(itemByKey).map(getIDFromKey); - } - } - - function getRootIDs() { - if (canUseCollections) { - return Array.from(rootIDSet.keys()); - } else { + }; + getRootIDs = function () { return Object.keys(rootByKey).map(getIDFromKey); - } + }; } + var unmountedIDs = []; + function purgeDeep(id) { - var item = get(id); + var item = getItem(id); if (item) { var childIDs = item.childIDs; - remove(id); + removeItem(id); childIDs.forEach(purgeDeep); } } function describeComponentFrame(name, source, ownerName) { - return '\n in ' + name + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); + return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); } function getDisplayName(element) { @@ -3495,12 +3340,13 @@ var ReactComponentTreeHook = { onSetChildren: function (id, nextChildIDs) { - var item = get(id); + var item = getItem(id); + !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0; item.childIDs = nextChildIDs; for (var i = 0; i < nextChildIDs.length; i++) { var nextChildID = nextChildIDs[i]; - var nextChild = get(nextChildID); + var nextChild = getItem(nextChildID); !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected hook events to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('140') : void 0; !(nextChild.childIDs != null || typeof nextChild.element !== 'object' || nextChild.element == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() to fire for a container child before its parent includes it in onSetChildren().') : _prodInvariant('141') : void 0; !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('71') : void 0; @@ -3508,16 +3354,24 @@ nextChild.parentID = id; // TODO: This shouldn't be necessary but mounting a new root during in // componentWillMount currently causes not-yet-mounted components to - // be purged from our tree data so their parent ID is missing. + // be purged from our tree data so their parent id is missing. } !(nextChild.parentID === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onBeforeMountComponent() parent and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : _prodInvariant('142', nextChildID, nextChild.parentID, id) : void 0; } }, onBeforeMountComponent: function (id, element, parentID) { - create(id, element, parentID); + var item = { + element: element, + parentID: parentID, + text: null, + childIDs: [], + isMounted: false, + updateCount: 0 + }; + setItem(id, item); }, onBeforeUpdateComponent: function (id, element) { - var item = get(id); + var item = getItem(id); if (!item || !item.isMounted) { // We may end up here as a result of setState() in componentWillUnmount(). // In this case, ignore the element. @@ -3526,7 +3380,8 @@ item.element = element; }, onMountComponent: function (id) { - var item = get(id); + var item = getItem(id); + !item ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Item must have been set') : _prodInvariant('144') : void 0; item.isMounted = true; var isRoot = item.parentID === 0; if (isRoot) { @@ -3534,7 +3389,7 @@ } }, onUpdateComponent: function (id) { - var item = get(id); + var item = getItem(id); if (!item || !item.isMounted) { // We may end up here as a result of setState() in componentWillUnmount(). // In this case, ignore the element. @@ -3543,7 +3398,7 @@ item.updateCount++; }, onUnmountComponent: function (id) { - var item = get(id); + var item = getItem(id); if (item) { // We need to check if it exists. // `item` might not exist if it is inside an error boundary, and a sibling @@ -3571,16 +3426,15 @@ unmountedIDs.length = 0; }, isMounted: function (id) { - var item = get(id); + var item = getItem(id); return item ? item.isMounted : false; }, getCurrentStackAddendum: function (topElement) { var info = ''; if (topElement) { - var type = topElement.type; - var name = typeof type === 'function' ? type.displayName || type.name : type; + var name = getDisplayName(topElement); var owner = topElement._owner; - info += describeComponentFrame(name || 'Unknown', topElement._source, owner && owner.getName()); + info += describeComponentFrame(name, topElement._source, owner && owner.getName()); } var currentOwner = ReactCurrentOwner.current; @@ -3598,7 +3452,7 @@ return info; }, getChildIDs: function (id) { - var item = get(id); + var item = getItem(id); return item ? item.childIDs : []; }, getDisplayName: function (id) { @@ -3609,7 +3463,7 @@ return getDisplayName(element); }, getElement: function (id) { - var item = get(id); + var item = getItem(id); return item ? item.element : null; }, getOwnerID: function (id) { @@ -3620,11 +3474,11 @@ return element._owner._debugID; }, getParentID: function (id) { - var item = get(id); + var item = getItem(id); return item ? item.parentID : null; }, getSource: function (id) { - var item = get(id); + var item = getItem(id); var element = item ? item.element : null; var source = element != null ? element._source : null; return source; @@ -3640,21 +3494,20 @@ } }, getUpdateCount: function (id) { - var item = get(id); + var item = getItem(id); return item ? item.updateCount : 0; }, - getRegisteredIDs: getRegisteredIDs, - - getRootIDs: getRootIDs + getRootIDs: getRootIDs, + getRegisteredIDs: getItemIDs }; module.exports = ReactComponentTreeHook; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 29 */ +/* 27 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -3665,15 +3518,14 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule checkReactTypeSpec */ 'use strict'; var _prodInvariant = __webpack_require__(7); - var ReactPropTypeLocationNames = __webpack_require__(24); - var ReactPropTypesSecret = __webpack_require__(30); + var ReactPropTypeLocationNames = __webpack_require__(23); + var ReactPropTypesSecret = __webpack_require__(28); var invariant = __webpack_require__(8); var warning = __webpack_require__(11); @@ -3686,7 +3538,7 @@ // https://github.com/facebook/react/issues/7240 // Remove the inline requires when we don't need them anymore: // https://github.com/facebook/react/pull/7178 - ReactComponentTreeHook = __webpack_require__(28); + ReactComponentTreeHook = __webpack_require__(26); } var loggedTypeFailures = {}; @@ -3728,7 +3580,7 @@ if (process.env.NODE_ENV !== 'production') { if (!ReactComponentTreeHook) { - ReactComponentTreeHook = __webpack_require__(28); + ReactComponentTreeHook = __webpack_require__(26); } if (debugID !== null) { componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); @@ -3747,7 +3599,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 30 */ +/* 28 */ /***/ function(module, exports) { /** @@ -3758,7 +3610,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactPropTypesSecret + * */ 'use strict'; @@ -3768,7 +3620,7 @@ module.exports = ReactPropTypesSecret; /***/ }, -/* 31 */ +/* 29 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -3779,17 +3631,16 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactPropTypes */ 'use strict'; var ReactElement = __webpack_require__(9); - var ReactPropTypeLocationNames = __webpack_require__(24); - var ReactPropTypesSecret = __webpack_require__(30); + var ReactPropTypeLocationNames = __webpack_require__(23); + var ReactPropTypesSecret = __webpack_require__(28); var emptyFunction = __webpack_require__(12); - var getIteratorFn = __webpack_require__(15); + var getIteratorFn = __webpack_require__(16); var warning = __webpack_require__(11); /** @@ -3904,7 +3755,7 @@ if (secret !== ReactPropTypesSecret && typeof console !== 'undefined') { var cacheKey = componentName + ':' + propName; if (!manualPropTypeCallCache[cacheKey]) { - process.env.NODE_ENV !== 'production' ? warning(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will not work in the next major version. You may be ' + 'seeing this warning due to a third-party PropTypes library. ' + 'See https://fb.me/react-warning-dont-call-proptypes for details.', propFullName, componentName) : void 0; + process.env.NODE_ENV !== 'production' ? warning(false, 'You are manually calling a React.PropTypes validation ' + 'function for the `%s` prop on `%s`. This is deprecated ' + 'and will not work in production with the next major version. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.', propFullName, componentName) : void 0; manualPropTypeCallCache[cacheKey] = true; } } @@ -3912,7 +3763,10 @@ if (props[propName] == null) { var locationName = ReactPropTypeLocationNames[location]; if (isRequired) { - return new PropTypeError('Required ' + locationName + ' `' + propFullName + '` was not specified in ' + ('`' + componentName + '`.')); + if (props[propName] === null) { + return new PropTypeError('The ' + locationName + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); + } + return new PropTypeError('The ' + locationName + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); } return null; } else { @@ -4205,7 +4059,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 32 */ +/* 30 */ /***/ function(module, exports) { /** @@ -4216,15 +4070,14 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactVersion */ 'use strict'; - module.exports = '15.3.2'; + module.exports = '15.4.2'; /***/ }, -/* 33 */ +/* 31 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -4235,7 +4088,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule onlyChild */ 'use strict'; @@ -4268,16 +4120,16 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 34 */ +/* 32 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; - module.exports = __webpack_require__(35); + module.exports = __webpack_require__(33); /***/ }, -/* 35 */ +/* 33 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -4288,23 +4140,22 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactDOM */ /* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ 'use strict'; - var ReactDOMComponentTree = __webpack_require__(36); - var ReactDefaultInjection = __webpack_require__(39); - var ReactMount = __webpack_require__(162); + var ReactDOMComponentTree = __webpack_require__(34); + var ReactDefaultInjection = __webpack_require__(38); + var ReactMount = __webpack_require__(166); var ReactReconciler = __webpack_require__(59); var ReactUpdates = __webpack_require__(56); - var ReactVersion = __webpack_require__(32); + var ReactVersion = __webpack_require__(171); - var findDOMNode = __webpack_require__(167); - var getHostComponentFromComposite = __webpack_require__(168); - var renderSubtreeIntoContainer = __webpack_require__(169); + var findDOMNode = __webpack_require__(172); + var getHostComponentFromComposite = __webpack_require__(173); + var renderSubtreeIntoContainer = __webpack_require__(174); var warning = __webpack_require__(11); ReactDefaultInjection.inject(); @@ -4322,7 +4173,6 @@ // Inject the runtime into a devtools global hook regardless of browser. // Allows for debugging when the hook is injected on the page. - /* eslint-enable camelcase */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ ComponentTree: { @@ -4345,7 +4195,7 @@ } if (process.env.NODE_ENV !== 'production') { - var ExecutionEnvironment = __webpack_require__(49); + var ExecutionEnvironment = __webpack_require__(48); if (ExecutionEnvironment.canUseDOM && window.top === window.self) { // First check if devtools is not installed @@ -4369,7 +4219,7 @@ var expectedFeatures = [ // shims - Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim]; + Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.trim]; for (var i = 0; i < expectedFeatures.length; i++) { if (!expectedFeatures[i]) { @@ -4382,18 +4232,20 @@ if (process.env.NODE_ENV !== 'production') { var ReactInstrumentation = __webpack_require__(62); - var ReactDOMUnknownPropertyHook = __webpack_require__(170); - var ReactDOMNullInputValuePropHook = __webpack_require__(171); + var ReactDOMUnknownPropertyHook = __webpack_require__(175); + var ReactDOMNullInputValuePropHook = __webpack_require__(176); + var ReactDOMInvalidARIAHook = __webpack_require__(177); ReactInstrumentation.debugTool.addHook(ReactDOMUnknownPropertyHook); ReactInstrumentation.debugTool.addHook(ReactDOMNullInputValuePropHook); + ReactInstrumentation.debugTool.addHook(ReactDOMInvalidARIAHook); } module.exports = ReactDOM; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 36 */ +/* 34 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -4404,15 +4256,14 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactDOMComponentTree */ 'use strict'; - var _prodInvariant = __webpack_require__(7); + var _prodInvariant = __webpack_require__(35); - var DOMProperty = __webpack_require__(37); - var ReactDOMComponentFlags = __webpack_require__(38); + var DOMProperty = __webpack_require__(36); + var ReactDOMComponentFlags = __webpack_require__(37); var invariant = __webpack_require__(8); @@ -4422,6 +4273,13 @@ var internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2); /** + * Check if a given node should be cached. + */ + function shouldPrecacheNode(node, nodeID) { + return node.nodeType === 1 && node.getAttribute(ATTR_NAME) === String(nodeID) || node.nodeType === 8 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === 8 && node.nodeValue === ' react-empty: ' + nodeID + ' '; + } + + /** * Drill down (through composites and empty components) until we get a host or * host text component. * @@ -4486,7 +4344,7 @@ } // We assume the child nodes are in the same order as the child instances. for (; childNode !== null; childNode = childNode.nextSibling) { - if (childNode.nodeType === 1 && childNode.getAttribute(ATTR_NAME) === String(childID) || childNode.nodeType === 8 && childNode.nodeValue === ' react-text: ' + childID + ' ' || childNode.nodeType === 8 && childNode.nodeValue === ' react-empty: ' + childID + ' ') { + if (shouldPrecacheNode(childNode, childID)) { precacheNode(childInst, childNode); continue outer; } @@ -4587,7 +4445,50 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 37 */ +/* 35 */ +/***/ function(module, exports) { + + /** + * Copyright (c) 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * + */ + 'use strict'; + + /** + * WARNING: DO NOT manually require this module. + * This is a replacement for `invariant(...)` used by the error code system + * and will _only_ be required by the corresponding babel pass. + * It always throws. + */ + + function reactProdInvariant(code) { + var argCount = arguments.length - 1; + + var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; + + for (var argIdx = 0; argIdx < argCount; argIdx++) { + message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); + } + + message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; + + var error = new Error(message); + error.name = 'Invariant Violation'; + error.framesToPop = 1; // we don't care about reactProdInvariant's own frame + + throw error; + } + + module.exports = reactProdInvariant; + +/***/ }, +/* 36 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** @@ -4598,12 +4499,11 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule DOMProperty */ 'use strict'; - var _prodInvariant = __webpack_require__(7); + var _prodInvariant = __webpack_require__(35); var invariant = __webpack_require__(8); @@ -4769,9 +4669,13 @@ /** * Mapping from lowercase property names to the properly cased version, used * to warn in the case of missing properties. Available only in __DEV__. + * + * autofocus is predefined, because adding it to the property whitelist + * causes unintended side effects. + * * @type {Object} */ - getPossibleStandardName: process.env.NODE_ENV !== 'production' ? {} : null, + getPossibleStandardName: process.env.NODE_ENV !== 'production' ? { autofocus: 'autoFocus' } : null, /** * All of the isCustomAttribute() functions that have been injected. @@ -4799,7 +4703,7 @@ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) /***/ }, -/* 38 */ +/* 37 */ /***/ function(module, exports) { /** @@ -4810,7 +4714,6 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactDOMComponentFlags */ 'use strict'; @@ -4822,7 +4725,7 @@ module.exports = ReactDOMComponentFlags; /***/ }, -/* 39 */ +/* 38 */ /***/ function(module, exports, __webpack_require__) { /** @@ -4833,29 +4736,29 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactDefaultInjection */ 'use strict'; + var ARIADOMPropertyConfig = __webpack_require__(39); var BeforeInputEventPlugin = __webpack_require__(40); var ChangeEventPlugin = __webpack_require__(55); - var DefaultEventPluginOrder = __webpack_require__(73); - var EnterLeaveEventPlugin = __webpack_require__(74); - var HTMLDOMPropertyConfig = __webpack_require__(79); - var ReactComponentBrowserEnvironment = __webpack_require__(80); - var ReactDOMComponent = __webpack_require__(94); - var ReactDOMComponentTree = __webpack_require__(36); - var ReactDOMEmptyComponent = __webpack_require__(133); - var ReactDOMTreeTraversal = __webpack_require__(134); - var ReactDOMTextComponent = __webpack_require__(135); - var ReactDefaultBatchingStrategy = __webpack_require__(136); - var ReactEventListener = __webpack_require__(137); - var ReactInjection = __webpack_require__(140); - var ReactReconcileTransaction = __webpack_require__(141); - var SVGDOMPropertyConfig = __webpack_require__(149); - var SelectEventPlugin = __webpack_require__(150); - var SimpleEventPlugin = __webpack_require__(151); + var DefaultEventPluginOrder = __webpack_require__(72); + var EnterLeaveEventPlugin = __webpack_require__(73); + var HTMLDOMPropertyConfig = __webpack_require__(78); + var ReactComponentBrowserEnvironment = __webpack_require__(79); + var ReactDOMComponent = __webpack_require__(92); + var ReactDOMComponentTree = __webpack_require__(34); + var ReactDOMEmptyComponent = __webpack_require__(137); + var ReactDOMTreeTraversal = __webpack_require__(138); + var ReactDOMTextComponent = __webpack_require__(139); + var ReactDefaultBatchingStrategy = __webpack_require__(140); + var ReactEventListener = __webpack_require__(141); + var ReactInjection = __webpack_require__(144); + var ReactReconcileTransaction = __webpack_require__(145); + var SVGDOMPropertyConfig = __webpack_require__(153); + var SelectEventPlugin = __webpack_require__(154); + var SimpleEventPlugin = __webpack_require__(155); var alreadyInjected = false; @@ -4893,6 +4796,7 @@ ReactInjection.HostComponent.injectTextComponentClass(ReactDOMTextComponent); + ReactInjection.DOMProperty.injectDOMPropertyConfig(ARIADOMPropertyConfig); ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); @@ -4911,6 +4815,84 @@ }; /***/ }, +/* 39 */ +/***/ function(module, exports) { + + /** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + + 'use strict'; + + var ARIADOMPropertyConfig = { + Properties: { + // Global States and Properties + 'aria-current': 0, // state + 'aria-details': 0, + 'aria-disabled': 0, // state + 'aria-hidden': 0, // state + 'aria-invalid': 0, // state + 'aria-keyshortcuts': 0, + 'aria-label': 0, + 'aria-roledescription': 0, + // Widget Attributes + 'aria-autocomplete': 0, + 'aria-checked': 0, + 'aria-expanded': 0, + 'aria-haspopup': 0, + 'aria-level': 0, + 'aria-modal': 0, + 'aria-multiline': 0, + 'aria-multiselectable': 0, + 'aria-orientation': 0, + 'aria-placeholder': 0, + 'aria-pressed': 0, + 'aria-readonly': 0, + 'aria-required': 0, + 'aria-selected': 0, + 'aria-sort': 0, + 'aria-valuemax': 0, + 'aria-valuemin': 0, + 'aria-valuenow': 0, + 'aria-valuetext': 0, + // Live Region Attributes + 'aria-atomic': 0, + 'aria-busy': 0, + 'aria-live': 0, + 'aria-relevant': 0, + // Drag-and-Drop Attributes + 'aria-dropeffect': 0, + 'aria-grabbed': 0, + // Relationship Attributes + 'aria-activedescendant': 0, + 'aria-colcount': 0, + 'aria-colindex': 0, + 'aria-colspan': 0, + 'aria-controls': 0, + 'aria-describedby': 0, + 'aria-errormessage': 0, + 'aria-flowto': 0, + 'aria-labelledby': 0, + 'aria-owns': 0, + 'aria-posinset': 0, + 'aria-rowcount': 0, + 'aria-rowindex': 0, + 'aria-rowspan': 0, + 'aria-setsize': 0 + }, + DOMAttributeNames: {}, + DOMPropertyNames: {} + }; + + module.exports = ARIADOMPropertyConfig; + +/***/ }, /* 40 */ /***/ function(module, exports, __webpack_require__) { @@ -4922,20 +4904,16 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule BeforeInputEventPlugin */ 'use strict'; - var EventConstants = __webpack_require__(41); - var EventPropagators = __webpack_require__(42); - va…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need to be revised. @trueadm will likely pick this up.
Superseded by #9147. |
This implements #6351 using Rollup. It could be used to replace our Browserify build step (i.e., it takes pre-built files from
./build/modules
) and it's pretty similar to #4230.Firstly I moved all our non-top-level requires to the top level and
__DEV__
on their usage (we only have 5 files that have that). Since we no longer have dynamic parts in our require/exports, they are pretty much ES6-compliant. Then there's a Babel pass for Rollup to firstly rewrite all require/exports to ES6 import/exports, and finally it bundles to a flat file (in UMD format). It sounds weird to transpile files from ES5 to ES6 but using this babel pass results in smaller file sizes comparing with using Rollup's CommonJS plugin.This decreases our gzipped minified (prod) file size by ~10% and some of the benchmarks look pretty good.
cc @facebook/react-core
Size Comparison
Benchmarks
TODO: