Bundler.js: @flow
Reviewed By: davidaurelio Differential Revision: D4036964 fbshipit-source-id: dceb81299d076493d12b2ade13354e927c10ea7c
This commit is contained in:
parent
7fbb46c316
commit
2e06e708fe
|
@ -5,19 +5,41 @@
|
|||
* 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';
|
||||
|
||||
const BundleBase = require('./BundleBase');
|
||||
const ModuleTransport = require('../lib/ModuleTransport');
|
||||
|
||||
const _ = require('lodash');
|
||||
const base64VLQ = require('./base64-vlq');
|
||||
const BundleBase = require('./BundleBase');
|
||||
const ModuleTransport = require('../lib/ModuleTransport');
|
||||
const crypto = require('crypto');
|
||||
|
||||
import type {GetSourceOptions, FinalizeOptions} from './BundleBase';
|
||||
|
||||
const SOURCEMAPPING_URL = '\n\/\/# sourceMappingURL=';
|
||||
|
||||
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();
|
||||
this._sourceMap = false;
|
||||
this._sourceMapUrl = sourceMapUrl;
|
||||
|
@ -30,7 +52,16 @@ class Bundle extends BundleBase {
|
|||
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);
|
||||
return resolver.wrapModule({
|
||||
resolutionResponse,
|
||||
|
@ -53,17 +84,21 @@ class Bundle extends BundleBase {
|
|||
});
|
||||
}
|
||||
|
||||
finalize(options) {
|
||||
finalize(options: FinalizeOptions) {
|
||||
options = options || {};
|
||||
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);
|
||||
/* $FlowFixMe: this is unsound, as nothing enforces the module ID to have
|
||||
* been set beforehand. */
|
||||
this._addRequireCall(super.getMainModuleId());
|
||||
}
|
||||
|
||||
super.finalize(options);
|
||||
}
|
||||
|
||||
_addRequireCall(moduleId) {
|
||||
_addRequireCall(moduleId: string) {
|
||||
const code = `;require(${JSON.stringify(moduleId)});`;
|
||||
const name = 'require-' + moduleId;
|
||||
super.addModule(new ModuleTransport({
|
||||
|
@ -88,12 +123,12 @@ class Bundle extends BundleBase {
|
|||
return this._inlineSourceMap;
|
||||
}
|
||||
|
||||
getSource(options) {
|
||||
getSource(options: GetSourceOptions) {
|
||||
super.assertFinalized();
|
||||
|
||||
options = options || {};
|
||||
|
||||
let source = super.getSource();
|
||||
let source = super.getSource(options);
|
||||
|
||||
if (options.inlineSourceMap) {
|
||||
source += SOURCEMAPPING_URL + this._getInlineSourceMap(options.dev);
|
||||
|
@ -104,7 +139,7 @@ class Bundle extends BundleBase {
|
|||
return source;
|
||||
}
|
||||
|
||||
getUnbundle(type) {
|
||||
getUnbundle() {
|
||||
this.assertFinalized();
|
||||
if (!this._ramBundle) {
|
||||
const modules = this.getModules().slice();
|
||||
|
@ -122,7 +157,7 @@ class Bundle extends BundleBase {
|
|||
groups = createGroups(ramGroups || [], lazyModules);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -166,7 +201,7 @@ class Bundle extends BundleBase {
|
|||
return result;
|
||||
}
|
||||
|
||||
getSourceMap(options) {
|
||||
getSourceMap(options: {excludeSource?: boolean}) {
|
||||
super.assertFinalized();
|
||||
|
||||
if (this._shouldCombineSourceMaps) {
|
||||
|
@ -182,12 +217,14 @@ class Bundle extends BundleBase {
|
|||
names: [],
|
||||
mappings: mappings,
|
||||
sourcesContent: options.excludeSource
|
||||
? [] : modules.map(module => module.sourceCode)
|
||||
? [] : modules.map(module => module.sourceCode),
|
||||
};
|
||||
return map;
|
||||
}
|
||||
|
||||
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');
|
||||
return eTag;
|
||||
}
|
||||
|
@ -254,6 +291,7 @@ class Bundle extends BundleBase {
|
|||
|
||||
getDebugInfo() {
|
||||
return [
|
||||
/* $FlowFixMe: this is unsound as the module ID could be unset. */
|
||||
'<div><h3>Main Module:</h3> ' + super.getMainModuleId() + '</div>',
|
||||
'<style>',
|
||||
'pre.collapsed {',
|
||||
|
@ -274,7 +312,7 @@ class Bundle extends BundleBase {
|
|||
].join('\n');
|
||||
}
|
||||
|
||||
setRamGroups(ramGroups) {
|
||||
setRamGroups(ramGroups: Array<string>) {
|
||||
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);
|
||||
for (const [, {path}] of moduleTransport.meta.dependencyPairs || []) {
|
||||
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
|
||||
// by path or (numeric) module id;
|
||||
const byPath = new Map();
|
||||
|
@ -400,12 +438,14 @@ function createGroups(ramGroups, lazyModules) {
|
|||
const doubles = filter(all, ([, parents]) => parents.length > 1);
|
||||
for (const [moduleId, parents] of doubles) {
|
||||
// remove them from their groups
|
||||
/* $FlowFixMe: this assumes the element exists. */
|
||||
parents.forEach(p => result.get(p).delete(moduleId));
|
||||
|
||||
// print a warning for each removed module
|
||||
const parentNames = parents.map(byId.get, byId);
|
||||
const lastName = parentNames.pop();
|
||||
console.warn(
|
||||
/* $FlowFixMe: this assumes the element exists. */
|
||||
`Module ${byId.get(moduleId)} belongs to groups ${
|
||||
parentNames.join(', ')}, and ${lastName
|
||||
}. Removing it from all groups.`
|
||||
|
|
|
@ -12,11 +12,22 @@
|
|||
|
||||
const ModuleTransport = require('../lib/ModuleTransport');
|
||||
|
||||
export type FinalizeOptions = {
|
||||
allowUpdates?: boolean,
|
||||
runBeforeMainModule?: Array<mixed>,
|
||||
runMainModule?: boolean,
|
||||
};
|
||||
|
||||
export type GetSourceOptions = {
|
||||
inlineSourceMap: boolean,
|
||||
dev: boolean,
|
||||
};
|
||||
|
||||
class BundleBase {
|
||||
|
||||
_assets: Array<mixed>;
|
||||
_finalized: boolean;
|
||||
_mainModuleId: mixed | void;
|
||||
_mainModuleId: string | void;
|
||||
_modules: Array<ModuleTransport>;
|
||||
_source: ?string;
|
||||
|
||||
|
@ -35,7 +46,7 @@ class BundleBase {
|
|||
return this._mainModuleId;
|
||||
}
|
||||
|
||||
setMainModuleId(moduleId: mixed) {
|
||||
setMainModuleId(moduleId: string) {
|
||||
this._mainModuleId = moduleId;
|
||||
}
|
||||
|
||||
|
@ -67,7 +78,7 @@ class BundleBase {
|
|||
this._assets.push(asset);
|
||||
}
|
||||
|
||||
finalize(options: {allowUpdates?: boolean}) {
|
||||
finalize(options: FinalizeOptions) {
|
||||
if (!options.allowUpdates) {
|
||||
Object.freeze(this._modules);
|
||||
Object.freeze(this._assets);
|
||||
|
@ -76,7 +87,7 @@ class BundleBase {
|
|||
this._finalized = true;
|
||||
}
|
||||
|
||||
getSource() {
|
||||
getSource(options: GetSourceOptions) {
|
||||
this.assertFinalized();
|
||||
|
||||
if (this._source) {
|
||||
|
@ -97,9 +108,9 @@ class BundleBase {
|
|||
}
|
||||
}
|
||||
|
||||
setRamGroups() {}
|
||||
setRamGroups(ramGroups: Array<string>) {}
|
||||
|
||||
toJSON() {
|
||||
toJSON(): mixed {
|
||||
return {
|
||||
modules: this._modules,
|
||||
assets: this._assets,
|
||||
|
|
Loading…
Reference in New Issue