From ee5a1deb0b00e46170e3f5e4f51c484c30cafc95 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Tue, 3 May 2016 15:18:10 -0700 Subject: [PATCH] @ignore-signedsource [react-native-packager] use a single require implementation Reviewed By: javache, bestander Differential Revision: D3252718 fb-gh-sync-id: bfd85acc28dd6e2df72a3227743514cb6f8c32f1 fbshipit-source-id: bfd85acc28dd6e2df72a3227743514cb6f8c32f1 --- packager/react-packager/src/Resolver/index.js | 4 +- .../Resolver/polyfills/require-unbundle.js | 117 ----------- .../src/Resolver/polyfills/require.js | 184 ++++++++++-------- 3 files changed, 106 insertions(+), 199 deletions(-) delete mode 100644 packager/react-packager/src/Resolver/polyfills/require-unbundle.js diff --git a/packager/react-packager/src/Resolver/index.js b/packager/react-packager/src/Resolver/index.js index f2cad3e6b..9fd7e4aa8 100644 --- a/packager/react-packager/src/Resolver/index.js +++ b/packager/react-packager/src/Resolver/index.js @@ -163,9 +163,7 @@ class Resolver { ? path.join(__dirname, 'polyfills/prelude_dev.js') : path.join(__dirname, 'polyfills/prelude.js'); - const moduleSystem = opts.unbundle - ? path.join(__dirname, 'polyfills/require-unbundle.js') - : path.join(__dirname, 'polyfills/require.js'); + const moduleSystem = path.join(__dirname, 'polyfills/require.js'); return [ prelude, diff --git a/packager/react-packager/src/Resolver/polyfills/require-unbundle.js b/packager/react-packager/src/Resolver/polyfills/require-unbundle.js deleted file mode 100644 index fa774787e..000000000 --- a/packager/react-packager/src/Resolver/polyfills/require-unbundle.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * 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'; - -global.require = require; -global.__d = define; - -const modules = Object.create(null); - -function define(moduleId, factory) { - if (moduleId in modules) { - // prevent repeated calls to `global.nativeRequire` to overwrite modules - // that are already loaded - return; - } - modules[moduleId] = { - factory, - hasError: false, - isInitialized: false, - exports: undefined, - }; -} - -function require(moduleId) { - const module = modules[moduleId]; - return module && module.isInitialized - ? module.exports - : guardedLoadModule(moduleId, module); -} - -var inGuard = false; -function guardedLoadModule(moduleId, module) { - if (global.ErrorUtils && !inGuard) { - inGuard = true; - var returnValue; - try { - returnValue = loadModuleImplementation(moduleId, module); - } catch (e) { - global.ErrorUtils.reportFatalError(e); - } - inGuard = false; - return returnValue; - } else { - return loadModuleImplementation(moduleId, module); - } -} - -function loadModuleImplementation(moduleId, module) { - if (!module) { - global.nativeRequire(moduleId); - module = modules[moduleId]; - } - - if (!module) { - throw unknownModuleError(moduleId); - } - - if (module.hasError) { - throw moduleThrewError(moduleId); - } - - // `require` calls int the require polyfill itself are not analyzed and - // replaced so that they use numeric module IDs. - // The systrace module will expose itself on the require function so that - // it can be used here. - // TODO(davidaurelio) Scan polyfills for dependencies, too (t9759686) - if (__DEV__) { - var {Systrace} = require; - } - - const exports = module.exports = {}; - module.isInitialized = true; - const {factory} = module; - try { - if (__DEV__) { - Systrace.beginEvent('JS_require_' + moduleId); - } - - const moduleObject = {exports}; - factory(global, require, moduleObject, exports); - module.factory = undefined; - - if (__DEV__) { - Systrace.endEvent(); - } - return (module.exports = moduleObject.exports); - } catch (e) { - module.isInitialized = false; - module.hasError = true; - module.exports = undefined; - throw e; - } -} - -function unknownModuleError(id) { - let message = 'Requiring unknown module "' + id + '".'; - if (__DEV__) { - message += - 'If you are sure the module is there, try restarting the packager or running "npm install".'; - } - return Error(message); -} - -function moduleThrewError(id) { - return Error('Requiring module "' + id + '", which threw an exception.'); -} - -if (__DEV__) { - require.Systrace = { beginEvent: () => {}, endEvent: () => {} }; -} diff --git a/packager/react-packager/src/Resolver/polyfills/require.js b/packager/react-packager/src/Resolver/polyfills/require.js index bf5c37111..045927211 100644 --- a/packager/react-packager/src/Resolver/polyfills/require.js +++ b/packager/react-packager/src/Resolver/polyfills/require.js @@ -7,65 +7,67 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -/* eslint strict:0 */ -var modules = Object.create(null); -var inGuard = false; +'use strict'; -function define(id, factory) { - modules[id] = { +global.require = require; +global.__d = define; + +const modules = Object.create(null); + +function define(moduleId, factory) { + if (moduleId in modules) { + // prevent repeated calls to `global.nativeRequire` to overwrite modules + // that are already loaded + return; + } + modules[moduleId] = { factory, - module: {exports: {}}, - isInitialized: false, hasError: false, + isInitialized: false, + exports: undefined, }; - if (__DEV__) { // HMR - Object.assign(modules[id].module, { - hot: { - acceptCallback: null, - accept: function(callback) { - modules[id].module.hot.acceptCallback = callback; - } - } - }); + modules[moduleId].hot = createHotReloadingObject(); } } -function require(id) { - var mod = modules[id]; - if (mod && mod.isInitialized) { - return mod.module.exports; - } - - return requireImpl(id); +function require(moduleId) { + const module = modules[moduleId]; + return module && module.isInitialized + ? module.exports + : guardedLoadModule(moduleId, module); } -function requireImpl(id) { - if (global.ErrorUtils && !inGuard) { +var inGuard = false; +function guardedLoadModule(moduleId, module) { + if (!inGuard && global.ErrorUtils) { inGuard = true; var returnValue; try { - returnValue = requireImpl(id); + returnValue = loadModuleImplementation(moduleId, module); } catch (e) { global.ErrorUtils.reportFatalError(e); } inGuard = false; return returnValue; + } else { + return loadModuleImplementation(moduleId, module); + } +} + +function loadModuleImplementation(moduleId, module) { + const nativeRequire = global.nativeRequire; + if (!module && nativeRequire) { + nativeRequire(moduleId); + module = modules[moduleId]; } - 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 or running "npm install".'; - } - throw new Error(msg); + if (!module) { + throw unknownModuleError(moduleId); } - if (mod.hasError) { - throw new Error( - 'Requiring module "' + id + '" which threw an exception' - ); + if (module.hasError) { + throw moduleThrewError(moduleId); } // `require` calls int the require polyfill itself are not analyzed and @@ -77,49 +79,95 @@ function requireImpl(id) { var {Systrace} = require; } + // We must optimistically mark module as initialized before running the + // factory to keep any require cycles inside the factory from causing an + // infinite require loop. + module.isInitialized = true; + const exports = module.exports = {}; + const {factory} = module; 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 (__DEV__) { - Systrace.beginEvent('JS_require_' + id); + Systrace.beginEvent('JS_require_' + moduleId); + } + + const moduleObject = {exports}; + if (__DEV__ && module.hot) { + moduleObject.hot = module.hot; } // 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); - mod.factory = undefined; + factory(global, require, moduleObject, exports); + module.factory = undefined; if (__DEV__) { Systrace.endEvent(); } + return (module.exports = moduleObject.exports); } catch (e) { - mod.hasError = true; - mod.isInitialized = false; + module.hasError = true; + module.isInitialized = false; + module.exports = undefined; throw e; } +} - return mod.module.exports; +function unknownModuleError(id) { + let message = 'Requiring unknown module "' + id + '".'; + if (__DEV__) { + message += + 'If you are sure the module is there, try restarting the packager or running "npm install".'; + } + return Error(message); +} + +function moduleThrewError(id) { + return Error('Requiring module "' + id + '", which threw an exception.'); } if (__DEV__) { require.Systrace = { beginEvent: () => {}, endEvent: () => {} }; -} -global.__d = define; -global.require = require; + // HOT MODULE RELOADING + var createHotReloadingObject = function() { + const hot = { + acceptCallback: null, + accept: callback => { hot.acceptCallback = callback; }, + }; + return hot; + }; -if (__DEV__) { // HMR - function accept(id, factory, inverseDependencies) { - var mod = modules[id]; + const acceptAll = function(dependentModules, inverseDependencies) { + if (!dependentModules || dependentModules.length === 0) { + return true; + } + + const notAccepted = dependentModules.filter( + module => !accept(module, /*factory*/ undefined, inverseDependencies)); + + const parents = []; + for (let i = 0; i < notAccepted.length; i++) { + // if the module has no parents then the change cannot be hot loaded + if (inverseDependencies[notAccepted[i]].length === 0) { + return false; + } + + parents.pushAll(inverseDependencies[notAccepted[i]]); + } + + return acceptAll(parents, inverseDependencies); + }; + + const accept = function(id, factory, inverseDependencies) { + const mod = modules[id]; if (!mod) { define(id, factory); return true; // new modules don't need to be accepted } - if (!mod.module.hot) { + const {hot} = mod; + if (!hot) { console.warn( 'Cannot accept module because Hot Module Replacement ' + 'API was not installed.' @@ -134,8 +182,8 @@ if (__DEV__) { // HMR mod.isInitialized = false; require(id); - if (mod.module.hot.acceptCallback) { - mod.module.hot.acceptCallback(); + if (hot.acceptCallback) { + hot.acceptCallback(); return true; } else { // need to have inverseDependencies to bubble up accept @@ -146,29 +194,7 @@ if (__DEV__) { // HMR // accept parent modules recursively up until all siblings are accepted return acceptAll(inverseDependencies[id], inverseDependencies); } - } - - function acceptAll(modules, inverseDependencies) { - if (!modules || modules.length === 0) { - return true; - } - - var notAccepted = modules.filter(function(module) { - return !accept(module, /*factory*/ undefined, inverseDependencies); - }); - - var parents = []; - for (var i = 0; i < notAccepted.length; i++) { - // if this the module has no parents then the change cannot be hot loaded - if (inverseDependencies[notAccepted[i]].length === 0) { - return false; - } - - parents.pushAll(inverseDependencies[notAccepted[i]]); - } - - return acceptAll(parents, inverseDependencies); - } + }; global.__accept = accept; }