mirror of https://github.com/status-im/metro.git
Prepare `__d` fn for Buck integration
Summary: The new Packager/Buck integration passes module factory functions as first argument, so that the complete call can be amended at the end safely at a later point in time. The call expression as a whole is covered perfectly by the created source map. Appending to that code later won’t break mappings. `__d` now also accepts an additional `dependencyMap` parameter, which so far is only used by the new Packager/Buck integration. It enables module-local dependency IDs, thus eliminating the need to insert `correct` module IDs when building a bundle. Advantages are that source maps are no longer affected, and that builds can be quicker. Reviewed By: cpojer Differential Revision: D4124333 fbshipit-source-id: 12eba15d0b9d8c6624280a2ba1e7e4bc654bc83d
This commit is contained in:
parent
c296a3ee25
commit
dee58678c6
|
@ -366,19 +366,19 @@ describe('Resolver', function() {
|
|||
dev: false,
|
||||
}).then(({code: processedCode}) => {
|
||||
expect(processedCode).toEqual([
|
||||
`__d(${resolutionResponse.getModuleId(module)} /* test module */, function(global, require, module, exports) {` +
|
||||
'__d(/* test module */function(global, require, module, exports) {' +
|
||||
// require
|
||||
`require(${moduleIds.get('x')} /* x */)`,
|
||||
`require(${moduleIds.get('y')} /* y */)`,
|
||||
'require( \'z\' )',
|
||||
'require( "a")',
|
||||
'require("b" )',
|
||||
'});',
|
||||
`}, ${resolutionResponse.getModuleId(module)});`,
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
|
||||
pit('should add module transport names as third argument to `__d`', () => {
|
||||
pit('should add module transport names as fourth argument to `__d`', () => {
|
||||
const module = createModule('test module');
|
||||
const code = 'arbitrary(code)'
|
||||
const resolutionResponse = new ResolutionResponseMock({
|
||||
|
@ -393,9 +393,9 @@ describe('Resolver', function() {
|
|||
dev: true,
|
||||
}).then(({code: processedCode}) =>
|
||||
expect(processedCode).toEqual([
|
||||
`__d(${resolutionResponse.getModuleId(module)} /* test module */, function(global, require, module, exports) {` +
|
||||
'__d(/* test module */function(global, require, module, exports) {' +
|
||||
code,
|
||||
'}, "test module");'
|
||||
`}, ${resolutionResponse.getModuleId(module)}, null, "test module");`
|
||||
].join('\n'))
|
||||
);
|
||||
});
|
||||
|
@ -455,8 +455,8 @@ describe('Resolver', function() {
|
|||
.wrapModule({resolutionResponse, module, name: id, code, dev: false})
|
||||
.then(({code: processedCode}) =>
|
||||
expect(processedCode).toEqual([
|
||||
`__d(${resolutionResponse.getModuleId(module)} /* ${id} */, function(global, require, module, exports) {`,
|
||||
`module.exports = ${code}\n});`,
|
||||
`__d(/* ${id} */function(global, require, module, exports) {`,
|
||||
`module.exports = ${code}\n}, ${resolutionResponse.getModuleId(module)});`,
|
||||
].join('')));
|
||||
});
|
||||
});
|
||||
|
@ -483,7 +483,9 @@ describe('Resolver', function() {
|
|||
});
|
||||
|
||||
pit('should invoke the minifier with the wrapped code', () => {
|
||||
const wrappedCode = `__d(${resolutionResponse.getModuleId(module)} /* ${id} */, function(global, require, module, exports) {${code}\n});`
|
||||
const wrappedCode =
|
||||
`__d(/* ${id} */function(global, require, module, exports) {${
|
||||
code}\n}, ${resolutionResponse.getModuleId(module)});`
|
||||
return depResolver
|
||||
.wrapModule({
|
||||
resolutionResponse,
|
||||
|
|
|
@ -259,12 +259,12 @@ class Resolver {
|
|||
|
||||
function defineModuleCode(moduleName, code, verboseName = '', dev = true) {
|
||||
return [
|
||||
'__d(',
|
||||
`${JSON.stringify(moduleName)} /* ${verboseName} */, `,
|
||||
'function(global, require, module, exports) {',
|
||||
`__d(/* ${verboseName} */`,
|
||||
'function(global, require, module, exports) {', // module factory
|
||||
code,
|
||||
'\n}',
|
||||
dev ? `, ${JSON.stringify(verboseName)}` : '',
|
||||
'\n}, ',
|
||||
`${JSON.stringify(moduleName)}`, // module id, null = id map. used in ModuleGraph
|
||||
dev ? `, null, ${JSON.stringify(verboseName)}` : '',
|
||||
');',
|
||||
].join('');
|
||||
}
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
type DependencyMap = Array<ModuleID>;
|
||||
type Exports = any;
|
||||
type FactoryFn = (
|
||||
global: Object,
|
||||
require: RequireFn,
|
||||
moduleObject: {exports: {}},
|
||||
exports: {},
|
||||
dependencyMap: ?DependencyMap,
|
||||
) => void;
|
||||
type HotModuleReloadingAcceptFn = Function;
|
||||
type HotModuleReloadingData = {|
|
||||
|
@ -29,12 +31,13 @@ type Module = {
|
|||
};
|
||||
type ModuleID = number;
|
||||
type ModuleDefinition = {|
|
||||
dependencyMap: ?DependencyMap,
|
||||
exports: Exports,
|
||||
factory: FactoryFn,
|
||||
hasError: boolean,
|
||||
isInitialized: boolean,
|
||||
exports: Exports,
|
||||
verboseName?: string,
|
||||
hot?: HotModuleReloadingData,
|
||||
isInitialized: boolean,
|
||||
verboseName?: string,
|
||||
|};
|
||||
type ModuleMap =
|
||||
{[key: ModuleID]: (ModuleDefinition)};
|
||||
|
@ -50,8 +53,9 @@ if (__DEV__) {
|
|||
}
|
||||
|
||||
function define(
|
||||
moduleId: number,
|
||||
factory: FactoryFn,
|
||||
moduleId: number,
|
||||
dependencyMap?: DependencyMap,
|
||||
) {
|
||||
if (moduleId in modules) {
|
||||
// prevent repeated calls to `global.nativeRequire` to overwrite modules
|
||||
|
@ -59,18 +63,20 @@ function define(
|
|||
return;
|
||||
}
|
||||
modules[moduleId] = {
|
||||
dependencyMap,
|
||||
exports: undefined,
|
||||
factory,
|
||||
hasError: false,
|
||||
isInitialized: false,
|
||||
exports: undefined,
|
||||
};
|
||||
if (__DEV__) {
|
||||
// HMR
|
||||
modules[moduleId].hot = createHotReloadingObject();
|
||||
|
||||
// DEBUGGABLE MODULES NAMES
|
||||
// avoid unnecessary parameter in prod
|
||||
const verboseName: string | void = arguments[2];
|
||||
// we take `verboseName` from `arguments` to avoid an unused named parameter
|
||||
// in `define` in production.
|
||||
const verboseName: string | void = arguments[3];
|
||||
if (verboseName) {
|
||||
modules[moduleId].verboseName = verboseName;
|
||||
verboseNamesToModuleIds[verboseName] = moduleId;
|
||||
|
@ -90,14 +96,14 @@ function require(moduleId: ModuleID | VerboseModuleNameForDev) {
|
|||
'debugging purposes and will BREAK IN PRODUCTION!'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
moduleId = +moduleId;
|
||||
}
|
||||
|
||||
const module = modules[moduleId];
|
||||
//$FlowFixMe: at this point we know that moduleId is a number
|
||||
const moduleIdReallyIsNumber: number = moduleId;
|
||||
const module = modules[moduleIdReallyIsNumber];
|
||||
return module && module.isInitialized
|
||||
? module.exports
|
||||
: guardedLoadModule(moduleId, module);
|
||||
: guardedLoadModule(moduleIdReallyIsNumber, module);
|
||||
}
|
||||
|
||||
let inGuard = false;
|
||||
|
@ -146,7 +152,7 @@ function loadModuleImplementation(moduleId, module) {
|
|||
// infinite require loop.
|
||||
module.isInitialized = true;
|
||||
const exports = module.exports = {};
|
||||
const {factory} = module;
|
||||
const {factory, dependencyMap} = module;
|
||||
try {
|
||||
if (__DEV__) {
|
||||
// $FlowFixMe: we know that __DEV__ is const and `Systrace` exists
|
||||
|
@ -161,7 +167,7 @@ function loadModuleImplementation(moduleId, module) {
|
|||
// 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);
|
||||
factory(global, require, moduleObject, exports, dependencyMap);
|
||||
|
||||
// avoid removing factory in DEV mode as it breaks HMR
|
||||
if (!__DEV__) {
|
||||
|
@ -239,7 +245,7 @@ if (__DEV__) {
|
|||
const mod = modules[id];
|
||||
|
||||
if (!mod && factory) { // new modules need a factory
|
||||
define(id, factory);
|
||||
define(factory, id);
|
||||
return true; // new modules don't need to be accepted
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue