mirror of https://github.com/status-im/metro.git
ModuleResolution: switch _resolveHasteDependency to non-throwing resolveFileOrDir()
Summary: This changeset alters the Haste resolution logic to be in sync with the new refactored pieces (resolveFile, etc.) Next steps involve extracting this function outside of the class so as to reduce the surface API and promote composability. Reviewed By: cpojer Differential Revision: D6645302 fbshipit-source-id: 6ee00fb52025cc0d332e57f837b46e8323faf6f4
This commit is contained in:
parent
af1e6e3298
commit
7cab9a02c9
|
@ -126,23 +126,22 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|||
}
|
||||
|
||||
_resolveHasteDependency(
|
||||
fromModule: TModule,
|
||||
toModuleName: string,
|
||||
moduleName: string,
|
||||
platform: string | null,
|
||||
): TModule {
|
||||
): Result<FileResolution, void> {
|
||||
const modulePath = this._options.moduleMap.getModule(
|
||||
toModuleName,
|
||||
moduleName,
|
||||
platform,
|
||||
/* supportsNativePlatform */ true,
|
||||
);
|
||||
if (modulePath != null) {
|
||||
const module = this._options.moduleCache.getModule(modulePath);
|
||||
/* temporary until we strengthen the typing */
|
||||
invariant(module.type === 'Module', 'expected Module type');
|
||||
return module;
|
||||
return {
|
||||
type: 'resolved',
|
||||
resolution: {type: 'sourceFile', filePath: modulePath},
|
||||
};
|
||||
}
|
||||
|
||||
let packageName = toModuleName;
|
||||
let packageName = moduleName;
|
||||
let packageJsonPath;
|
||||
while (packageName && packageName !== '.') {
|
||||
packageJsonPath = this._options.moduleMap.getPackage(
|
||||
|
@ -156,32 +155,28 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|||
packageName = path.dirname(packageName);
|
||||
}
|
||||
|
||||
if (packageJsonPath != null) {
|
||||
// FIXME: `moduleCache.getModule` should return the directory path, not
|
||||
// the `package.json` file path, because the directory is what's really
|
||||
// representing the package.
|
||||
const packageDirPath = path.dirname(packageJsonPath);
|
||||
// FIXME: if we're trying to require the package main module (ie.
|
||||
// packageName === toModuleName), don't do as if it could be a
|
||||
// "FileOrDir", call directly the `resolvePackage` function! Otherwise we
|
||||
// might actually be grabbing a completely unrelated file.
|
||||
const potentialModulePath = path.join(
|
||||
packageDirPath,
|
||||
path.relative(packageName, toModuleName),
|
||||
);
|
||||
return this._loadAsFileOrDirOrThrow(
|
||||
potentialModulePath,
|
||||
fromModule,
|
||||
toModuleName,
|
||||
platform,
|
||||
);
|
||||
if (packageJsonPath == null) {
|
||||
return failedFor();
|
||||
}
|
||||
// FIXME: `moduleCache.getModule` should return the directory path, not
|
||||
// the `package.json` file path, because the directory is what's really
|
||||
// representing the package.
|
||||
const packageDirPath = path.dirname(packageJsonPath);
|
||||
|
||||
throw new UnableToResolveError(
|
||||
fromModule.path,
|
||||
toModuleName,
|
||||
'Unable to resolve dependency',
|
||||
);
|
||||
const pathInModule = moduleName.substring(packageName.length + 1);
|
||||
const potentialModulePath = path.join(packageDirPath, pathInModule);
|
||||
|
||||
const context = {
|
||||
...this._options,
|
||||
getPackageMainPath: this._getPackageMainPath,
|
||||
};
|
||||
const result = resolveFileOrDir(context, potentialModulePath, platform);
|
||||
if (result.type === 'resolved') {
|
||||
return result;
|
||||
}
|
||||
const {candidates} = result;
|
||||
const opts = {moduleName, packageName, pathInModule, candidates};
|
||||
throw new MissingFileInHastePackageError(opts);
|
||||
}
|
||||
|
||||
_redirectRequire(fromModule: TModule, modulePath: string): string | false {
|
||||
|
@ -246,16 +241,12 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|||
// At that point we only have module names that
|
||||
// aren't relative paths nor absolute paths.
|
||||
if (allowHaste) {
|
||||
try {
|
||||
return this._resolveHasteDependency(
|
||||
fromModule,
|
||||
normalizePath(realModuleName),
|
||||
platform,
|
||||
);
|
||||
} catch (error) {
|
||||
if (!(error instanceof UnableToResolveError)) {
|
||||
throw error;
|
||||
}
|
||||
const result = this._resolveHasteDependency(
|
||||
normalizePath(realModuleName),
|
||||
platform,
|
||||
);
|
||||
if (result.type === 'resolved') {
|
||||
return this._getFileResolvedModule(result.resolution);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,6 +372,30 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|||
}
|
||||
}
|
||||
|
||||
class MissingFileInHastePackageError extends Error {
|
||||
candidates: FileAndDirCandidates;
|
||||
moduleName: string;
|
||||
packageName: string;
|
||||
pathInModule: string;
|
||||
|
||||
constructor(opts: {|
|
||||
+candidates: FileAndDirCandidates,
|
||||
+moduleName: string,
|
||||
+packageName: string,
|
||||
+pathInModule: string,
|
||||
|}) {
|
||||
super(
|
||||
`While resolving module \`${opts.moduleName}\`, ` +
|
||||
`the Haste package \`${opts.packageName}\` was found. However the ` +
|
||||
`module \`${opts.pathInModule}\` could not be found within ` +
|
||||
`the package. Indeed, none of these files exist:\n\n` +
|
||||
` * \`${formatFileCandidates(opts.candidates.file)}\`\n` +
|
||||
` * \`${formatFileCandidates(opts.candidates.dir)}\``,
|
||||
);
|
||||
Object.assign(this, opts);
|
||||
}
|
||||
}
|
||||
|
||||
type FileOrDirContext = FileContext & {
|
||||
/**
|
||||
* This should return the path of the "main" module of the specified
|
||||
|
@ -644,7 +659,7 @@ function resolveSourceFileForExt(
|
|||
if (context.doesFileExist(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
context.candidateExts.push(filePath);
|
||||
context.candidateExts.push(extension);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue