diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js index 37f507c2e..dea05fa95 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js +++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js @@ -25,11 +25,11 @@ require('regenerator/runtime'); if (typeof GLOBAL === 'undefined') { - GLOBAL = this; + global.GLOBAL = this; } if (typeof window === 'undefined') { - window = GLOBAL; + global.window = GLOBAL; } function setUpConsole() { @@ -70,6 +70,15 @@ function polyfillGlobal(name, newValue, scope = GLOBAL) { Object.defineProperty(scope, name, {...descriptor, value: newValue}); } +/** + * Polyfill a module if it is not already defined in `scope`. + */ +function polyfillIfNeeded(name, polyfill, scope = GLOBAL, descriptor = {}) { + if (scope[name] === undefined) { + Object.defineProperty(scope, name, {...descriptor, value: polyfill}); + } +} + function setUpErrorHandler() { if (global.__fbDisableExceptionsManager) { return; @@ -78,7 +87,7 @@ function setUpErrorHandler() { function handleError(e, isFatal) { try { require('ExceptionsManager').handleException(e, isFatal); - } catch(ee) { + } catch (ee) { console.log('Failed to print error: ', ee.message); } } @@ -146,7 +155,11 @@ function setUpXHR() { } function setUpGeolocation() { - GLOBAL.navigator = GLOBAL.navigator || {}; + polyfillIfNeeded('navigator', {}, GLOBAL, { + writable: true, + enumerable: true, + configurable: true, + }); polyfillGlobal('geolocation', require('Geolocation'), GLOBAL.navigator); } @@ -179,9 +192,9 @@ function setUpProcessEnv() { } function setUpNumber() { - Number.EPSILON = Number.EPSILON || Math.pow(2, -52); - Number.MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1; - Number.MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1); + polyfillIfNeeded('EPSILON', Math.pow(2, -52), Number); + polyfillIfNeeded('MAX_SAFE_INTEGER', Math.pow(2, 53) - 1, Number); + polyfillIfNeeded('MIN_SAFE_INTEGER', -(Math.pow(2, 53) - 1), Number); } function setUpDevTools() { diff --git a/Libraries/JavaScriptAppEngine/polyfills/document.js b/Libraries/JavaScriptAppEngine/polyfills/document.js index 4e76db957..bff669cce 100644 --- a/Libraries/JavaScriptAppEngine/polyfills/document.js +++ b/Libraries/JavaScriptAppEngine/polyfills/document.js @@ -1,34 +1,30 @@ -/* eslint global-strict: 0 */ -(function(GLOBAL) { - /** - * The document must be shimmed before anything else that might define the - * `ExecutionEnvironment` module (which checks for `document.createElement`). - */ +/* eslint strict: 0 */ - // The browser defines Text and Image globals by default. If you forget to - // require them, then the error message is very confusing. - function getInvalidGlobalUseError(name) { - return new Error( - 'You are trying to render the global ' + name + ' variable as a ' + - 'React element. You probably forgot to require ' + name + '.' - ); - } - GLOBAL.Text = { - get defaultProps() { - throw getInvalidGlobalUseError('Text'); - } - }; - GLOBAL.Image = { - get defaultProps() { - throw getInvalidGlobalUseError('Image'); - } - }; - // Force `ExecutionEnvironment.canUseDOM` to be false. - if (GLOBAL.document) { - GLOBAL.document.createElement = null; - } +// TODO: Remove document polyfill now that chrome debugging is in a web worker. - // There is no DOM so MutationObserver doesn't make sense. It is used - // as feature detection in Bluebird Promise implementation - GLOBAL.MutationObserver = undefined; -})(this); +// The browser defines Text and Image globals by default. If you forget to +// require them, then the error message is very confusing. +function getInvalidGlobalUseError(name) { + return new Error( + 'You are trying to render the global ' + name + ' variable as a ' + + 'React element. You probably forgot to require ' + name + '.' + ); +} +global.Text = { + get defaultProps() { + throw getInvalidGlobalUseError('Text'); + } +}; +global.Image = { + get defaultProps() { + throw getInvalidGlobalUseError('Image'); + } +}; +// Force `ExecutionEnvironment.canUseDOM` to be false. +if (global.document) { + global.document.createElement = null; +} + +// There is no DOM so MutationObserver doesn't make sense. It is used +// as feature detection in Bluebird Promise implementation +global.MutationObserver = undefined; diff --git a/Libraries/vendor/emitter/mixInEventEmitter.js b/Libraries/vendor/emitter/mixInEventEmitter.js index cc62d04d4..4dc938199 100644 --- a/Libraries/vendor/emitter/mixInEventEmitter.js +++ b/Libraries/vendor/emitter/mixInEventEmitter.js @@ -49,12 +49,13 @@ var TYPES_KEY = keyOf({__types: true}); */ function mixInEventEmitter(klass, types) { invariant(types, 'Must supply set of valid event types'); - invariant(!this.__eventEmitter, 'An active emitter is already mixed in'); // If this is a constructor, write to the prototype, otherwise write to the // singleton object. var target = klass.prototype || klass; + invariant(!target.__eventEmitter, 'An active emitter is already mixed in'); + var ctor = klass.constructor; if (ctor) { invariant( diff --git a/packager/react-packager/src/Resolver/__tests__/Resolver-test.js b/packager/react-packager/src/Resolver/__tests__/Resolver-test.js index 82184c61b..825399b4a 100644 --- a/packager/react-packager/src/Resolver/__tests__/Resolver-test.js +++ b/packager/react-packager/src/Resolver/__tests__/Resolver-test.js @@ -58,6 +58,14 @@ describe('Resolver', function() { return module; } + function createPolyfill(id, dependencies) { + var polyfill = new Polyfill({}); + polyfill.getName.mockImpl(() => Promise.resolve(id)); + polyfill.getDependencies.mockImpl(() => Promise.resolve(dependencies)); + polyfill.isPolyfill.mockReturnValue(true); + return polyfill; + } + describe('getDependencies', function() { pit('should get dependencies with polyfills', function() { var module = createModule('index'); @@ -1020,5 +1028,26 @@ describe('Resolver', function() { ].join('\n')); }); }); + + pit('should resolve polyfills', function () { + const depResolver = new Resolver({ + projectRoot: '/root', + }); + const polyfill = createPolyfill('test polyfill', []); + const code = [ + 'global.fetch = () => 1;', + ].join(''); + return depResolver.wrapModule( + null, + polyfill, + code + ).then(processedCode => { + expect(processedCode.code).toEqual([ + '(function(global) {', + 'global.fetch = () => 1;', + "\n})(typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this);", + ].join('')); + }); + }); }); }); diff --git a/packager/react-packager/src/Resolver/index.js b/packager/react-packager/src/Resolver/index.js index cf021e16f..0166681f0 100644 --- a/packager/react-packager/src/Resolver/index.js +++ b/packager/react-packager/src/Resolver/index.js @@ -214,7 +214,9 @@ class Resolver { wrapModule(resolutionResponse, module, code) { if (module.isPolyfill()) { - return Promise.resolve({code}); + return Promise.resolve({ + code: definePolyfillCode(code), + }); } return this.resolveRequires(resolutionResponse, module, code).then( @@ -239,4 +241,12 @@ function defineModuleCode(moduleName, code) { ].join(''); } +function definePolyfillCode(code) { + return [ + '(function(global) {', + code, + `\n})(typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this);`, + ].join(''); +} + module.exports = Resolver; diff --git a/packager/react-packager/src/Resolver/polyfills/Array.prototype.es6.js b/packager/react-packager/src/Resolver/polyfills/Array.prototype.es6.js index 80e62f05d..2752aab5e 100644 --- a/packager/react-packager/src/Resolver/polyfills/Array.prototype.es6.js +++ b/packager/react-packager/src/Resolver/polyfills/Array.prototype.es6.js @@ -5,54 +5,51 @@ * @polyfill */ -/*eslint-disable */ -/*jslint bitwise: true */ +/* eslint-disable */ -(function(undefined) { - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex - function findIndex(predicate, context) { - if (this == null) { - throw new TypeError( - 'Array.prototype.findIndex called on null or undefined' - ); +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex +function findIndex(predicate, context) { + if (this == null) { + throw new TypeError( + 'Array.prototype.findIndex called on null or undefined' + ); + } + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + var list = Object(this); + var length = list.length >>> 0; + for (var i = 0; i < length; i++) { + if (predicate.call(context, list[i], i, list)) { + return i; } - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - var list = Object(this); - var length = list.length >>> 0; - for (var i = 0; i < length; i++) { - if (predicate.call(context, list[i], i, list)) { - return i; + } + return -1; +} + +if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + enumerable: false, + writable: true, + configurable: true, + value: findIndex + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + enumerable: false, + writable: true, + configurable: true, + value: function(predicate, context) { + if (this == null) { + throw new TypeError( + 'Array.prototype.find called on null or undefined' + ); } + var index = findIndex.call(this, predicate, context); + return index === -1 ? undefined : this[index]; } - return -1; - } - - if (!Array.prototype.findIndex) { - Object.defineProperty(Array.prototype, 'findIndex', { - enumerable: false, - writable: true, - configurable: true, - value: findIndex - }); - } - - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find - if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - enumerable: false, - writable: true, - configurable: true, - value: function(predicate, context) { - if (this == null) { - throw new TypeError( - 'Array.prototype.find called on null or undefined' - ); - } - var index = findIndex.call(this, predicate, context); - return index === -1 ? undefined : this[index]; - } - }); - } -})(); + }); +} diff --git a/packager/react-packager/src/Resolver/polyfills/babelHelpers.js b/packager/react-packager/src/Resolver/polyfills/babelHelpers.js index de54ebc2c..ff4422574 100644 --- a/packager/react-packager/src/Resolver/polyfills/babelHelpers.js +++ b/packager/react-packager/src/Resolver/polyfills/babelHelpers.js @@ -7,8 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -/* global self:true */ -/* eslint-disable strict */ +/* eslint-disable */ // Created by running: // require('babel-core').buildExternalHelpers('_extends classCallCheck createClass createRawReactElement defineProperty get inherits interopRequireDefault interopRequireWildcard objectWithoutProperties possibleConstructorReturn slicedToArray taggedTemplateLiteral toArray toConsumableArray '.split(' ')) @@ -16,217 +15,215 @@ // // actually, that's a lie, because babel6 omits _extends and createRawReactElement -(function (global) { - var babelHelpers = global.babelHelpers = {}; +var babelHelpers = global.babelHelpers = {}; - babelHelpers.createRawReactElement = (function () { - var REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7; - return function createRawReactElement(type, key, props) { - return { - $$typeof: REACT_ELEMENT_TYPE, - type: type, - key: key, - ref: null, - props: props, - _owner: null - }; +babelHelpers.createRawReactElement = (function () { + var REACT_ELEMENT_TYPE = typeof Symbol === "function" && Symbol.for && Symbol.for("react.element") || 0xeac7; + return function createRawReactElement(type, key, props) { + return { + $$typeof: REACT_ELEMENT_TYPE, + type: type, + key: key, + ref: null, + props: props, + _owner: null }; - })(); - - babelHelpers.classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } }; +})(); - babelHelpers.createClass = (function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } +babelHelpers.classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +babelHelpers.createClass = (function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); } + } - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - })(); - - babelHelpers.defineProperty = function (obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; }; +})(); - babelHelpers._extends = babelHelpers.extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; - }; - - babelHelpers.get = function get(object, property, receiver) { - if (object === null) object = Function.prototype; - var desc = Object.getOwnPropertyDescriptor(object, property); - - if (desc === undefined) { - var parent = Object.getPrototypeOf(object); - - if (parent === null) { - return undefined; - } else { - return get(parent, property, receiver); - } - } else if ("value" in desc) { - return desc.value; - } else { - var getter = desc.get; - - if (getter === undefined) { - return undefined; - } - - return getter.call(receiver); - } - }; - - babelHelpers.inherits = function (subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - enumerable: false, - writable: true, - configurable: true - } +babelHelpers.defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true }); - if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; - }; + } else { + obj[key] = value; + } - babelHelpers.interopRequireDefault = function (obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; - }; + return obj; +}; - babelHelpers.interopRequireWildcard = function (obj) { - if (obj && obj.__esModule) { - return obj; - } else { - var newObj = {}; +babelHelpers._extends = babelHelpers.extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; - if (obj != null) { - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; - } + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; } - - newObj.default = obj; - return newObj; } - }; + } - babelHelpers.objectWithoutProperties = function (obj, keys) { - var target = {}; + return target; +}; - for (var i in obj) { - if (keys.indexOf(i) >= 0) continue; - if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; - target[i] = obj[i]; +babelHelpers.get = function get(object, property, receiver) { + if (object === null) object = Function.prototype; + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === undefined) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return undefined; + } else { + return get(parent, property, receiver); + } + } else if ("value" in desc) { + return desc.value; + } else { + var getter = desc.get; + + if (getter === undefined) { + return undefined; } - return target; - }; + return getter.call(receiver); + } +}; - babelHelpers.possibleConstructorReturn = function (self, call) { - if (!self) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); +babelHelpers.inherits = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; +}; + +babelHelpers.interopRequireDefault = function (obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; +}; + +babelHelpers.interopRequireWildcard = function (obj) { + if (obj && obj.__esModule) { + return obj; + } else { + var newObj = {}; + + if (obj != null) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; + } } - return call && (typeof call === "object" || typeof call === "function") ? call : self; - }; + newObj.default = obj; + return newObj; + } +}; - babelHelpers.slicedToArray = (function () { - function sliceIterator(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; +babelHelpers.objectWithoutProperties = function (obj, keys) { + var target = {}; + for (var i in obj) { + if (keys.indexOf(i) >= 0) continue; + if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; + target[i] = obj[i]; + } + + return target; +}; + +babelHelpers.possibleConstructorReturn = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; +}; + +babelHelpers.slicedToArray = (function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; + if (!_n && _i["return"]) _i["return"](); } finally { - try { - if (!_n && _i["return"]) _i["return"](); - } finally { - if (_d) throw _e; - } + if (_d) throw _e; } - - return _arr; } - return function (arr, i) { - if (Array.isArray(arr)) { - return arr; - } else if (Symbol.iterator in Object(arr)) { - return sliceIterator(arr, i); - } else { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); - } - }; - })(); - - babelHelpers.taggedTemplateLiteral = function (strings, raw) { - return Object.freeze(Object.defineProperties(strings, { - raw: { - value: Object.freeze(raw) - } - })); - }; + return _arr; + } - babelHelpers.toArray = function (arr) { - return Array.isArray(arr) ? arr : Array.from(arr); - }; - - babelHelpers.toConsumableArray = function (arr) { + return function (arr, i) { if (Array.isArray(arr)) { - for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); } else { - return Array.from(arr); + throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; -})(typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : this); +})(); + +babelHelpers.taggedTemplateLiteral = function (strings, raw) { + return Object.freeze(Object.defineProperties(strings, { + raw: { + value: Object.freeze(raw) + } + })); +}; + +babelHelpers.toArray = function (arr) { + return Array.isArray(arr) ? arr : Array.from(arr); +}; + +babelHelpers.toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; diff --git a/packager/react-packager/src/Resolver/polyfills/console.js b/packager/react-packager/src/Resolver/polyfills/console.js index a8e5a72f4..5406db73e 100644 --- a/packager/react-packager/src/Resolver/polyfills/console.js +++ b/packager/react-packager/src/Resolver/polyfills/console.js @@ -14,495 +14,492 @@ * @nolint */ -(function(global) { - 'use strict'; +/* eslint-disable */ - var inspect = (function() { - // Copyright Joyent, Inc. and other Node contributors. - // - // Permission is hereby granted, free of charge, to any person obtaining a - // copy of this software and associated documentation files (the - // "Software"), to deal in the Software without restriction, including - // without limitation the rights to use, copy, modify, merge, publish, - // distribute, sublicense, and/or sell copies of the Software, and to permit - // persons to whom the Software is furnished to do so, subject to the - // following conditions: - // - // The above copyright notice and this permission notice shall be included - // in all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - // USE OR OTHER DEALINGS IN THE SOFTWARE. - // - // https://github.com/joyent/node/blob/master/lib/util.js +var inspect = (function() { + // Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + // + // https://github.com/joyent/node/blob/master/lib/util.js - function inspect(obj, opts) { - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - return formatValue(ctx, obj, opts.depth); + function inspect(obj, opts) { + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + return formatValue(ctx, obj, opts.depth); + } + + function stylizeNoColor(str, styleType) { + return str; + } + + function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; + } + + + function formatValue(ctx, value, recurseTimes) { + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; } - function stylizeNoColor(str, styleType) { - return str; + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); } - function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; - } - - - function formatValue(ctx, value, recurseTimes) { - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { return formatError(value); } + } - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } + var base = '', array = false, braces = ['{', '}']; - var base = '', array = false, braces = ['{', '}']; + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } - // Make RegExps say that they are RegExps + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); + return ctx.stylize('[Object]', 'special'); } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); } + ctx.seen.push(value); - function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); - } - - - function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; - } - - - function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); - return output; } + ctx.seen.pop(); - function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); + return reduceToSingleString(output, base, braces); + } + + + function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); + } + + + function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; + } + + + function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; + } + + + function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); } else { - str = ctx.stylize('[Getter]', 'special'); + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } } } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } + str = ctx.stylize('[Circular]', 'special'); } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } + } + + return name + ': ' + str; + } + + + function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { + return Array.isArray(ar); + } + + function isBoolean(arg) { + return typeof arg === 'boolean'; + } + + function isNull(arg) { + return arg === null; + } + + function isNullOrUndefined(arg) { + return arg == null; + } + + function isNumber(arg) { + return typeof arg === 'number'; + } + + function isString(arg) { + return typeof arg === 'string'; + } + + function isSymbol(arg) { + return typeof arg === 'symbol'; + } + + function isUndefined(arg) { + return arg === void 0; + } + + function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; + } + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + + function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; + } + + function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); + } + + function isFunction(arg) { + return typeof arg === 'function'; + } + + function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; + } + + function objectToString(o) { + return Object.prototype.toString.call(o); + } + + function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + return inspect; +})(); + + +var OBJECT_COLUMN_NAME = '(index)'; +var LOG_LEVELS = { + trace: 0, + info: 1, + warn: 2, + error: 3 +}; + +function setupConsole(global) { + if (!global.nativeLoggingHook) { + return; + } + + function getNativeLogFunction(level) { + return function() { + var str; + if (arguments.length === 1 && typeof arguments[0] === 'string') { + str = arguments[0]; + } else { + str = Array.prototype.map.call(arguments, function(arg) { + return inspect(arg, {depth: 10}); + }).join(', '); } - return name + ': ' + str; - } - - - function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; + var logLevel = level; + if (str.slice(0, 9) === 'Warning: ' && logLevel >= LOG_LEVELS.error) { + // React warnings use console.error so that a stack trace is shown, + // but we don't (currently) want these to show a redbox + // (Note: Logic duplicated in ExceptionsManager.js.) + logLevel = LOG_LEVELS.warn; } + global.nativeLoggingHook(str, logLevel); + }; + } - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; - } - - - // NOTE: These type checking functions intentionally don't use `instanceof` - // because it is fragile and can be easily faked with `Object.create()`. - function isArray(ar) { - return Array.isArray(ar); - } - - function isBoolean(arg) { - return typeof arg === 'boolean'; - } - - function isNull(arg) { - return arg === null; - } - - function isNullOrUndefined(arg) { - return arg == null; - } - - function isNumber(arg) { - return typeof arg === 'number'; - } - - function isString(arg) { - return typeof arg === 'string'; - } - - function isSymbol(arg) { - return typeof arg === 'symbol'; - } - - function isUndefined(arg) { - return arg === void 0; - } - - function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; - } - - function isObject(arg) { - return typeof arg === 'object' && arg !== null; - } - - function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; - } - - function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); - } - - function isFunction(arg) { - return typeof arg === 'function'; - } - - function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; - } - - function objectToString(o) { - return Object.prototype.toString.call(o); - } - - function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); - } - - return inspect; - })(); - - - var OBJECT_COLUMN_NAME = '(index)'; - var LOG_LEVELS = { - trace: 0, - info: 1, - warn: 2, - error: 3 + var repeat = function(element, n) { + return Array.apply(null, Array(n)).map(function() { return element; }); }; - function setupConsole(global) { - if (!global.nativeLoggingHook) { + function consoleTablePolyfill(rows) { + // convert object -> array + if (!Array.isArray(rows)) { + var data = rows; + rows = []; + for (var key in data) { + if (data.hasOwnProperty(key)) { + var row = data[key]; + row[OBJECT_COLUMN_NAME] = key; + rows.push(row); + } + } + } + if (rows.length === 0) { + global.nativeLoggingHook('', LOG_LEVELS.info); return; } - function getNativeLogFunction(level) { - return function() { - var str; - if (arguments.length === 1 && typeof arguments[0] === 'string') { - str = arguments[0]; - } else { - str = Array.prototype.map.call(arguments, function(arg) { - return inspect(arg, {depth: 10}); - }).join(', '); - } + var columns = Object.keys(rows[0]).sort(); + var stringRows = []; + var columnWidths = []; - var logLevel = level; - if (str.slice(0, 9) === 'Warning: ' && logLevel >= LOG_LEVELS.error) { - // React warnings use console.error so that a stack trace is shown, - // but we don't (currently) want these to show a redbox - // (Note: Logic duplicated in ExceptionsManager.js.) - logLevel = LOG_LEVELS.warn; - } - global.nativeLoggingHook(str, logLevel); - }; - } - - var repeat = function(element, n) { - return Array.apply(null, Array(n)).map(function() { return element; }); - }; - - function consoleTablePolyfill(rows) { - // convert object -> array - if (!Array.isArray(rows)) { - var data = rows; - rows = []; - for (var key in data) { - if (data.hasOwnProperty(key)) { - var row = data[key]; - row[OBJECT_COLUMN_NAME] = key; - rows.push(row); - } - } + // Convert each cell to a string. Also + // figure out max cell width for each column + columns.forEach(function(k, i) { + columnWidths[i] = k.length; + for (var j = 0; j < rows.length; j++) { + var cellStr = rows[j][k].toString(); + stringRows[j] = stringRows[j] || []; + stringRows[j][i] = cellStr; + columnWidths[i] = Math.max(columnWidths[i], cellStr.length); } - if (rows.length === 0) { - global.nativeLoggingHook('', LOG_LEVELS.info); - return; - } - - var columns = Object.keys(rows[0]).sort(); - var stringRows = []; - var columnWidths = []; - - // Convert each cell to a string. Also - // figure out max cell width for each column - columns.forEach(function(k, i) { - columnWidths[i] = k.length; - for (var j = 0; j < rows.length; j++) { - var cellStr = rows[j][k].toString(); - stringRows[j] = stringRows[j] || []; - stringRows[j][i] = cellStr; - columnWidths[i] = Math.max(columnWidths[i], cellStr.length); - } - }); - - // Join all elements in the row into a single string with | separators - // (appends extra spaces to each cell to make separators | alligned) - var joinRow = function(row, space) { - var cells = row.map(function(cell, i) { - var extraSpaces = repeat(' ', columnWidths[i] - cell.length).join(''); - return cell + extraSpaces; - }); - space = space || ' '; - return cells.join(space + '|' + space); - }; - - var separators = columnWidths.map(function(columnWidth) { - return repeat('-', columnWidth).join(''); - }); - var separatorRow = joinRow(separators, '-'); - var header = joinRow(columns); - var table = [header, separatorRow]; - - for (var i = 0; i < rows.length; i++) { - table.push(joinRow(stringRows[i])); - } - - // Notice extra empty line at the beginning. - // Native logging hook adds "RCTLog >" at the front of every - // logged string, which would shift the header and screw up - // the table - global.nativeLoggingHook('\n' + table.join('\n'), LOG_LEVELS.info); - } - - // Preserve the original `console` as `originalConsole` - var originalConsole = global.console; - var descriptor = Object.getOwnPropertyDescriptor(global, 'console'); - if (descriptor) { - Object.defineProperty(global, 'originalConsole', descriptor); - } - - var console = { - error: getNativeLogFunction(LOG_LEVELS.error), - info: getNativeLogFunction(LOG_LEVELS.info), - log: getNativeLogFunction(LOG_LEVELS.info), - warn: getNativeLogFunction(LOG_LEVELS.warn), - trace: getNativeLogFunction(LOG_LEVELS.trace), - table: consoleTablePolyfill - }; - - // don't reassign to the original descriptor. breaks on ios7 - Object.defineProperty(global, 'console', { - value: console, - configurable: descriptor ? descriptor.configurable : true, - enumerable: descriptor ? descriptor.enumerable : true, - writable: descriptor ? descriptor.writable : true, }); - // If available, also call the original `console` method since that is - // sometimes useful. Ex: on OS X, this will let you see rich output in - // the Safari Web Inspector console. - if (__DEV__ && originalConsole) { - Object.keys(console).forEach(methodName => { - var reactNativeMethod = console[methodName]; - if (originalConsole[methodName]) { - console[methodName] = function() { - originalConsole[methodName](...arguments); - reactNativeMethod.apply(console, arguments); - }; - } + // Join all elements in the row into a single string with | separators + // (appends extra spaces to each cell to make separators | alligned) + var joinRow = function(row, space) { + var cells = row.map(function(cell, i) { + var extraSpaces = repeat(' ', columnWidths[i] - cell.length).join(''); + return cell + extraSpaces; }); + space = space || ' '; + return cells.join(space + '|' + space); + }; + + var separators = columnWidths.map(function(columnWidth) { + return repeat('-', columnWidth).join(''); + }); + var separatorRow = joinRow(separators, '-'); + var header = joinRow(columns); + var table = [header, separatorRow]; + + for (var i = 0; i < rows.length; i++) { + table.push(joinRow(stringRows[i])); } + + // Notice extra empty line at the beginning. + // Native logging hook adds "RCTLog >" at the front of every + // logged string, which would shift the header and screw up + // the table + global.nativeLoggingHook('\n' + table.join('\n'), LOG_LEVELS.info); } - if (typeof module !== 'undefined') { - module.exports = setupConsole; - } else { - setupConsole(global); + // Preserve the original `console` as `originalConsole` + var originalConsole = global.console; + var descriptor = Object.getOwnPropertyDescriptor(global, 'console'); + if (descriptor) { + Object.defineProperty(global, 'originalConsole', descriptor); } -})(this); + var console = { + error: getNativeLogFunction(LOG_LEVELS.error), + info: getNativeLogFunction(LOG_LEVELS.info), + log: getNativeLogFunction(LOG_LEVELS.info), + warn: getNativeLogFunction(LOG_LEVELS.warn), + trace: getNativeLogFunction(LOG_LEVELS.trace), + table: consoleTablePolyfill + }; + + // don't reassign to the original descriptor. breaks on ios7 + Object.defineProperty(global, 'console', { + value: console, + configurable: descriptor ? descriptor.configurable : true, + enumerable: descriptor ? descriptor.enumerable : true, + writable: descriptor ? descriptor.writable : true, + }); + + // If available, also call the original `console` method since that is + // sometimes useful. Ex: on OS X, this will let you see rich output in + // the Safari Web Inspector console. + if (__DEV__ && originalConsole) { + Object.keys(console).forEach(methodName => { + var reactNativeMethod = console[methodName]; + if (originalConsole[methodName]) { + console[methodName] = function() { + originalConsole[methodName](...arguments); + reactNativeMethod.apply(console, arguments); + }; + } + }); + } +} + +if (typeof module !== 'undefined') { + module.exports = setupConsole; +} else { + setupConsole(global); +} diff --git a/packager/react-packager/src/Resolver/polyfills/error-guard.js b/packager/react-packager/src/Resolver/polyfills/error-guard.js index ac99cadca..8810a4b12 100644 --- a/packager/react-packager/src/Resolver/polyfills/error-guard.js +++ b/packager/react-packager/src/Resolver/polyfills/error-guard.js @@ -13,74 +13,72 @@ * before any of the modules, this ErrorUtils must be defined (and the handler * set) globally before requiring anything. */ -/* eslint global-strict:0 */ -(function(global) { - var ErrorUtils = { - _inGuard: 0, - _globalHandler: null, - setGlobalHandler: function(fun) { - ErrorUtils._globalHandler = fun; - }, - reportError: function(error) { - ErrorUtils._globalHandler && ErrorUtils._globalHandler(error); - }, - reportFatalError: function(error) { - ErrorUtils._globalHandler && ErrorUtils._globalHandler(error, true); - }, - applyWithGuard: function(fun, context, args) { - try { - ErrorUtils._inGuard++; - return fun.apply(context, args); - } catch (e) { - ErrorUtils.reportError(e); - } finally { - ErrorUtils._inGuard--; - } - }, - applyWithGuardIfNeeded: function(fun, context, args) { - if (ErrorUtils.inGuard()) { - return fun.apply(context, args); - } else { - ErrorUtils.applyWithGuard(fun, context, args); - } - }, - inGuard: function() { - return ErrorUtils._inGuard; - }, - guard: function(fun, name, context) { - if (typeof fun !== 'function') { - console.warn('A function must be passed to ErrorUtils.guard, got ', fun); - return null; - } - name = name || fun.name || ''; - function guarded() { - return ( - ErrorUtils.applyWithGuard( - fun, - context || this, - arguments, - null, - name - ) - ); - } - - return guarded; +/* eslint strict:0 */ +var ErrorUtils = { + _inGuard: 0, + _globalHandler: null, + setGlobalHandler: function(fun) { + ErrorUtils._globalHandler = fun; + }, + reportError: function(error) { + ErrorUtils._globalHandler && ErrorUtils._globalHandler(error); + }, + reportFatalError: function(error) { + ErrorUtils._globalHandler && ErrorUtils._globalHandler(error, true); + }, + applyWithGuard: function(fun, context, args) { + try { + ErrorUtils._inGuard++; + return fun.apply(context, args); + } catch (e) { + ErrorUtils.reportError(e); + } finally { + ErrorUtils._inGuard--; + } + }, + applyWithGuardIfNeeded: function(fun, context, args) { + if (ErrorUtils.inGuard()) { + return fun.apply(context, args); + } else { + ErrorUtils.applyWithGuard(fun, context, args); + } + }, + inGuard: function() { + return ErrorUtils._inGuard; + }, + guard: function(fun, name, context) { + if (typeof fun !== 'function') { + console.warn('A function must be passed to ErrorUtils.guard, got ', fun); + return null; + } + name = name || fun.name || ''; + function guarded() { + return ( + ErrorUtils.applyWithGuard( + fun, + context || this, + arguments, + null, + name + ) + ); } - }; - global.ErrorUtils = ErrorUtils; - /** - * This is the error handler that is called when we encounter an exception - * when loading a module. This will report any errors encountered before - * ExceptionsManager is configured. - */ - function setupErrorGuard() { - var onError = function(e) { - global.console.error('Error: ' + e.message + ', stack:\n' + e.stack); - }; - global.ErrorUtils.setGlobalHandler(onError); + return guarded; } +}; +global.ErrorUtils = ErrorUtils; - setupErrorGuard(); -})(this); +/** + * This is the error handler that is called when we encounter an exception + * when loading a module. This will report any errors encountered before + * ExceptionsManager is configured. + */ +function setupErrorGuard() { + var onError = function(e) { + global.console.error('Error: ' + e.message + ', stack:\n' + e.stack); + }; + global.ErrorUtils.setGlobalHandler(onError); +} + +setupErrorGuard(); diff --git a/packager/react-packager/src/Resolver/polyfills/loadBundles.js b/packager/react-packager/src/Resolver/polyfills/loadBundles.js index 4e893eda9..7bb9be104 100644 --- a/packager/react-packager/src/Resolver/polyfills/loadBundles.js +++ b/packager/react-packager/src/Resolver/polyfills/loadBundles.js @@ -1,50 +1,34 @@ -/* eslint global-strict:0 */ -(global => { - let loadBundlesOnNative = (bundles) => - new Promise((resolve) => - require('NativeModules').RCTBundlesLoader.loadBundles(bundles, resolve)); +/* eslint strict:0 */ - let requestedBundles = Object.create(null); +let loadBundlesOnNative = (bundles) => + new Promise((resolve) => + require('NativeModules').RCTBundlesLoader.loadBundles(bundles, resolve)); - /** - * Returns a promise that is fulfilled once all the indicated bundles are - * loaded into memory and injected into the JS engine. - * This invokation might need to go through the bridge - * and run native code to load some, if not all, the requested bundles. - * If all the bundles have already been loaded, the promise is resolved - * immediately. Otherwise, we'll determine which bundles still need to get - * loaded considering both, the ones already loaded, and the ones being - * currently asynchronously loaded by other invocations to `__loadBundles`, - * and return a promise that will get fulfilled once all these are finally - * loaded. - * - * Note this function should only be invoked by generated code. - */ - global.__loadBundles = function(bundles) { - // split bundles by whether they've already been requested or not - const bundlesToRequest = bundles.filter(b => !requestedBundles[b]); - const bundlesAlreadyRequested = bundles.filter(b => !!requestedBundles[b]); +let requestedBundles = Object.create(null); - // keep a reference to the promise loading each bundle - if (bundlesToRequest.length > 0) { - const nativePromise = loadBundlesOnNative(bundlesToRequest); - bundlesToRequest.forEach(b => requestedBundles[b] = nativePromise); - } +/** + * Returns a promise that is fulfilled once all the indicated bundles are + * loaded into memory and injected into the JS engine. + * This invokation might need to go through the bridge + * and run native code to load some, if not all, the requested bundles. + * If all the bundles have already been loaded, the promise is resolved + * immediately. Otherwise, we'll determine which bundles still need to get + * loaded considering both, the ones already loaded, and the ones being + * currently asynchronously loaded by other invocations to `__loadBundles`, + * and return a promise that will get fulfilled once all these are finally + * loaded. + * + * Note this function should only be invoked by generated code. + */ +global.__loadBundles = function(bundles) { + // split bundles by whether they've already been requested or not + const bundlesToRequest = bundles.filter(b => !requestedBundles[b]); - return Promise.all(bundles.map(bundle => requestedBundles[bundle])); - }; -})(global); + // keep a reference to the promise loading each bundle + if (bundlesToRequest.length > 0) { + const nativePromise = loadBundlesOnNative(bundlesToRequest); + bundlesToRequest.forEach(b => requestedBundles[b] = nativePromise); + } - -// turns a callback async based function into a promised based one -function promisify(fn) { - return function() { - var self = this; - var args = Array.prototype.slice.call(arguments); - - return new Promise((resolve, reject) => { - args.push(resolve); - fn.apply(self, args); - }); - }; -} + return Promise.all(bundles.map(bundle => requestedBundles[bundle])); +}; diff --git a/packager/react-packager/src/Resolver/polyfills/polyfills.js b/packager/react-packager/src/Resolver/polyfills/polyfills.js index 9698b4911..565233421 100644 --- a/packager/react-packager/src/Resolver/polyfills/polyfills.js +++ b/packager/react-packager/src/Resolver/polyfills/polyfills.js @@ -15,7 +15,7 @@ // WARNING: This is an optimized version that fails on hasOwnProperty checks // and non objects. It's not spec-compliant. It's a perf optimization. -/* eslint global-strict:0 */ +/* eslint strict:0 */ Object.assign = function(target, sources) { if (__DEV__) { if (target == null) { diff --git a/packager/react-packager/src/Resolver/polyfills/prelude.js b/packager/react-packager/src/Resolver/polyfills/prelude.js index a1004b7d4..02386ae10 100644 --- a/packager/react-packager/src/Resolver/polyfills/prelude.js +++ b/packager/react-packager/src/Resolver/polyfills/prelude.js @@ -1,5 +1,4 @@ -/* eslint global-strict:0 */ -__DEV__ = false; +/* eslint strict:0 */ +global.__DEV__ = false; -/* global __BUNDLE_START_TIME__:true */ -__BUNDLE_START_TIME__ = Date.now(); +global.__BUNDLE_START_TIME__ = Date.now(); diff --git a/packager/react-packager/src/Resolver/polyfills/prelude_dev.js b/packager/react-packager/src/Resolver/polyfills/prelude_dev.js index 14b97faad..99b9de2c1 100644 --- a/packager/react-packager/src/Resolver/polyfills/prelude_dev.js +++ b/packager/react-packager/src/Resolver/polyfills/prelude_dev.js @@ -1,5 +1,4 @@ -/* eslint global-strict:0 */ -__DEV__ = true; +/* eslint strict:0 */ +global.__DEV__ = true; -/* global __BUNDLE_START_TIME__:true */ -__BUNDLE_START_TIME__ = Date.now(); +global.__BUNDLE_START_TIME__ = Date.now(); diff --git a/packager/react-packager/src/Resolver/polyfills/require-unbundle.js b/packager/react-packager/src/Resolver/polyfills/require-unbundle.js index 1ea71705d..c6c7cbc79 100644 --- a/packager/react-packager/src/Resolver/polyfills/require-unbundle.js +++ b/packager/react-packager/src/Resolver/polyfills/require-unbundle.js @@ -1,73 +1,70 @@ 'use strict'; -((global) => { - const {ErrorUtils, __nativeRequire} = global; - global.require = require; - global.__d = define; +const {ErrorUtils, __nativeRequire} = global; +global.require = require; +global.__d = define; - const modules = Object.create(null); +const modules = Object.create(null); - const loadModule = ErrorUtils ? - guardedLoadModule : loadModuleImplementation; +const loadModule = ErrorUtils ? + guardedLoadModule : loadModuleImplementation; - function define(moduleId, factory) { - modules[moduleId] = { - factory, - hasError: false, - exports: undefined, - }; +function define(moduleId, factory) { + modules[moduleId] = { + factory, + hasError: false, + exports: undefined, + }; +} + +function require(moduleId) { + const module = modules[moduleId]; + return module && module.exports || loadModule(moduleId, module); +} + +function guardedLoadModule(moduleId, module) { + try { + return loadModuleImplementation(moduleId, module); + } catch (e) { + ErrorUtils.reportFatalError(e); + } +} + +function loadModuleImplementation(moduleId, module) { + if (!module) { + __nativeRequire(moduleId); + module = modules[moduleId]; } - function require(moduleId) { - const module = modules[moduleId]; - return module && module.exports || loadModule(moduleId, module); + if (!module) { + throw unknownModuleError(moduleId); } - function guardedLoadModule(moduleId, module) { - try { - return loadModuleImplementation(moduleId, module); - } catch (e) { - ErrorUtils.reportFatalError(e); - } + if (module.hasError) { + throw moduleThrewError(moduleId); } - function loadModuleImplementation(moduleId, module) { - if (!module) { - __nativeRequire(moduleId); - module = modules[moduleId]; - } - - if (!module) { - throw unknownModuleError(moduleId); - } - - if (module.hasError) { - throw moduleThrewError(moduleId); - } - - const exports = module.exports = {}; - const {factory} = module; - try { - const moduleObject = {exports}; - factory(global, require, moduleObject, exports); - return (module.exports = moduleObject.exports); - } catch(e) { - module.hasError = true; - module.exports = undefined; - } + const exports = module.exports = {}; + const {factory} = module; + try { + const moduleObject = {exports}; + factory(global, require, moduleObject, exports); + return (module.exports = moduleObject.exports); + } catch (e) { + module.hasError = true; + module.exports = undefined; } +} - function unknownModuleError(id) { - let message = 'Requiring unknown module "' + id + '".'; - if (__DEV__) { - message += - 'If you are sure the module is there, try restarting the packager.'; - } - return Error(message); +function unknownModuleError(id) { + let message = 'Requiring unknown module "' + id + '".'; + if (__DEV__) { + message += + 'If you are sure the module is there, try restarting the packager.'; } + return Error(message); +} - function moduleThrewError(id) { - return Error('Requiring module "' + id + '", which threw an exception.'); - } - -})(this); +function moduleThrewError(id) { + return Error('Requiring module "' + id + '", which threw an exception.'); +} diff --git a/packager/react-packager/src/Resolver/polyfills/require.js b/packager/react-packager/src/Resolver/polyfills/require.js index 36c2b6b90..a5a7a55f0 100644 --- a/packager/react-packager/src/Resolver/polyfills/require.js +++ b/packager/react-packager/src/Resolver/polyfills/require.js @@ -1,130 +1,128 @@ /* eslint strict:0 */ -(function(global) { - var modules = Object.create(null); - var inGuard = false; +var modules = Object.create(null); +var inGuard = false; - function define(id, factory) { - modules[id] = { - factory, - module: {exports: {}}, - isInitialized: false, - hasError: false, - }; +function define(id, factory) { + modules[id] = { + factory, + module: {exports: {}}, + isInitialized: false, + hasError: false, + }; - if (__DEV__) { // HMR - Object.assign(modules[id].module, { - hot: { - acceptCallback: null, - accept: function(callback) { - modules[id].module.hot.acceptCallback = callback; - } + if (__DEV__) { // HMR + Object.assign(modules[id].module, { + hot: { + acceptCallback: null, + accept: function(callback) { + modules[id].module.hot.acceptCallback = callback; } - }); - } - } - - function require(id) { - var mod = modules[id]; - if (mod && mod.isInitialized) { - return mod.module.exports; - } - - return requireImpl(id); - } - - function requireImpl(id) { - if (global.ErrorUtils && !inGuard) { - inGuard = true; - var returnValue; - try { - returnValue = requireImpl.apply(this, arguments); - } catch (e) { - global.ErrorUtils.reportFatalError(e); } - inGuard = false; - return returnValue; - } - - var mod = modules[id]; - if (!mod) { - var msg = 'Requiring unknown module "' + id + '"'; - if (__DEV__) { - msg += '. If you are sure the module is there, try restarting the packager.'; - } - throw new Error(msg); - } - - if (mod.hasError) { - throw new Error( - 'Requiring module "' + id + '" which threw an exception' - ); - } - - try { - // We must optimistically mark mod as initialized before running the factory to keep any - // require cycles inside the factory from causing an infinite require loop. - mod.isInitialized = true; - - __DEV__ && Systrace().beginEvent('JS_require_' + id); - - // keep args in sync with with defineModuleCode in - // packager/react-packager/src/Resolver/index.js - mod.factory.call(global, global, require, mod.module, mod.module.exports); - - __DEV__ && Systrace().endEvent(); - } catch (e) { - mod.hasError = true; - mod.isInitialized = false; - throw e; - } + }); + } +} +function require(id) { + var mod = modules[id]; + if (mod && mod.isInitialized) { return mod.module.exports; } - const Systrace = __DEV__ && (() => { - var _Systrace; + return requireImpl(id); +} + +function requireImpl(id) { + if (global.ErrorUtils && !inGuard) { + inGuard = true; + var returnValue; try { - _Systrace = require('Systrace'); - } catch(e) {} + returnValue = requireImpl.apply(this, arguments); + } catch (e) { + global.ErrorUtils.reportFatalError(e); + } + inGuard = false; + return returnValue; + } - return _Systrace && _Systrace.beginEvent ? - _Systrace : { beginEvent: () => {}, endEvent: () => {} }; - }); + var mod = modules[id]; + if (!mod) { + var msg = 'Requiring unknown module "' + id + '"'; + if (__DEV__) { + msg += '. If you are sure the module is there, try restarting the packager.'; + } + throw new Error(msg); + } - global.__d = define; - global.require = require; + if (mod.hasError) { + throw new Error( + 'Requiring module "' + id + '" which threw an exception' + ); + } - if (__DEV__) { // HMR - function accept(id, factory) { - var mod = modules[id]; + try { + // We must optimistically mark mod as initialized before running the factory to keep any + // require cycles inside the factory from causing an infinite require loop. + mod.isInitialized = true; - if (!mod) { - define(id, factory); - return; // new modules don't need to be accepted - } + __DEV__ && Systrace().beginEvent('JS_require_' + id); - if (!mod.module.hot) { - console.warn( - 'Cannot accept module because Hot Module Replacement ' + - 'API was not installed.' - ); - return; - } + // keep args in sync with with defineModuleCode in + // packager/react-packager/src/Resolver/index.js + mod.factory.call(global, global, require, mod.module, mod.module.exports); - if (mod.module.hot.acceptCallback) { - mod.factory = factory; - mod.isInitialized = false; - require(id); + __DEV__ && Systrace().endEvent(); + } catch (e) { + mod.hasError = true; + mod.isInitialized = false; + throw e; + } - mod.module.hot.acceptCallback(); - } else { - console.warn( - '[HMR] Module `' + id + '` can\'t be hot reloaded because it ' + - 'doesn\'t provide accept callback hook. Reload the app to get the updates.' - ); - } + return mod.module.exports; +} + +const Systrace = __DEV__ && (() => { + var _Systrace; + try { + _Systrace = require('Systrace'); + } catch (e) {} + + return _Systrace && _Systrace.beginEvent ? + _Systrace : { beginEvent: () => {}, endEvent: () => {} }; +}); + +global.__d = define; +global.require = require; + +if (__DEV__) { // HMR + function accept(id, factory) { + var mod = modules[id]; + + if (!mod) { + define(id, factory); + return; // new modules don't need to be accepted } - global.__accept = accept; + if (!mod.module.hot) { + console.warn( + 'Cannot accept module because Hot Module Replacement ' + + 'API was not installed.' + ); + return; + } + + if (mod.module.hot.acceptCallback) { + mod.factory = factory; + mod.isInitialized = false; + require(id); + + mod.module.hot.acceptCallback(); + } else { + console.warn( + '[HMR] Module `' + id + '` can\'t be hot reloaded because it ' + + 'doesn\'t provide accept callback hook. Reload the app to get the updates.' + ); + } } -})(this); + + global.__accept = accept; +} diff --git a/packager/react-packager/src/transforms/whole-program-optimisations/__tests__/dead-module-elimination-test.js b/packager/react-packager/src/transforms/whole-program-optimisations/__tests__/dead-module-elimination-test.js index 7525fd0f0..4d7d142c4 100644 --- a/packager/react-packager/src/transforms/whole-program-optimisations/__tests__/dead-module-elimination-test.js +++ b/packager/react-packager/src/transforms/whole-program-optimisations/__tests__/dead-module-elimination-test.js @@ -33,7 +33,7 @@ const trim = (str) => describe('dead-module-elimination', () => { it('should inline __DEV__', () => { compare( - `__DEV__ = false; + `global.__DEV__ = false; var foo = __DEV__;`, `var foo = false;` ); @@ -41,7 +41,7 @@ describe('dead-module-elimination', () => { it('should accept unary operators with literals', () => { compare( - `__DEV__ = !1; + `global.__DEV__ = !1; var foo = __DEV__;`, `var foo = false;` ); @@ -49,7 +49,7 @@ describe('dead-module-elimination', () => { it('should kill dead branches', () => { compare( - `__DEV__ = false; + `global.__DEV__ = false; if (__DEV__) { doSomething(); }`, @@ -74,7 +74,7 @@ describe('dead-module-elimination', () => { it('should kill modules referenced only from dead branches', () => { compare( - `__DEV__ = false; + `global.__DEV__ = false; __d('bar', function() {}); if (__DEV__) { require('bar'); }`, `` @@ -83,7 +83,7 @@ describe('dead-module-elimination', () => { it('should replace logical expressions with the result', () => { compare( - `__DEV__ = false; + `global.__DEV__ = false; __d('bar', function() {}); __DEV__ && require('bar');`, `false;` @@ -92,7 +92,7 @@ describe('dead-module-elimination', () => { it('should keep if result branch', () => { compare( - `__DEV__ = false; + `global.__DEV__ = false; __d('bar', function() {}); if (__DEV__) { killWithFire(); @@ -106,7 +106,7 @@ describe('dead-module-elimination', () => { it('should replace falsy ternaries with alternate expression', () => { compare( - `__DEV__ = false; + `global.__DEV__ = false; __DEV__ ? foo() : bar(); `, `bar();` diff --git a/packager/react-packager/src/transforms/whole-program-optimisations/dead-module-elimination.js b/packager/react-packager/src/transforms/whole-program-optimisations/dead-module-elimination.js index 39eeb0a6c..1d6c8f340 100644 --- a/packager/react-packager/src/transforms/whole-program-optimisations/dead-module-elimination.js +++ b/packager/react-packager/src/transforms/whole-program-optimisations/dead-module-elimination.js @@ -60,7 +60,12 @@ module.exports = function () { AssignmentExpression(path) { const { node } = path; - if (node.left.type === 'Identifier' && node.left.name === '__DEV__') { + if ( + node.left.type === 'MemberExpression' && + node.left.object.name === 'global' && + node.left.property.type === 'Identifier' && + node.left.property.name === '__DEV__' + ) { var value; if (node.right.type === 'BooleanLiteral') { value = node.right.value; @@ -73,7 +78,7 @@ module.exports = function () { } else { return; } - globals[node.left.name] = value; + globals[node.left.property.name] = value; // workaround babel/source map bug - the minifier should strip it path.replaceWith(t.booleanLiteral(value));