metro: ModuleResolution: extract resolveModulePath

Summary: Continue cleaning up the resolution algo. By removing the class completely as well as the `TModule` type, and providing options via the `context`, we'll be able to identify clearly the inputs of the resolution algorithm, and reuse it eventually for Jest. This changeset extract one more function in this fashion. Next steps: extract the rest of the stateful code into functions, or into `ResolutionRequest`.

Reviewed By: davidaurelio

Differential Revision: D6937569

fbshipit-source-id: bab0bcd280be32a11f23174b0591dd0cc7dee7ab
This commit is contained in:
Jean Lauliac 2018-02-08 10:08:41 -08:00 committed by Facebook Github Bot
parent 1498c4ba6b
commit 07a79853ef
1 changed files with 51 additions and 42 deletions

View File

@ -140,30 +140,6 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
return modulePath; return modulePath;
} }
_resolveModulePath(
fromModule: TModule,
toModuleName: string,
platform: string | null,
): Result<Resolution, Candidates> {
const modulePath = isAbsolutePath(toModuleName)
? resolveWindowsPath(toModuleName)
: path.join(path.dirname(fromModule.path), toModuleName);
const redirectedPath = this._redirectRequire(fromModule, modulePath);
if (redirectedPath === false) {
return resolvedAs({type: 'empty'});
}
const context = {
...this._options,
getPackageMainPath: this._getPackageMainPath,
};
const result = resolveFileOrDir(context, redirectedPath, platform);
if (result.type === 'resolved') {
return result;
}
return failedFor({type: 'modulePath', which: result.candidates});
}
resolveDependency( resolveDependency(
fromModule: TModule, fromModule: TModule,
toModuleName: string, toModuleName: string,
@ -221,8 +197,20 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
allowHaste: boolean, allowHaste: boolean,
platform: string | null, platform: string | null,
): Result<Resolution, Candidates> { ): Result<Resolution, Candidates> {
const context = {
...this._options,
getPackageMainPath: this._getPackageMainPath,
originModulePath: fromModule.path,
redirectModulePath: modulePath =>
this._redirectRequire(fromModule, modulePath),
resolveHasteModule: name =>
this._options.moduleMap.getModule(name, platform, true),
resolveHastePackage: name =>
this._options.moduleMap.getPackage(name, platform, true),
};
if (isRelativeImport(toModuleName) || isAbsolutePath(toModuleName)) { if (isRelativeImport(toModuleName) || isAbsolutePath(toModuleName)) {
return this._resolveModulePath(fromModule, toModuleName, platform); return resolveModulePath(context, toModuleName, platform);
} }
const realModuleName = this._redirectRequire(fromModule, toModuleName); const realModuleName = this._redirectRequire(fromModule, toModuleName);
// exclude // exclude
@ -239,29 +227,14 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
fromModule.path.indexOf(path.sep, fromModuleParentIdx), fromModule.path.indexOf(path.sep, fromModuleParentIdx),
); );
const absPath = path.join(fromModuleDir, realModuleName); const absPath = path.join(fromModuleDir, realModuleName);
return this._resolveModulePath(fromModule, absPath, platform); return resolveModulePath(context, absPath, platform);
} }
// At that point we only have module names that // At that point we only have module names that
// aren't relative paths nor absolute paths. // aren't relative paths nor absolute paths.
if (allowHaste) { if (allowHaste) {
const result = resolveHasteName( const result = resolveHasteName(
{ context,
...this._options,
resolveHasteModule: name =>
this._options.moduleMap.getModule(
name,
platform,
/* supportsNativePlatform */ true,
),
resolveHastePackage: name =>
this._options.moduleMap.getPackage(
name,
platform,
/* supportsNativePlatform */ true,
),
getPackageMainPath: this._getPackageMainPath,
},
normalizePath(realModuleName), normalizePath(realModuleName),
platform, platform,
); );
@ -336,6 +309,42 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
} }
} }
type ModulePathContext = FileOrDirContext & {
/**
* Full path of the module that is requiring or importing the module to be
* resolved.
*/
+originModulePath: string,
/**
* Lookup the module's closest `package.json` and process the redirects
* metadata. Return an absolute path to the resolved path.
*/
+redirectModulePath: (modulePath: string) => string | false,
};
/**
* Resolve any kind of module path, whether it's a file, a directory,
* a package name.
*/
function resolveModulePath(
context: ModulePathContext,
toModuleName: string,
platform: string | null,
): Result<Resolution, Candidates> {
const modulePath = isAbsolutePath(toModuleName)
? resolveWindowsPath(toModuleName)
: path.join(path.dirname(context.originModulePath), toModuleName);
const redirectedPath = context.redirectModulePath(modulePath);
if (redirectedPath === false) {
return resolvedAs({type: 'empty'});
}
const result = resolveFileOrDir(context, redirectedPath, platform);
if (result.type === 'resolved') {
return result;
}
return failedFor({type: 'modulePath', which: result.candidates});
}
type HasteContext = FileOrDirContext & { type HasteContext = FileOrDirContext & {
/** /**
* Given a name, this should return the full path to the file that provides * Given a name, this should return the full path to the file that provides