mirror of https://github.com/status-im/metro.git
Add flow to require implementation, always warn when modules are accepted by name
Reviewed By: matryoshcow Differential Revision: D4124228 fbshipit-source-id: 461087caf4add07db376bb71ae5ba42bf3536cd3
This commit is contained in:
parent
4ce09ce88a
commit
cda4129dd3
|
@ -5,19 +5,54 @@
|
|||
* 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.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
type Exports = any;
|
||||
type FactoryFn = (
|
||||
global: Object,
|
||||
require: RequireFn,
|
||||
moduleObject: {exports: {}},
|
||||
exports: {},
|
||||
) => void;
|
||||
type HotModuleReloadingAcceptFn = Function;
|
||||
type HotModuleReloadingData = {|
|
||||
acceptCallback: ?HotModuleReloadingAcceptFn,
|
||||
accept: (callback: HotModuleReloadingAcceptFn) => void,
|
||||
|};
|
||||
type Module = {
|
||||
exports: Exports,
|
||||
hot?: HotModuleReloadingData,
|
||||
};
|
||||
type ModuleID = number;
|
||||
type ModuleDefinition = {|
|
||||
factory: FactoryFn,
|
||||
hasError: boolean,
|
||||
isInitialized: boolean,
|
||||
exports: Exports,
|
||||
verboseName?: string,
|
||||
hot?: HotModuleReloadingData,
|
||||
|};
|
||||
type ModuleMap =
|
||||
{[key: ModuleID]: (ModuleDefinition)};
|
||||
type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;
|
||||
type VerboseModuleNameForDev = string;
|
||||
|
||||
global.require = require;
|
||||
global.__d = define;
|
||||
|
||||
const modules = Object.create(null);
|
||||
const modules: ModuleMap = Object.create(null);
|
||||
if (__DEV__) {
|
||||
var verboseNamesToModuleIds = Object.create(null);
|
||||
var verboseNamesToModuleIds: {[key: string]: number} = Object.create(null);
|
||||
}
|
||||
|
||||
function define(moduleId, factory) {
|
||||
function define(
|
||||
moduleId: number,
|
||||
factory: FactoryFn,
|
||||
) {
|
||||
if (moduleId in modules) {
|
||||
// prevent repeated calls to `global.nativeRequire` to overwrite modules
|
||||
// that are already loaded
|
||||
|
@ -35,22 +70,38 @@ function define(moduleId, factory) {
|
|||
|
||||
// DEBUGGABLE MODULES NAMES
|
||||
// avoid unnecessary parameter in prod
|
||||
const verboseName = modules[moduleId].verboseName = arguments[2];
|
||||
verboseNamesToModuleIds[verboseName] = moduleId;
|
||||
const verboseName: string | void = arguments[2];
|
||||
if (verboseName) {
|
||||
modules[moduleId].verboseName = verboseName;
|
||||
verboseNamesToModuleIds[verboseName] = moduleId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function require(moduleId) {
|
||||
const module = __DEV__
|
||||
? modules[moduleId] || modules[verboseNamesToModuleIds[moduleId]]
|
||||
: modules[moduleId];
|
||||
function require(moduleId: ModuleID | VerboseModuleNameForDev) {
|
||||
if (__DEV__ && typeof moduleId === 'string') {
|
||||
const verboseName = moduleId;
|
||||
moduleId = verboseNamesToModuleIds[moduleId];
|
||||
if (moduleId == null) {
|
||||
throw new Error(`Unknown named module: '${verboseName}'`);
|
||||
} else {
|
||||
console.warn(
|
||||
`Requiring module '${verboseName}' by name is only supported for ` +
|
||||
'debugging purposes and will BREAK IN PRODUCTION!'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
moduleId = +moduleId;
|
||||
}
|
||||
|
||||
const module = modules[moduleId];
|
||||
return module && module.isInitialized
|
||||
? module.exports
|
||||
: guardedLoadModule(moduleId, module);
|
||||
}
|
||||
|
||||
let inGuard = false;
|
||||
function guardedLoadModule(moduleId, module) {
|
||||
function guardedLoadModule(moduleId: ModuleID , module) {
|
||||
if (!inGuard && global.ErrorUtils) {
|
||||
inGuard = true;
|
||||
let returnValue;
|
||||
|
@ -73,17 +124,6 @@ function loadModuleImplementation(moduleId, module) {
|
|||
module = modules[moduleId];
|
||||
}
|
||||
|
||||
if (__DEV__ && !module) {
|
||||
// allow verbose module names to be passed as module ID
|
||||
module = modules[verboseNamesToModuleIds[moduleId]];
|
||||
if (module) {
|
||||
console.warn(
|
||||
`Requiring module '${moduleId}' by name is only supported for ` +
|
||||
'debugging purposes and will break in production'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!module) {
|
||||
throw unknownModuleError(moduleId);
|
||||
}
|
||||
|
@ -109,24 +149,28 @@ function loadModuleImplementation(moduleId, module) {
|
|||
const {factory} = module;
|
||||
try {
|
||||
if (__DEV__) {
|
||||
// $FlowFixMe: we know that __DEV__ is const and `Systrace` exists
|
||||
Systrace.beginEvent('JS_require_' + (module.verboseName || moduleId));
|
||||
}
|
||||
|
||||
const moduleObject = {exports};
|
||||
const moduleObject: Module = {exports};
|
||||
if (__DEV__ && module.hot) {
|
||||
moduleObject.hot = module.hot;
|
||||
}
|
||||
|
||||
// keep args in sync with with defineModuleCode in
|
||||
// packager/react-packager/src/Resolver/index.js
|
||||
// and packager/react-packager/src/ModuleGraph/worker.js
|
||||
factory(global, require, moduleObject, exports);
|
||||
|
||||
// avoid removing factory in DEV mode as it breaks HMR
|
||||
if (!__DEV__) {
|
||||
// $FlowFixMe: This is only sound because we never access `factory` again
|
||||
module.factory = undefined;
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
// $FlowFixMe: we know that __DEV__ is const and `Systrace` exists
|
||||
Systrace.endEvent();
|
||||
}
|
||||
return (module.exports = moduleObject.exports);
|
||||
|
@ -156,14 +200,17 @@ if (__DEV__) {
|
|||
|
||||
// HOT MODULE RELOADING
|
||||
var createHotReloadingObject = function() {
|
||||
const hot = {
|
||||
const hot: HotModuleReloadingData = {
|
||||
acceptCallback: null,
|
||||
accept: callback => { hot.acceptCallback = callback; },
|
||||
};
|
||||
return hot;
|
||||
};
|
||||
|
||||
const acceptAll = function(dependentModules, inverseDependencies) {
|
||||
const acceptAll = function(
|
||||
dependentModules,
|
||||
inverseDependencies,
|
||||
) {
|
||||
if (!dependentModules || dependentModules.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -178,16 +225,20 @@ if (__DEV__) {
|
|||
return false;
|
||||
}
|
||||
|
||||
parents.pushAll(inverseDependencies[notAccepted[i]]);
|
||||
parents.push(...inverseDependencies[notAccepted[i]]);
|
||||
}
|
||||
|
||||
return acceptAll(parents, inverseDependencies);
|
||||
};
|
||||
|
||||
const accept = function(id, factory, inverseDependencies) {
|
||||
const accept = function(
|
||||
id: ModuleID,
|
||||
factory?: FactoryFn,
|
||||
inverseDependencies: {[key: ModuleID]: Array<ModuleID>},
|
||||
) {
|
||||
const mod = modules[id];
|
||||
|
||||
if (!mod) {
|
||||
if (!mod && factory) { // new modules need a factory
|
||||
define(id, factory);
|
||||
return true; // new modules don't need to be accepted
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue