packager: ResolutionRequest: use moduleMap instead of hasteMap

Reviewed By: cpojer

Differential Revision: D4605535

fbshipit-source-id: bc8394eb296f3fbeda5d8f0f3c17790db8691033
This commit is contained in:
Jean Lauliac 2017-03-02 08:33:04 -08:00 committed by Facebook Github Bot
parent 17c6ca3484
commit 6e71c2e30a
5 changed files with 80 additions and 38 deletions

View File

@ -9,37 +9,55 @@
* @flow
*/
'use strict';
'use strict';
import type { // eslint-disable-line sort-requires
import type { // eslint-disable-line sort-requires
Extensions,
Path,
} from './node-haste.flow';
import type {
import type {
ResolveFn,
TransformedFile,
} from '../types.flow';
const DependencyGraphHelpers = require('../../node-haste/DependencyGraph/DependencyGraphHelpers');
const HasteFS = require('./HasteFS');
const HasteMap = require('../../node-haste/DependencyGraph/HasteMap');
const Module = require('./Module');
const ModuleCache = require('./ModuleCache');
const ResolutionRequest = require('../../node-haste/DependencyGraph/ResolutionRequest');
const DependencyGraphHelpers = require('../../node-haste/DependencyGraph/DependencyGraphHelpers');
const HasteFS = require('./HasteFS');
const HasteMap = require('../../node-haste/DependencyGraph/HasteMap');
const Module = require('./Module');
const ModuleCache = require('./ModuleCache');
const ResolutionRequest = require('../../node-haste/DependencyGraph/ResolutionRequest');
const defaults = require('../../../defaults');
const defaults = require('../../../defaults');
type ResolveOptions = {|
type ResolveOptions = {|
assetExts: Extensions,
extraNodeModules: {[id: string]: string},
transformedFiles: {[path: Path]: TransformedFile},
|};
const platforms = new Set(defaults.platforms);
const platforms = new Set(defaults.platforms);
exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
const {
/**
* We don't need to crawl the filesystem all over again so we just mock
* a jest-haste-map's ModuleMap instance. Eventually, though, we'll
* want to figure out how to reunify and get rid of `HasteMap`.
*/
function getFakeModuleMap(hasteMap: HasteMap) {
return {
getModule(name: string, platform_: string): ?string {
const module = hasteMap.getModule(name, platform_);
return module && module.type === 'Module' ? module.path : null;
},
getPackage(name: string, platform_: string): ?string {
const module = hasteMap.getModule(name, platform_);
return module && module.type === 'Package' ? module.path : null;
},
};
}
exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
const {
assetExts,
extraNodeModules,
transformedFiles,
@ -82,6 +100,7 @@
hasteMap,
helpers,
moduleCache,
moduleMap: getFakeModuleMap(hasteMap),
platform,
platforms,
preferNativePlatform: true,

View File

@ -91,7 +91,7 @@ class HasteMap extends EventEmitter {
});
}
getModule(name, platform = null) {
getModule(name, platform = null): Module {
const modulesMap = this._map[name];
if (modulesMap == null) {
return null;

View File

@ -17,27 +17,35 @@ const debug = require('debug')('RNP:DependencyGraph');
const util = require('util');
const path = require('path');
const realPath = require('path');
const invariant = require('fbjs/lib/invariant');
const isAbsolutePath = require('absolute-path');
const getAssetDataFromName = require('../lib/getAssetDataFromName');
import type {HasteFS} from '../types';
import type DependencyGraphHelpers from './DependencyGraphHelpers';
import type HasteMap from './HasteMap';
import type Module from '../Module';
import type ModuleCache from '../ModuleCache';
import type ResolutionResponse from './ResolutionResponse';
type DirExistsFn = (filePath: string) => boolean;
/**
* `jest-haste-map`'s interface for ModuleMap.
*/
export type ModuleMap = {
getModule(name: string, platform: string, supportsNativePlatform: boolean): ?string,
getPackage(name: string, platform: string, supportsNativePlatform: boolean): ?string,
};
type Options = {
dirExists: DirExistsFn,
entryPath: string,
extraNodeModules: ?Object,
hasteFS: HasteFS,
hasteMap: HasteMap,
helpers: DependencyGraphHelpers,
// TODO(cpojer): Remove 'any' type. This is used for ModuleGraph/node-haste
moduleCache: ModuleCache | any,
moduleMap: ModuleMap,
platform: string,
platforms: Set<string>,
preferNativePlatform: boolean,
@ -48,10 +56,10 @@ class ResolutionRequest {
_entryPath: string;
_extraNodeModules: ?Object;
_hasteFS: HasteFS;
_hasteMap: HasteMap;
_helpers: DependencyGraphHelpers;
_immediateResolutionCache: {[key: string]: string};
_immediateResolutionCache: {[key: string]: Module};
_moduleCache: ModuleCache;
_moduleMap: ModuleMap;
_platform: string;
_platforms: Set<string>;
_preferNativePlatform: boolean;
@ -62,9 +70,9 @@ class ResolutionRequest {
entryPath,
extraNodeModules,
hasteFS,
hasteMap,
helpers,
moduleCache,
moduleMap,
platform,
platforms,
preferNativePlatform,
@ -73,16 +81,16 @@ class ResolutionRequest {
this._entryPath = entryPath;
this._extraNodeModules = extraNodeModules;
this._hasteFS = hasteFS;
this._hasteMap = hasteMap;
this._helpers = helpers;
this._moduleCache = moduleCache;
this._moduleMap = moduleMap;
this._platform = platform;
this._platforms = platforms;
this._preferNativePlatform = preferNativePlatform;
this._resetResolutionCache();
}
_tryResolve(action: () => Promise<string>, secondaryAction: () => ?Promise<string>) {
_tryResolve<T>(action: () => Promise<T>, secondaryAction: () => ?Promise<T>): Promise<T> {
return action().catch(error => {
if (error.type !== 'UnableToResolveError') {
throw error;
@ -219,7 +227,7 @@ class ResolutionRequest {
});
}
_resolveHasteDependency(fromModule: Module, toModuleName: string) {
_resolveHasteDependency(fromModule: Module, toModuleName: string): Promise<Module> {
toModuleName = normalizePath(toModuleName);
let p = fromModule.getPackage();
@ -230,23 +238,34 @@ class ResolutionRequest {
}
return p.then(realModuleName => {
let dep = this._hasteMap.getModule(realModuleName, this._platform);
if (dep && dep.type === 'Module') {
return dep;
const modulePath = this._moduleMap
.getModule(realModuleName, this._platform, /* supportsNativePlatform */ true);
if (modulePath != null) {
const module = this._moduleCache.getModule(modulePath);
/* temporary until we strengthen the typing */
invariant(module.type === 'Module', 'expected Module type');
return module;
}
let packageName = realModuleName;
let packagePath;
while (packageName && packageName !== '.') {
dep = this._hasteMap.getModule(packageName, this._platform);
if (dep && dep.type === 'Package') {
packagePath = this._moduleMap
.getPackage(packageName, this._platform, /* supportsNativePlatform */ true);
if (packagePath != null) {
break;
}
packageName = path.dirname(packageName);
}
if (dep && dep.type === 'Package') {
if (packagePath != null) {
const package_ = this._moduleCache.getPackage(packagePath);
/* temporary until we strengthen the typing */
invariant(package_.type === 'Package', 'expected Package type');
const potentialModulePath = path.join(
dep.root,
package_.root,
path.relative(packageName, realModuleName)
);
return this._tryResolve(
@ -379,7 +398,7 @@ class ResolutionRequest {
}
}
_loadAsFile(potentialModulePath: string, fromModule: Module, toModule: string) {
_loadAsFile(potentialModulePath: string, fromModule: Module, toModule: string): Promise<Module> {
return Promise.resolve().then(() => {
if (this._helpers.isAssetFile(potentialModulePath)) {
let dirname = path.dirname(potentialModulePath);

View File

@ -78,7 +78,7 @@ class ModuleCache {
this._reporter = reporter;
}
getModule(filePath: string) {
getModule(filePath: string): Module {
if (!this._moduleCache[filePath]) {
this._moduleCache[filePath] = new Module({
cache: this._cache,

View File

@ -42,6 +42,7 @@ import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
import type GlobalTransformCache from '../lib/GlobalTransformCache';
import type {GetTransformCacheKey} from '../lib/TransformCache';
import type {Reporter} from '../lib/reporting';
import type {ModuleMap} from './DependencyGraph/ResolutionRequest';
import type {
Options as ModuleOptions,
TransformCode,
@ -81,6 +82,7 @@ class DependencyGraph extends EventEmitter {
_hasteMapError: ?Error;
_helpers: DependencyGraphHelpers;
_moduleCache: ModuleCache;
_moduleMap: ModuleMap;
_loading: Promise<void>;
@ -116,8 +118,9 @@ class DependencyGraph extends EventEmitter {
const initializingPackagerLogEntry =
log(createActionStartEntry('Initializing Packager'));
this._opts.reporter.update({type: 'dep_graph_loading'});
this._loading = this._haste.build().then(({hasteFS}) => {
this._loading = this._haste.build().then(({hasteFS, moduleMap}) => {
this._hasteFS = hasteFS;
this._moduleMap = moduleMap;
const hasteFSFiles = hasteFS.getAllFiles();
this._moduleCache = new ModuleCache({
@ -153,9 +156,10 @@ class DependencyGraph extends EventEmitter {
platforms: this._opts.platforms,
});
this._haste.on('change', ({eventsQueue, hasteFS: newHasteFS}) => {
this._hasteFS = newHasteFS;
eventsQueue.forEach(({type, filePath, stat}) =>
this._haste.on('change', event => {
this._hasteFS = event.hasteFS;
this._moduleMap = event.moduleMap;
event.eventsQueue.forEach(({type, filePath, stat}) =>
this.processFileChange(type, filePath, stat)
);
this.emit('change');
@ -189,7 +193,7 @@ class DependencyGraph extends EventEmitter {
* Returns a promise with the direct dependencies the module associated to
* the given entryPath has.
*/
getShallowDependencies(entryPath: string, transformOptions: mixed) {
getShallowDependencies(entryPath: string, transformOptions: TransformOptions) {
return this._moduleCache
.getModule(entryPath)
.getDependencies(transformOptions);
@ -237,9 +241,9 @@ class DependencyGraph extends EventEmitter {
entryPath: absPath,
extraNodeModules: this._opts.extraNodeModules,
hasteFS: this._hasteFS,
hasteMap: this._hasteMap,
helpers: this._helpers,
moduleCache: this._moduleCache,
moduleMap: this._moduleMap,
platform,
platforms: this._opts.platforms,
preferNativePlatform: this._opts.preferNativePlatform,