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,
|
dev: false,
|
||||||
}).then(({code: processedCode}) => {
|
}).then(({code: processedCode}) => {
|
||||||
expect(processedCode).toEqual([
|
expect(processedCode).toEqual([
|
||||||
`__d(${resolutionResponse.getModuleId(module)} /* test module */, function(global, require, module, exports) {` +
|
'__d(/* test module */function(global, require, module, exports) {' +
|
||||||
// require
|
// require
|
||||||
`require(${moduleIds.get('x')} /* x */)`,
|
`require(${moduleIds.get('x')} /* x */)`,
|
||||||
`require(${moduleIds.get('y')} /* y */)`,
|
`require(${moduleIds.get('y')} /* y */)`,
|
||||||
'require( \'z\' )',
|
'require( \'z\' )',
|
||||||
'require( "a")',
|
'require( "a")',
|
||||||
'require("b" )',
|
'require("b" )',
|
||||||
'});',
|
`}, ${resolutionResponse.getModuleId(module)});`,
|
||||||
].join('\n'));
|
].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 module = createModule('test module');
|
||||||
const code = 'arbitrary(code)'
|
const code = 'arbitrary(code)'
|
||||||
const resolutionResponse = new ResolutionResponseMock({
|
const resolutionResponse = new ResolutionResponseMock({
|
||||||
|
@ -393,9 +393,9 @@ describe('Resolver', function() {
|
||||||
dev: true,
|
dev: true,
|
||||||
}).then(({code: processedCode}) =>
|
}).then(({code: processedCode}) =>
|
||||||
expect(processedCode).toEqual([
|
expect(processedCode).toEqual([
|
||||||
`__d(${resolutionResponse.getModuleId(module)} /* test module */, function(global, require, module, exports) {` +
|
'__d(/* test module */function(global, require, module, exports) {' +
|
||||||
code,
|
code,
|
||||||
'}, "test module");'
|
`}, ${resolutionResponse.getModuleId(module)}, null, "test module");`
|
||||||
].join('\n'))
|
].join('\n'))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -455,8 +455,8 @@ describe('Resolver', function() {
|
||||||
.wrapModule({resolutionResponse, module, name: id, code, dev: false})
|
.wrapModule({resolutionResponse, module, name: id, code, dev: false})
|
||||||
.then(({code: processedCode}) =>
|
.then(({code: processedCode}) =>
|
||||||
expect(processedCode).toEqual([
|
expect(processedCode).toEqual([
|
||||||
`__d(${resolutionResponse.getModuleId(module)} /* ${id} */, function(global, require, module, exports) {`,
|
`__d(/* ${id} */function(global, require, module, exports) {`,
|
||||||
`module.exports = ${code}\n});`,
|
`module.exports = ${code}\n}, ${resolutionResponse.getModuleId(module)});`,
|
||||||
].join('')));
|
].join('')));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -483,7 +483,9 @@ describe('Resolver', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
pit('should invoke the minifier with the wrapped code', () => {
|
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
|
return depResolver
|
||||||
.wrapModule({
|
.wrapModule({
|
||||||
resolutionResponse,
|
resolutionResponse,
|
||||||
|
|
|
@ -259,12 +259,12 @@ class Resolver {
|
||||||
|
|
||||||
function defineModuleCode(moduleName, code, verboseName = '', dev = true) {
|
function defineModuleCode(moduleName, code, verboseName = '', dev = true) {
|
||||||
return [
|
return [
|
||||||
'__d(',
|
`__d(/* ${verboseName} */`,
|
||||||
`${JSON.stringify(moduleName)} /* ${verboseName} */, `,
|
'function(global, require, module, exports) {', // module factory
|
||||||
'function(global, require, module, exports) {',
|
|
||||||
code,
|
code,
|
||||||
'\n}',
|
'\n}, ',
|
||||||
dev ? `, ${JSON.stringify(verboseName)}` : '',
|
`${JSON.stringify(moduleName)}`, // module id, null = id map. used in ModuleGraph
|
||||||
|
dev ? `, null, ${JSON.stringify(verboseName)}` : '',
|
||||||
');',
|
');',
|
||||||
].join('');
|
].join('');
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
type DependencyMap = Array<ModuleID>;
|
||||||
type Exports = any;
|
type Exports = any;
|
||||||
type FactoryFn = (
|
type FactoryFn = (
|
||||||
global: Object,
|
global: Object,
|
||||||
require: RequireFn,
|
require: RequireFn,
|
||||||
moduleObject: {exports: {}},
|
moduleObject: {exports: {}},
|
||||||
exports: {},
|
exports: {},
|
||||||
|
dependencyMap: ?DependencyMap,
|
||||||
) => void;
|
) => void;
|
||||||
type HotModuleReloadingAcceptFn = Function;
|
type HotModuleReloadingAcceptFn = Function;
|
||||||
type HotModuleReloadingData = {|
|
type HotModuleReloadingData = {|
|
||||||
|
@ -29,12 +31,13 @@ type Module = {
|
||||||
};
|
};
|
||||||
type ModuleID = number;
|
type ModuleID = number;
|
||||||
type ModuleDefinition = {|
|
type ModuleDefinition = {|
|
||||||
|
dependencyMap: ?DependencyMap,
|
||||||
|
exports: Exports,
|
||||||
factory: FactoryFn,
|
factory: FactoryFn,
|
||||||
hasError: boolean,
|
hasError: boolean,
|
||||||
isInitialized: boolean,
|
|
||||||
exports: Exports,
|
|
||||||
verboseName?: string,
|
|
||||||
hot?: HotModuleReloadingData,
|
hot?: HotModuleReloadingData,
|
||||||
|
isInitialized: boolean,
|
||||||
|
verboseName?: string,
|
||||||
|};
|
|};
|
||||||
type ModuleMap =
|
type ModuleMap =
|
||||||
{[key: ModuleID]: (ModuleDefinition)};
|
{[key: ModuleID]: (ModuleDefinition)};
|
||||||
|
@ -50,8 +53,9 @@ if (__DEV__) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function define(
|
function define(
|
||||||
moduleId: number,
|
|
||||||
factory: FactoryFn,
|
factory: FactoryFn,
|
||||||
|
moduleId: number,
|
||||||
|
dependencyMap?: DependencyMap,
|
||||||
) {
|
) {
|
||||||
if (moduleId in modules) {
|
if (moduleId in modules) {
|
||||||
// prevent repeated calls to `global.nativeRequire` to overwrite modules
|
// prevent repeated calls to `global.nativeRequire` to overwrite modules
|
||||||
|
@ -59,18 +63,20 @@ function define(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modules[moduleId] = {
|
modules[moduleId] = {
|
||||||
|
dependencyMap,
|
||||||
|
exports: undefined,
|
||||||
factory,
|
factory,
|
||||||
hasError: false,
|
hasError: false,
|
||||||
isInitialized: false,
|
isInitialized: false,
|
||||||
exports: undefined,
|
|
||||||
};
|
};
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
// HMR
|
// HMR
|
||||||
modules[moduleId].hot = createHotReloadingObject();
|
modules[moduleId].hot = createHotReloadingObject();
|
||||||
|
|
||||||
// DEBUGGABLE MODULES NAMES
|
// DEBUGGABLE MODULES NAMES
|
||||||
// avoid unnecessary parameter in prod
|
// we take `verboseName` from `arguments` to avoid an unused named parameter
|
||||||
const verboseName: string | void = arguments[2];
|
// in `define` in production.
|
||||||
|
const verboseName: string | void = arguments[3];
|
||||||
if (verboseName) {
|
if (verboseName) {
|
||||||
modules[moduleId].verboseName = verboseName;
|
modules[moduleId].verboseName = verboseName;
|
||||||
verboseNamesToModuleIds[verboseName] = moduleId;
|
verboseNamesToModuleIds[verboseName] = moduleId;
|
||||||
|
@ -90,14 +96,14 @@ function require(moduleId: ModuleID | VerboseModuleNameForDev) {
|
||||||
'debugging purposes and will BREAK IN PRODUCTION!'
|
'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
|
return module && module.isInitialized
|
||||||
? module.exports
|
? module.exports
|
||||||
: guardedLoadModule(moduleId, module);
|
: guardedLoadModule(moduleIdReallyIsNumber, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
let inGuard = false;
|
let inGuard = false;
|
||||||
|
@ -146,7 +152,7 @@ function loadModuleImplementation(moduleId, module) {
|
||||||
// infinite require loop.
|
// infinite require loop.
|
||||||
module.isInitialized = true;
|
module.isInitialized = true;
|
||||||
const exports = module.exports = {};
|
const exports = module.exports = {};
|
||||||
const {factory} = module;
|
const {factory, dependencyMap} = module;
|
||||||
try {
|
try {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
// $FlowFixMe: we know that __DEV__ is const and `Systrace` exists
|
// $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
|
// keep args in sync with with defineModuleCode in
|
||||||
// packager/react-packager/src/Resolver/index.js
|
// packager/react-packager/src/Resolver/index.js
|
||||||
// and packager/react-packager/src/ModuleGraph/worker.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
|
// avoid removing factory in DEV mode as it breaks HMR
|
||||||
if (!__DEV__) {
|
if (!__DEV__) {
|
||||||
|
@ -239,7 +245,7 @@ if (__DEV__) {
|
||||||
const mod = modules[id];
|
const mod = modules[id];
|
||||||
|
|
||||||
if (!mod && factory) { // new modules need a factory
|
if (!mod && factory) { // new modules need a factory
|
||||||
define(id, factory);
|
define(factory, id);
|
||||||
return true; // new modules don't need to be accepted
|
return true; // new modules don't need to be accepted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue