mirror of https://github.com/status-im/metro.git
Bundler.js: @flow
Reviewed By: davidaurelio Differential Revision: D4036964 fbshipit-source-id: dceb81299d076493d12b2ade13354e927c10ea7c
This commit is contained in:
parent
c803b69ce1
commit
977e7209ac
|
@ -5,19 +5,41 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* 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
|
* 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.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const BundleBase = require('./BundleBase');
|
||||||
|
const ModuleTransport = require('../lib/ModuleTransport');
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const base64VLQ = require('./base64-vlq');
|
const base64VLQ = require('./base64-vlq');
|
||||||
const BundleBase = require('./BundleBase');
|
|
||||||
const ModuleTransport = require('../lib/ModuleTransport');
|
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
import type {GetSourceOptions, FinalizeOptions} from './BundleBase';
|
||||||
|
|
||||||
const SOURCEMAPPING_URL = '\n\/\/# sourceMappingURL=';
|
const SOURCEMAPPING_URL = '\n\/\/# sourceMappingURL=';
|
||||||
|
|
||||||
class Bundle extends BundleBase {
|
class Bundle extends BundleBase {
|
||||||
constructor({sourceMapUrl, dev, minify, ramGroups} = {}) {
|
|
||||||
|
_dev: boolean | void;
|
||||||
|
_inlineSourceMap: string | void;
|
||||||
|
_minify: boolean | void;
|
||||||
|
_numRequireCalls: number;
|
||||||
|
_ramBundle: mixed | void;
|
||||||
|
_ramGroups: Array<string> | void;
|
||||||
|
_shouldCombineSourceMaps: boolean;
|
||||||
|
_sourceMap: boolean;
|
||||||
|
_sourceMapUrl: string | void;
|
||||||
|
|
||||||
|
constructor({sourceMapUrl, dev, minify, ramGroups}: {
|
||||||
|
sourceMapUrl?: string,
|
||||||
|
dev?: boolean,
|
||||||
|
minify?: boolean,
|
||||||
|
ramGroups?: Array<string>,
|
||||||
|
} = {}) {
|
||||||
super();
|
super();
|
||||||
this._sourceMap = false;
|
this._sourceMap = false;
|
||||||
this._sourceMapUrl = sourceMapUrl;
|
this._sourceMapUrl = sourceMapUrl;
|
||||||
|
@ -30,7 +52,16 @@ class Bundle extends BundleBase {
|
||||||
this._ramBundle = null; // cached RAM Bundle
|
this._ramBundle = null; // cached RAM Bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
addModule(resolver, resolutionResponse, module, moduleTransport) {
|
addModule(
|
||||||
|
resolver: {wrapModule: (options: any) => Promise<{code: any, map: any}>},
|
||||||
|
resolutionResponse: mixed,
|
||||||
|
module: mixed,
|
||||||
|
moduleTransport: ModuleTransport,
|
||||||
|
/* $FlowFixMe: this code is inherently incorrect, because it modifies the
|
||||||
|
* signature of the base class function "addModule", originally returning
|
||||||
|
* a number. That means callsites using an instance typed as the base class
|
||||||
|
* would be broken. This must be refactored. */
|
||||||
|
): Promise<void> {
|
||||||
const index = super.addModule(moduleTransport);
|
const index = super.addModule(moduleTransport);
|
||||||
return resolver.wrapModule({
|
return resolver.wrapModule({
|
||||||
resolutionResponse,
|
resolutionResponse,
|
||||||
|
@ -53,17 +84,21 @@ class Bundle extends BundleBase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(options) {
|
finalize(options: FinalizeOptions) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
if (options.runMainModule) {
|
if (options.runMainModule) {
|
||||||
|
/* $FlowFixMe: this is unsound, as nothing enforces runBeforeMainModule
|
||||||
|
* to be available if `runMainModule` is true. Refactor. */
|
||||||
options.runBeforeMainModule.forEach(this._addRequireCall, this);
|
options.runBeforeMainModule.forEach(this._addRequireCall, this);
|
||||||
|
/* $FlowFixMe: this is unsound, as nothing enforces the module ID to have
|
||||||
|
* been set beforehand. */
|
||||||
this._addRequireCall(super.getMainModuleId());
|
this._addRequireCall(super.getMainModuleId());
|
||||||
}
|
}
|
||||||
|
|
||||||
super.finalize(options);
|
super.finalize(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addRequireCall(moduleId) {
|
_addRequireCall(moduleId: string) {
|
||||||
const code = `;require(${JSON.stringify(moduleId)});`;
|
const code = `;require(${JSON.stringify(moduleId)});`;
|
||||||
const name = 'require-' + moduleId;
|
const name = 'require-' + moduleId;
|
||||||
super.addModule(new ModuleTransport({
|
super.addModule(new ModuleTransport({
|
||||||
|
@ -88,12 +123,12 @@ class Bundle extends BundleBase {
|
||||||
return this._inlineSourceMap;
|
return this._inlineSourceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSource(options) {
|
getSource(options: GetSourceOptions) {
|
||||||
super.assertFinalized();
|
super.assertFinalized();
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
let source = super.getSource();
|
let source = super.getSource(options);
|
||||||
|
|
||||||
if (options.inlineSourceMap) {
|
if (options.inlineSourceMap) {
|
||||||
source += SOURCEMAPPING_URL + this._getInlineSourceMap(options.dev);
|
source += SOURCEMAPPING_URL + this._getInlineSourceMap(options.dev);
|
||||||
|
@ -104,7 +139,7 @@ class Bundle extends BundleBase {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUnbundle(type) {
|
getUnbundle() {
|
||||||
this.assertFinalized();
|
this.assertFinalized();
|
||||||
if (!this._ramBundle) {
|
if (!this._ramBundle) {
|
||||||
const modules = this.getModules().slice();
|
const modules = this.getModules().slice();
|
||||||
|
@ -122,7 +157,7 @@ class Bundle extends BundleBase {
|
||||||
groups = createGroups(ramGroups || [], lazyModules);
|
groups = createGroups(ramGroups || [], lazyModules);
|
||||||
}
|
}
|
||||||
return groups;
|
return groups;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +201,7 @@ class Bundle extends BundleBase {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSourceMap(options) {
|
getSourceMap(options: {excludeSource?: boolean}) {
|
||||||
super.assertFinalized();
|
super.assertFinalized();
|
||||||
|
|
||||||
if (this._shouldCombineSourceMaps) {
|
if (this._shouldCombineSourceMaps) {
|
||||||
|
@ -182,12 +217,14 @@ class Bundle extends BundleBase {
|
||||||
names: [],
|
names: [],
|
||||||
mappings: mappings,
|
mappings: mappings,
|
||||||
sourcesContent: options.excludeSource
|
sourcesContent: options.excludeSource
|
||||||
? [] : modules.map(module => module.sourceCode)
|
? [] : modules.map(module => module.sourceCode),
|
||||||
};
|
};
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEtag() {
|
getEtag() {
|
||||||
|
/* $FlowFixMe: we must pass options, or rename the
|
||||||
|
* base `getSource` function, as it does not actually need options. */
|
||||||
var eTag = crypto.createHash('md5').update(this.getSource()).digest('hex');
|
var eTag = crypto.createHash('md5').update(this.getSource()).digest('hex');
|
||||||
return eTag;
|
return eTag;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +291,7 @@ class Bundle extends BundleBase {
|
||||||
|
|
||||||
getDebugInfo() {
|
getDebugInfo() {
|
||||||
return [
|
return [
|
||||||
|
/* $FlowFixMe: this is unsound as the module ID could be unset. */
|
||||||
'<div><h3>Main Module:</h3> ' + super.getMainModuleId() + '</div>',
|
'<div><h3>Main Module:</h3> ' + super.getMainModuleId() + '</div>',
|
||||||
'<style>',
|
'<style>',
|
||||||
'pre.collapsed {',
|
'pre.collapsed {',
|
||||||
|
@ -274,7 +312,7 @@ class Bundle extends BundleBase {
|
||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
setRamGroups(ramGroups) {
|
setRamGroups(ramGroups: Array<string>) {
|
||||||
this._ramGroups = ramGroups;
|
this._ramGroups = ramGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +377,7 @@ function * filter(iterator, predicate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function * subtree(moduleTransport, moduleTransportsByPath, seen = new Set()) {
|
function * subtree(moduleTransport: ModuleTransport, moduleTransportsByPath, seen = new Set()) {
|
||||||
seen.add(moduleTransport.id);
|
seen.add(moduleTransport.id);
|
||||||
for (const [, {path}] of moduleTransport.meta.dependencyPairs || []) {
|
for (const [, {path}] of moduleTransport.meta.dependencyPairs || []) {
|
||||||
const dependency = moduleTransportsByPath.get(path);
|
const dependency = moduleTransportsByPath.get(path);
|
||||||
|
@ -361,7 +399,7 @@ class ArrayMap extends Map {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createGroups(ramGroups, lazyModules) {
|
function createGroups(ramGroups: Array<string>, lazyModules) {
|
||||||
// build two maps that allow to lookup module data
|
// build two maps that allow to lookup module data
|
||||||
// by path or (numeric) module id;
|
// by path or (numeric) module id;
|
||||||
const byPath = new Map();
|
const byPath = new Map();
|
||||||
|
@ -400,12 +438,14 @@ function createGroups(ramGroups, lazyModules) {
|
||||||
const doubles = filter(all, ([, parents]) => parents.length > 1);
|
const doubles = filter(all, ([, parents]) => parents.length > 1);
|
||||||
for (const [moduleId, parents] of doubles) {
|
for (const [moduleId, parents] of doubles) {
|
||||||
// remove them from their groups
|
// remove them from their groups
|
||||||
|
/* $FlowFixMe: this assumes the element exists. */
|
||||||
parents.forEach(p => result.get(p).delete(moduleId));
|
parents.forEach(p => result.get(p).delete(moduleId));
|
||||||
|
|
||||||
// print a warning for each removed module
|
// print a warning for each removed module
|
||||||
const parentNames = parents.map(byId.get, byId);
|
const parentNames = parents.map(byId.get, byId);
|
||||||
const lastName = parentNames.pop();
|
const lastName = parentNames.pop();
|
||||||
console.warn(
|
console.warn(
|
||||||
|
/* $FlowFixMe: this assumes the element exists. */
|
||||||
`Module ${byId.get(moduleId)} belongs to groups ${
|
`Module ${byId.get(moduleId)} belongs to groups ${
|
||||||
parentNames.join(', ')}, and ${lastName
|
parentNames.join(', ')}, and ${lastName
|
||||||
}. Removing it from all groups.`
|
}. Removing it from all groups.`
|
||||||
|
|
|
@ -12,11 +12,22 @@
|
||||||
|
|
||||||
const ModuleTransport = require('../lib/ModuleTransport');
|
const ModuleTransport = require('../lib/ModuleTransport');
|
||||||
|
|
||||||
|
export type FinalizeOptions = {
|
||||||
|
allowUpdates?: boolean,
|
||||||
|
runBeforeMainModule?: Array<mixed>,
|
||||||
|
runMainModule?: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetSourceOptions = {
|
||||||
|
inlineSourceMap: boolean,
|
||||||
|
dev: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
class BundleBase {
|
class BundleBase {
|
||||||
|
|
||||||
_assets: Array<mixed>;
|
_assets: Array<mixed>;
|
||||||
_finalized: boolean;
|
_finalized: boolean;
|
||||||
_mainModuleId: mixed | void;
|
_mainModuleId: string | void;
|
||||||
_modules: Array<ModuleTransport>;
|
_modules: Array<ModuleTransport>;
|
||||||
_source: ?string;
|
_source: ?string;
|
||||||
|
|
||||||
|
@ -35,7 +46,7 @@ class BundleBase {
|
||||||
return this._mainModuleId;
|
return this._mainModuleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMainModuleId(moduleId: mixed) {
|
setMainModuleId(moduleId: string) {
|
||||||
this._mainModuleId = moduleId;
|
this._mainModuleId = moduleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +78,7 @@ class BundleBase {
|
||||||
this._assets.push(asset);
|
this._assets.push(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(options: {allowUpdates?: boolean}) {
|
finalize(options: FinalizeOptions) {
|
||||||
if (!options.allowUpdates) {
|
if (!options.allowUpdates) {
|
||||||
Object.freeze(this._modules);
|
Object.freeze(this._modules);
|
||||||
Object.freeze(this._assets);
|
Object.freeze(this._assets);
|
||||||
|
@ -76,7 +87,7 @@ class BundleBase {
|
||||||
this._finalized = true;
|
this._finalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSource() {
|
getSource(options: GetSourceOptions) {
|
||||||
this.assertFinalized();
|
this.assertFinalized();
|
||||||
|
|
||||||
if (this._source) {
|
if (this._source) {
|
||||||
|
@ -97,9 +108,9 @@ class BundleBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setRamGroups() {}
|
setRamGroups(ramGroups: Array<string>) {}
|
||||||
|
|
||||||
toJSON() {
|
toJSON(): mixed {
|
||||||
return {
|
return {
|
||||||
modules: this._modules,
|
modules: this._modules,
|
||||||
assets: this._assets,
|
assets: this._assets,
|
||||||
|
|
Loading…
Reference in New Issue