Skip to content

Commit

Permalink
Add getPackageForModule function to resolution context
Browse files Browse the repository at this point in the history
Summary:
Exposes an additional accessor on this API in order for `package.json`-based resolution to be relocated into metro-resolver.

Changelog: **[Feature]** Add `getPackageForModule` accessor to custom resolver context

Reviewed By: jacdebug

Differential Revision: D42740236

fbshipit-source-id: 5753b427cd50417a657a59bcd06224aebd7b3fb9
  • Loading branch information
huntie authored and facebook-github-bot committed Jan 31, 2023
1 parent 11a4681 commit adfb593
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/Resolution.md
Expand Up @@ -168,6 +168,10 @@ The ordered list of fields in `package.json` that should be read to resolve a pa

Given the path to a `package.json` file, returns the parsed file contents.

#### `getPackageForModule: (modulePath: string) => ?PackageInfo`

Given a module path that may exist under an npm package, locates and returns the package root path and parsed `package.json` contents.

#### `resolveHasteModule: string => ?string`

Resolves a Haste module name to an absolute path. Returns `null` if no such module exists.
Expand Down
1 change: 1 addition & 0 deletions packages/metro-resolver/src/__tests__/utils.js
Expand Up @@ -33,6 +33,7 @@ export function createResolutionContext(
extraNodeModules: null,
getPackage: (packageJsonPath: string) =>
JSON.parse(fileMap[packageJsonPath]),
getPackageForModule: () => null,
isAssetFile: () => false,
mainFields: ['browser', 'main'],
nodeModulesPaths: [],
Expand Down
11 changes: 11 additions & 0 deletions packages/metro-resolver/src/types.js
Expand Up @@ -50,6 +50,11 @@ export type PackageJson = $ReadOnly<{
...
}>;

export type PackageInfo = $ReadOnly<{
packageJson: PackageJson,
rootPath: string,
}>;

/**
* Check existence of a single file.
*/
Expand Down Expand Up @@ -91,6 +96,12 @@ export type FileOrDirContext = $ReadOnly<{
* Get the parsed contents of the specified `package.json` file.
*/
getPackage: (packageJsonPath: string) => ?PackageJson,

/**
* Get the package information and parsed `package.json` file for for a given
* module path, if it is contained within an npm package.
*/
getPackageForModule: (modulePath: string) => ?PackageInfo,
}>;

export type HasteContext = $ReadOnly<{
Expand Down
Expand Up @@ -20,7 +20,7 @@ import type {
ResolveAsset,
} from 'metro-resolver';
import type {ResolverInputOptions} from '../../shared/types.flow';
import type {PackageJson} from 'metro-resolver/src/types';
import type {PackageInfo, PackageJson} from 'metro-resolver/src/types';

const {codeFrameColumns} = require('@babel/code-frame');
const fs = require('fs');
Expand Down Expand Up @@ -220,6 +220,7 @@ class ModuleResolver<TPackage: Packageish> {
resolveHastePackage: (name: string) =>
this._options.getHastePackagePath(name, platform),
getPackage: this._getPackage,
getPackageForModule: this._getPackageForModule,
},
moduleName,
platform,
Expand Down Expand Up @@ -282,6 +283,24 @@ class ModuleResolver<TPackage: Packageish> {
return null;
};

_getPackageForModule = (modulePath: string): ?PackageInfo => {
let pkg;

try {
pkg = this._options.moduleCache.getPackageOf(modulePath);
} catch (e) {
// Do nothing. The standard module cache does not trigger any error, but
// the ModuleGraph one does, if the module does not exist.
}

return pkg != null
? {
rootPath: path.dirname(pkg.path),
packageJson: pkg.read(),
}
: null;
};

/**
* TODO: Return Resolution instead of coercing to BundlerResolution here
*/
Expand Down

0 comments on commit adfb593

Please sign in to comment.