mirror of https://github.com/status-im/metro.git
Remove ModuleTransport/ResolutionResponse modules and lots of logic from Resolver/ResolutionRequest
Reviewed By: davidaurelio Differential Revision: D6284728 fbshipit-source-id: 53d27cd65b8c96ed6d6872eb16a9b5d1e14db85e
This commit is contained in:
parent
860dcc4867
commit
e1b5fe79fa
|
@ -18,7 +18,6 @@ const debug = require('debug')('Metro:Bundler');
|
|||
const fs = require('fs');
|
||||
const Transformer = require('../JSTransformer');
|
||||
const Resolver = require('../Resolver');
|
||||
const ModuleTransport = require('../lib/ModuleTransport');
|
||||
const path = require('path');
|
||||
const defaults = require('../defaults');
|
||||
const createModuleIdFactory = require('../lib/createModuleIdFactory');
|
||||
|
@ -240,12 +239,6 @@ class Bundler {
|
|||
);
|
||||
}
|
||||
|
||||
getModuleForPath(entryFile: string): Promise<Module> {
|
||||
return this._resolverPromise.then(resolver =>
|
||||
resolver.getModuleForPath(entryFile),
|
||||
);
|
||||
}
|
||||
|
||||
async generateAssetObjAndCode(
|
||||
module: Module,
|
||||
assetPlugins: Array<string>,
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
const Generator = require('./Generator');
|
||||
const SourceMap = require('source-map');
|
||||
|
||||
import type ModuleTransport from '../../lib/ModuleTransport';
|
||||
import type {MappingsMap, RawMappings} from '../../lib/SourceMap';
|
||||
import type {RawMapping as BabelRawMapping} from 'babel-generator';
|
||||
|
||||
|
|
|
@ -322,20 +322,22 @@ class DeltaTransformer extends EventEmitter {
|
|||
}
|
||||
|
||||
async _getAppend(dependencyEdges: DependencyEdges): Promise<DeltaEntries> {
|
||||
const dependencyGraph = this._resolver.getDependencyGraph();
|
||||
|
||||
// Get the absolute path of the entry file, in order to be able to get the
|
||||
// actual correspondant module (and its moduleId) to be able to add the
|
||||
// correct require(); call at the very end of the bundle.
|
||||
const absPath = this._resolver
|
||||
.getDependencyGraph()
|
||||
.getAbsolutePath(this._bundleOptions.entryFile);
|
||||
const entryPointModule = this._resolver.getModuleForPath(absPath);
|
||||
const absPath = dependencyGraph.getAbsolutePath(
|
||||
this._bundleOptions.entryFile,
|
||||
);
|
||||
const entryPointModule = dependencyGraph.getModuleForPath(absPath);
|
||||
|
||||
// First, get the modules correspondant to all the module names defined in
|
||||
// the `runBeforeMainModule` config variable. Then, append the entry point
|
||||
// module so the last thing that gets required is the entry point.
|
||||
const append = new Map(
|
||||
this._bundleOptions.runBeforeMainModule
|
||||
.map(path => this._resolver.getModuleForPath(path))
|
||||
.map(path => dependencyGraph.getModuleForPath(path))
|
||||
.concat(entryPointModule)
|
||||
.filter(module => dependencyEdges.has(module.path))
|
||||
.map(this._getModuleId)
|
||||
|
|
|
@ -96,94 +96,6 @@ describe('Resolver', function() {
|
|||
return polyfill;
|
||||
}
|
||||
|
||||
describe('getDependencies', function() {
|
||||
it('forwards transform options to the dependency graph', function() {
|
||||
expect.assertions(1);
|
||||
const transformOptions = {arbitrary: 'options'};
|
||||
const platform = 'ios';
|
||||
const entry = '/root/index.js';
|
||||
|
||||
DependencyGraph.prototype.getDependencies.mockImplementation(() =>
|
||||
Promise.reject(),
|
||||
);
|
||||
return Resolver.load({projectRoot: '/root'})
|
||||
.then(r => r.getDependencies(entry, {platform}, transformOptions))
|
||||
.catch(() => {
|
||||
expect(DependencyGraph.prototype.getDependencies).toBeCalledWith({
|
||||
entryPath: entry,
|
||||
platform,
|
||||
options: transformOptions,
|
||||
recursive: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('passes custom platforms to the dependency graph', function() {
|
||||
expect.assertions(1);
|
||||
return Resolver.load({
|
||||
projectRoot: '/root',
|
||||
platforms: ['ios', 'windows', 'vr'],
|
||||
}).then(() => {
|
||||
const platforms = DependencyGraph.mock.calls[0][0].platforms;
|
||||
expect(Array.from(platforms)).toEqual(['ios', 'windows', 'vr']);
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass in more polyfills when prependPolyfills is true', function() {
|
||||
expect.assertions(3);
|
||||
|
||||
var module = createModule('index');
|
||||
var deps = [module];
|
||||
|
||||
var depResolverPromise = Resolver.load({
|
||||
getPolyfills: () => ['custom-polyfill-1', 'custom-polyfill-2'],
|
||||
projectRoot: '/root',
|
||||
});
|
||||
|
||||
DependencyGraph.prototype.getDependencies.mockImplementation(function() {
|
||||
return Promise.resolve(
|
||||
new ResolutionResponseMock({
|
||||
dependencies: deps,
|
||||
mainModuleId: 'index',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
return depResolverPromise
|
||||
.then(r =>
|
||||
r.getDependencies(
|
||||
'/root/index.js',
|
||||
{dev: false, prependPolyfills: true},
|
||||
undefined,
|
||||
undefined,
|
||||
createGetModuleId(),
|
||||
),
|
||||
)
|
||||
.then(result => {
|
||||
expect(result.mainModuleId).toEqual('index');
|
||||
const calls = DependencyGraph.prototype.createPolyfill.mock.calls;
|
||||
const callPolyfill1 = calls[result.dependencies.length - 3];
|
||||
const callPolyfill2 = calls[result.dependencies.length - 2];
|
||||
|
||||
expect(callPolyfill1).toEqual([
|
||||
{
|
||||
file: 'custom-polyfill-1',
|
||||
id: 'custom-polyfill-1',
|
||||
dependencies: [],
|
||||
},
|
||||
]);
|
||||
|
||||
expect(callPolyfill2).toEqual([
|
||||
{
|
||||
file: 'custom-polyfill-2',
|
||||
id: 'custom-polyfill-2',
|
||||
dependencies: ['custom-polyfill-1'],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrapModule', function() {
|
||||
let depResolver;
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -23,7 +23,6 @@ const {
|
|||
} = require('../Bundler/source-map');
|
||||
const pathJoin = require('path').join;
|
||||
|
||||
import type ResolutionResponse from '../node-haste/DependencyGraph/ResolutionResponse';
|
||||
import type Module, {HasteImpl, TransformCode} from '../node-haste/Module';
|
||||
import type {MappingsMap, CompactRawMappings} from '../lib/SourceMap';
|
||||
import type {PostMinifyProcess} from '../Bundler';
|
||||
|
@ -107,52 +106,6 @@ class Resolver {
|
|||
return new Resolver(opts, depGraph);
|
||||
}
|
||||
|
||||
getShallowDependencies(
|
||||
entryFile: string,
|
||||
transformOptions: JSTransformerOptions,
|
||||
): Promise<Array<string>> {
|
||||
return this._depGraph.getShallowDependencies(entryFile, transformOptions);
|
||||
}
|
||||
|
||||
getModuleForPath(entryFile: string): Module {
|
||||
return this._depGraph.getModuleForPath(entryFile);
|
||||
}
|
||||
|
||||
async getDependencies<T: ContainsTransformerOptions>(
|
||||
entryPath: string,
|
||||
options: {
|
||||
platform: ?string,
|
||||
recursive?: boolean,
|
||||
prependPolyfills: boolean,
|
||||
},
|
||||
bundlingOptions: T,
|
||||
onProgress?: ?(finishedModules: number, totalModules: number) => mixed,
|
||||
getModuleId: mixed,
|
||||
): Promise<ResolutionResponse<Module, T>> {
|
||||
const {platform, recursive = true, prependPolyfills} = options;
|
||||
|
||||
const resolutionResponse: ResolutionResponse<
|
||||
Module,
|
||||
T,
|
||||
> = await this._depGraph.getDependencies({
|
||||
entryPath,
|
||||
platform,
|
||||
options: bundlingOptions,
|
||||
recursive,
|
||||
onProgress,
|
||||
});
|
||||
|
||||
if (prependPolyfills) {
|
||||
this._getPolyfillDependencies(platform)
|
||||
.reverse()
|
||||
.forEach(polyfill => resolutionResponse.prependDependency(polyfill));
|
||||
}
|
||||
|
||||
/* $FlowFixMe: monkey patching */
|
||||
resolutionResponse.getModuleId = getModuleId;
|
||||
return resolutionResponse.finalize();
|
||||
}
|
||||
|
||||
getModuleSystemDependencies({dev = true}: {dev?: boolean}): Array<Module> {
|
||||
const prelude = dev
|
||||
? pathJoin(__dirname, 'polyfills/prelude_dev.js')
|
||||
|
@ -169,20 +122,6 @@ class Resolver {
|
|||
);
|
||||
}
|
||||
|
||||
_getPolyfillDependencies(platform: ?string): Array<Module> {
|
||||
const polyfillModuleNames = this._getPolyfills({platform}).concat(
|
||||
this._polyfillModuleNames,
|
||||
);
|
||||
|
||||
return polyfillModuleNames.map((polyfillModuleName, idx) =>
|
||||
this._depGraph.createPolyfill({
|
||||
file: polyfillModuleName,
|
||||
id: polyfillModuleName,
|
||||
dependencies: polyfillModuleNames.slice(0, idx),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
resolveRequires(
|
||||
module: Module,
|
||||
getModuleId: ({path: string}) => number,
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {RawMapping} from '../Bundler/source-map';
|
||||
import type Module from '../node-haste/Module';
|
||||
import type {SourceMap} from './SourceMap';
|
||||
|
||||
export type SourceMapOrMappings = SourceMap | Array<RawMapping>;
|
||||
|
||||
type Metadata = {
|
||||
dependencies?: ?Array<string>,
|
||||
dependencyPairs?: Array<[string, Module]>,
|
||||
preloaded: ?boolean,
|
||||
dependencyOffsets?: ?Array<number>,
|
||||
};
|
||||
|
||||
class ModuleTransport {
|
||||
name: string;
|
||||
id: number;
|
||||
code: string;
|
||||
sourceCode: string;
|
||||
sourcePath: string;
|
||||
virtual: boolean;
|
||||
meta: ?Metadata;
|
||||
polyfill: boolean;
|
||||
map: ?SourceMapOrMappings;
|
||||
|
||||
constructor(data: {
|
||||
name: string,
|
||||
id: number,
|
||||
code: string,
|
||||
sourceCode: string,
|
||||
sourcePath: string,
|
||||
virtual?: boolean,
|
||||
meta?: ?Metadata,
|
||||
polyfill?: boolean,
|
||||
map?: ?SourceMapOrMappings,
|
||||
}) {
|
||||
this.name = data.name;
|
||||
|
||||
assertExists(data, 'id');
|
||||
this.id = data.id;
|
||||
|
||||
assertExists(data, 'code');
|
||||
this.code = data.code;
|
||||
|
||||
assertExists(data, 'sourceCode');
|
||||
this.sourceCode = data.sourceCode;
|
||||
|
||||
assertExists(data, 'sourcePath');
|
||||
this.sourcePath = data.sourcePath;
|
||||
|
||||
this.virtual = !!data.virtual;
|
||||
this.meta = data.meta;
|
||||
this.polyfill = !!data.polyfill;
|
||||
this.map = data.map;
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ModuleTransport;
|
||||
|
||||
function assertExists(obj, field) {
|
||||
if (obj[field] == null) {
|
||||
throw new Error('Modules must have `' + field + '`');
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ const JestHasteMap = require('jest-haste-map');
|
|||
const Module = require('./Module');
|
||||
const ModuleCache = require('./ModuleCache');
|
||||
const ResolutionRequest = require('./DependencyGraph/ResolutionRequest');
|
||||
const ResolutionResponse = require('./DependencyGraph/ResolutionResponse');
|
||||
|
||||
const fs = require('fs');
|
||||
const isAbsolutePath = require('absolute-path');
|
||||
|
@ -233,10 +232,6 @@ class DependencyGraph extends EventEmitter {
|
|||
return this._moduleCache.getModule(entryFile);
|
||||
}
|
||||
|
||||
getAllModules() {
|
||||
return Promise.resolve(this._moduleCache.getAllModules());
|
||||
}
|
||||
|
||||
resolveDependency(
|
||||
fromModule: Module,
|
||||
toModuleName: string,
|
||||
|
@ -253,45 +248,6 @@ class DependencyGraph extends EventEmitter {
|
|||
return req.resolveDependency(fromModule, toModuleName);
|
||||
}
|
||||
|
||||
getDependencies<T: {+transformer: JSTransformerOptions}>({
|
||||
entryPath,
|
||||
options,
|
||||
platform,
|
||||
onProgress,
|
||||
recursive = true,
|
||||
}: {
|
||||
entryPath: string,
|
||||
options: T,
|
||||
platform: ?string,
|
||||
onProgress?: ?(finishedModules: number, totalModules: number) => mixed,
|
||||
recursive: boolean,
|
||||
}): Promise<ResolutionResponse<Module, T>> {
|
||||
platform = this._getRequestPlatform(entryPath, platform);
|
||||
const absPath = this.getAbsolutePath(entryPath);
|
||||
const req = new ResolutionRequest({
|
||||
moduleResolver: this._moduleResolver,
|
||||
entryPath: absPath,
|
||||
helpers: this._helpers,
|
||||
platform: platform != null ? platform : null,
|
||||
moduleCache: this._moduleCache,
|
||||
});
|
||||
|
||||
const response = new ResolutionResponse(options);
|
||||
|
||||
return req
|
||||
.getOrderedDependencies({
|
||||
response,
|
||||
transformOptions: options.transformer,
|
||||
onProgress,
|
||||
recursive,
|
||||
})
|
||||
.then(() => response);
|
||||
}
|
||||
|
||||
matchFilesByPattern(pattern: RegExp) {
|
||||
return Promise.resolve(this._hasteFS.matchFiles(pattern));
|
||||
}
|
||||
|
||||
_doesFileExist = (filePath: string): boolean => {
|
||||
return this._hasteFS.exists(filePath);
|
||||
};
|
||||
|
|
|
@ -12,23 +12,19 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const AsyncTaskGroup = require('../lib/AsyncTaskGroup');
|
||||
const MapWithDefaults = require('../lib/MapWithDefaults');
|
||||
const ModuleResolution = require('./ModuleResolution');
|
||||
|
||||
const debug = require('debug')('Metro:DependencyGraph');
|
||||
const isAbsolutePath = require('absolute-path');
|
||||
const path = require('path');
|
||||
|
||||
const {DuplicateHasteCandidatesError} = require('jest-haste-map').ModuleMap;
|
||||
|
||||
import type DependencyGraphHelpers from './DependencyGraphHelpers';
|
||||
import type ResolutionResponse from './ResolutionResponse';
|
||||
import type {Options as TransformWorkerOptions} from '../../JSTransformer/worker';
|
||||
import type {ReadResult, CachedReadResult} from '../Module';
|
||||
import type {ModuleResolver} from './ModuleResolution';
|
||||
|
||||
const {UnableToResolveError, isRelativeImport} = ModuleResolution;
|
||||
const {isRelativeImport} = ModuleResolution;
|
||||
|
||||
export type Packageish = {
|
||||
isHaste(): boolean,
|
||||
|
@ -126,239 +122,6 @@ class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
|
|||
}
|
||||
}
|
||||
|
||||
resolveModuleDependencies(
|
||||
module: TModule,
|
||||
dependencyNames: $ReadOnlyArray<string>,
|
||||
): [$ReadOnlyArray<string>, $ReadOnlyArray<TModule>] {
|
||||
const dependencies = dependencyNames.map(name =>
|
||||
this.resolveDependency(module, name),
|
||||
);
|
||||
return [dependencyNames, dependencies];
|
||||
}
|
||||
|
||||
getOrderedDependencies<T>({
|
||||
response,
|
||||
transformOptions,
|
||||
onProgress,
|
||||
recursive = true,
|
||||
}: {
|
||||
response: ResolutionResponse<TModule, T>,
|
||||
transformOptions: TransformWorkerOptions,
|
||||
onProgress?: ?(finishedModules: number, totalModules: number) => mixed,
|
||||
recursive: boolean,
|
||||
}): Promise<void> {
|
||||
const entry = this._options.moduleCache.getModule(this._options.entryPath);
|
||||
|
||||
response.pushDependency(entry);
|
||||
let totalModules = 1;
|
||||
let finishedModules = 0;
|
||||
|
||||
let preprocessedModuleCount = 1;
|
||||
if (recursive) {
|
||||
this._preprocessPotentialDependencies(transformOptions, entry, count => {
|
||||
if (count + 1 <= preprocessedModuleCount) {
|
||||
return;
|
||||
}
|
||||
preprocessedModuleCount = count + 1;
|
||||
if (onProgress != null) {
|
||||
onProgress(finishedModules, preprocessedModuleCount);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const resolveDependencies = (module: TModule) =>
|
||||
Promise.resolve().then(() => {
|
||||
const cached = module.readCached(transformOptions);
|
||||
if (cached.result != null) {
|
||||
return this.resolveModuleDependencies(
|
||||
module,
|
||||
cached.result.dependencies,
|
||||
);
|
||||
}
|
||||
return module
|
||||
.readFresh(transformOptions)
|
||||
.then(({dependencies}) =>
|
||||
this.resolveModuleDependencies(module, dependencies),
|
||||
);
|
||||
});
|
||||
|
||||
const collectedDependencies: MapWithDefaults<
|
||||
TModule,
|
||||
Promise<Array<TModule>>,
|
||||
> = new MapWithDefaults(module => collect(module));
|
||||
const crawlDependencies = (mod, [depNames, dependencies]) => {
|
||||
const filteredPairs = [];
|
||||
|
||||
dependencies.forEach((modDep, i) => {
|
||||
const name = depNames[i];
|
||||
if (modDep == null) {
|
||||
debug(
|
||||
'WARNING: Cannot find required module `%s` from module `%s`',
|
||||
name,
|
||||
mod.path,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return filteredPairs.push([name, modDep]);
|
||||
});
|
||||
|
||||
response.setResolvedDependencyPairs(mod, filteredPairs);
|
||||
|
||||
const dependencyModules = filteredPairs.map(([, m]) => m);
|
||||
const newDependencies = dependencyModules.filter(
|
||||
m => !collectedDependencies.has(m),
|
||||
);
|
||||
|
||||
if (onProgress) {
|
||||
finishedModules += 1;
|
||||
totalModules += newDependencies.length;
|
||||
onProgress(
|
||||
finishedModules,
|
||||
Math.max(totalModules, preprocessedModuleCount),
|
||||
);
|
||||
}
|
||||
|
||||
if (recursive) {
|
||||
// doesn't block the return of this function invocation, but defers
|
||||
// the resulution of collectionsInProgress.done.then(...)
|
||||
dependencyModules.forEach(dependency =>
|
||||
collectedDependencies.get(dependency),
|
||||
);
|
||||
}
|
||||
return dependencyModules;
|
||||
};
|
||||
|
||||
const collectionsInProgress = new AsyncTaskGroup();
|
||||
function collect(module) {
|
||||
collectionsInProgress.start(module);
|
||||
const result = resolveDependencies(module).then(deps =>
|
||||
crawlDependencies(module, deps),
|
||||
);
|
||||
const end = () => collectionsInProgress.end(module);
|
||||
result.then(end, end);
|
||||
return result;
|
||||
}
|
||||
|
||||
function resolveKeyWithPromise(
|
||||
[key: TModule, promise: Promise<Array<TModule>>],
|
||||
): Promise<[TModule, Array<TModule>]> {
|
||||
return promise.then(value => [key, value]);
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
// kicks off recursive dependency discovery, but doesn't block until it's
|
||||
// done
|
||||
collectedDependencies.get(entry),
|
||||
|
||||
// resolves when there are no more modules resolving dependencies
|
||||
collectionsInProgress.done,
|
||||
])
|
||||
.then(([rootDependencies]) => {
|
||||
return Promise.all(
|
||||
Array.from(collectedDependencies, resolveKeyWithPromise),
|
||||
).then(moduleToDependenciesPairs => [
|
||||
rootDependencies,
|
||||
new MapWithDefaults(() => [], moduleToDependenciesPairs),
|
||||
]);
|
||||
})
|
||||
.then(([rootDependencies, moduleDependencies]) => {
|
||||
// serialize dependencies, and make sure that every single one is only
|
||||
// included once
|
||||
const seen = new Set([entry]);
|
||||
function traverse(dependencies) {
|
||||
dependencies.forEach(dependency => {
|
||||
if (seen.has(dependency)) {
|
||||
return;
|
||||
}
|
||||
|
||||
seen.add(dependency);
|
||||
response.pushDependency(dependency);
|
||||
traverse(moduleDependencies.get(dependency));
|
||||
});
|
||||
}
|
||||
|
||||
traverse(rootDependencies);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This synchronously look at all the specified modules and recursively kicks
|
||||
* off global cache fetching or transforming (via `readFresh`). This is a hack
|
||||
* that workaround the current structure, because we could do better. First
|
||||
* off, the algorithm that resolves dependencies recursively should be
|
||||
* synchronous itself until it cannot progress anymore (and needs to call
|
||||
* `readFresh`), so that this algo would be integrated into it.
|
||||
*/
|
||||
_preprocessPotentialDependencies(
|
||||
transformOptions: TransformWorkerOptions,
|
||||
module: TModule,
|
||||
onProgress: (moduleCount: number) => mixed,
|
||||
): void {
|
||||
const visitedModulePaths = new Set();
|
||||
const pendingBatches = [
|
||||
this.preprocessModule(transformOptions, module, visitedModulePaths),
|
||||
];
|
||||
onProgress(visitedModulePaths.size);
|
||||
while (pendingBatches.length > 0) {
|
||||
const dependencyModules = pendingBatches.pop();
|
||||
while (dependencyModules.length > 0) {
|
||||
const dependencyModule = dependencyModules.pop();
|
||||
const deps = this.preprocessModule(
|
||||
transformOptions,
|
||||
dependencyModule,
|
||||
visitedModulePaths,
|
||||
);
|
||||
pendingBatches.push(deps);
|
||||
onProgress(visitedModulePaths.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preprocessModule(
|
||||
transformOptions: TransformWorkerOptions,
|
||||
module: TModule,
|
||||
visitedModulePaths: Set<string>,
|
||||
): Array<TModule> {
|
||||
const cached = module.readCached(transformOptions);
|
||||
if (cached.result == null) {
|
||||
module.readFresh(transformOptions).catch(error => {
|
||||
/* ignore errors, they'll be handled later if the dependency is actually
|
||||
* not obsolete, and required from somewhere */
|
||||
});
|
||||
}
|
||||
const dependencies =
|
||||
cached.result != null
|
||||
? cached.result.dependencies
|
||||
: cached.outdatedDependencies;
|
||||
return this.tryResolveModuleDependencies(
|
||||
module,
|
||||
dependencies,
|
||||
visitedModulePaths,
|
||||
);
|
||||
}
|
||||
|
||||
tryResolveModuleDependencies(
|
||||
module: TModule,
|
||||
dependencyNames: $ReadOnlyArray<string>,
|
||||
visitedModulePaths: Set<string>,
|
||||
): Array<TModule> {
|
||||
const result = [];
|
||||
for (let i = 0; i < dependencyNames.length; ++i) {
|
||||
try {
|
||||
const depModule = this.resolveDependency(module, dependencyNames[i]);
|
||||
if (!visitedModulePaths.has(depModule.path)) {
|
||||
visitedModulePaths.add(depModule.path);
|
||||
result.push(depModule);
|
||||
}
|
||||
} catch (error) {
|
||||
if (!(error instanceof UnableToResolveError)) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
_resetResolutionCache() {
|
||||
this._immediateResolutionCache = Object.create(null);
|
||||
}
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const NO_OPTIONS = {};
|
||||
|
||||
class ResolutionResponse<TModule: {hash(): string}, TOptions> {
|
||||
dependencies: Array<TModule>;
|
||||
mainModuleId: ?(number | string);
|
||||
mocks: mixed;
|
||||
numPrependedDependencies: number;
|
||||
options: TOptions;
|
||||
|
||||
// This is monkey-patched from Resolver.
|
||||
getModuleId: ?() => number;
|
||||
|
||||
_mappings: {[hash: string]: Array<[string, TModule]>, __proto__: null};
|
||||
_finalized: boolean;
|
||||
_mainModule: ?TModule;
|
||||
|
||||
constructor(options: TOptions) {
|
||||
this.dependencies = [];
|
||||
this.mainModuleId = null;
|
||||
this.mocks = null;
|
||||
this.numPrependedDependencies = 0;
|
||||
this.options = options;
|
||||
this._mappings = Object.create(null);
|
||||
this._finalized = false;
|
||||
}
|
||||
|
||||
copy(properties: {
|
||||
dependencies?: Array<TModule>,
|
||||
mainModuleId?: number,
|
||||
mocks?: mixed,
|
||||
}): ResolutionResponse<TModule, TOptions> {
|
||||
const {
|
||||
dependencies = this.dependencies,
|
||||
mainModuleId = this.mainModuleId,
|
||||
mocks = this.mocks,
|
||||
} = properties;
|
||||
|
||||
const numPrependedDependencies =
|
||||
dependencies === this.dependencies ? this.numPrependedDependencies : 0;
|
||||
|
||||
/* $FlowFixMe: Flow doesn't like Object.assign on class-made objects. */
|
||||
return Object.assign(new this.constructor(this.options), this, {
|
||||
dependencies,
|
||||
mainModuleId,
|
||||
mocks,
|
||||
numPrependedDependencies,
|
||||
});
|
||||
}
|
||||
|
||||
_assertNotFinalized() {
|
||||
if (this._finalized) {
|
||||
throw new Error('Attempted to mutate finalized response.');
|
||||
}
|
||||
}
|
||||
|
||||
_assertFinalized() {
|
||||
if (!this._finalized) {
|
||||
throw new Error('Attempted to access unfinalized response.');
|
||||
}
|
||||
}
|
||||
|
||||
finalize(): Promise<this> {
|
||||
return Promise.resolve().then(() => {
|
||||
/* $FlowFixMe: _mainModule is not initialized in the constructor. */
|
||||
this.mainModuleId = this._mainModule.getName();
|
||||
this._finalized = true;
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
pushDependency(module: TModule) {
|
||||
this._assertNotFinalized();
|
||||
if (this.dependencies.length === 0) {
|
||||
this._mainModule = module;
|
||||
}
|
||||
|
||||
this.dependencies.push(module);
|
||||
}
|
||||
|
||||
prependDependency(module: TModule) {
|
||||
this._assertNotFinalized();
|
||||
this.dependencies.unshift(module);
|
||||
this.numPrependedDependencies += 1;
|
||||
}
|
||||
|
||||
setResolvedDependencyPairs(
|
||||
module: TModule,
|
||||
pairs: Array<[string, TModule]>,
|
||||
options: {ignoreFinalized?: boolean} = NO_OPTIONS,
|
||||
) {
|
||||
if (!options.ignoreFinalized) {
|
||||
this._assertNotFinalized();
|
||||
}
|
||||
const hash = module.hash();
|
||||
if (this._mappings[hash] == null) {
|
||||
this._mappings[hash] = pairs;
|
||||
}
|
||||
}
|
||||
|
||||
setMocks(mocks: mixed) {
|
||||
this.mocks = mocks;
|
||||
}
|
||||
|
||||
getResolvedDependencyPairs(
|
||||
module: TModule,
|
||||
): $ReadOnlyArray<[string, TModule]> {
|
||||
this._assertFinalized();
|
||||
return this._mappings[module.hash()] || [];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ResolutionResponse;
|
|
@ -1,37 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = class AsyncTaskGroup<TTaskHandle> {
|
||||
_runningTasks: Set<TTaskHandle>;
|
||||
_resolve: ?() => void;
|
||||
done: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
this._runningTasks = new Set();
|
||||
this._resolve = null;
|
||||
this.done = new Promise(resolve => (this._resolve = resolve));
|
||||
}
|
||||
|
||||
start(taskHandle: TTaskHandle) {
|
||||
this._runningTasks.add(taskHandle);
|
||||
}
|
||||
|
||||
end(taskHandle: TTaskHandle) {
|
||||
const runningTasks = this._runningTasks;
|
||||
if (runningTasks.delete(taskHandle) && runningTasks.size === 0) {
|
||||
/* $FlowFixMe: could be null */
|
||||
this._resolve();
|
||||
}
|
||||
}
|
||||
};
|
|
@ -10,7 +10,11 @@
|
|||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
import type {SourceMapOrMappings} from '../lib/ModuleTransport';
|
||||
|
||||
import type {RawMapping} from '../Bundler/source-map';
|
||||
import type {SourceMap} from '../lib/SourceMap';
|
||||
|
||||
type SourceMapOrMappings = SourceMap | Array<RawMapping>;
|
||||
|
||||
export type ModuleGroups = {|
|
||||
groups: Map<number, Set<number>>,
|
||||
|
|
Loading…
Reference in New Issue