or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-metro-resolver

Implementation of Metro's resolution logic for JavaScript modules, assets, and packages within React Native and Metro bundler projects.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/metro-resolver@0.83.x

To install, run

npx @tessl/cli install tessl/npm-metro-resolver@0.83.0

0

# Metro Resolver

1

2

Metro Resolver is a JavaScript library that implements Metro's module resolution logic, providing the core functionality for resolving JavaScript modules, assets, and packages within React Native and Metro bundler projects. It handles complex resolution scenarios including package.json exports, imports, platform-specific files, asset resolution, and custom resolver implementations.

3

4

## Package Information

5

6

- **Package Name**: metro-resolver

7

- **Package Type**: npm

8

- **Language**: JavaScript/TypeScript

9

- **Installation**: `npm install metro-resolver`

10

11

## Core Imports

12

13

```javascript

14

const Resolver = require("metro-resolver");

15

const { resolve } = Resolver;

16

```

17

18

For ES modules:

19

20

```javascript

21

import Resolver from "metro-resolver";

22

const { resolve } = Resolver;

23

```

24

25

TypeScript imports (with type definitions):

26

27

```typescript

28

import {

29

resolve,

30

type ResolutionContext,

31

type Resolution,

32

type CustomResolver

33

} from "metro-resolver";

34

```

35

36

## Basic Usage

37

38

```javascript

39

const Resolver = require("metro-resolver");

40

41

// Create a resolution context (typically provided by Metro bundler)

42

const context = {

43

allowHaste: false,

44

assetExts: new Set(['png', 'jpg', 'jpeg', 'gif']),

45

sourceExts: ['js', 'json', 'ts', 'tsx'],

46

mainFields: ['browser', 'main'],

47

fileSystemLookup: (path) => ({ exists: true, type: 'f', realPath: path }),

48

doesFileExist: (path) => true,

49

getPackage: (packagePath) => require(packagePath),

50

getPackageForModule: (modulePath) => null,

51

nodeModulesPaths: ['/node_modules'],

52

originModulePath: '/app/src/index.js',

53

preferNativePlatform: false,

54

resolveAsset: (dirPath, name, ext) => [`${dirPath}/${name}${ext}`],

55

resolveHasteModule: () => undefined,

56

resolveHastePackage: () => undefined,

57

redirectModulePath: (path) => path,

58

customResolverOptions: {},

59

disableHierarchicalLookup: false,

60

extraNodeModules: null,

61

dev: false,

62

unstable_conditionNames: ['import', 'require'],

63

unstable_conditionsByPlatform: {},

64

unstable_enablePackageExports: true,

65

unstable_logWarning: console.warn

66

};

67

68

// Resolve a module

69

const resolution = Resolver.resolve(context, 'react-native', 'ios');

70

console.log(resolution);

71

// { type: 'sourceFile', filePath: '/node_modules/react-native/index.js' }

72

```

73

74

## Architecture

75

76

Metro Resolver is built around several key components:

77

78

- **Core Resolution Engine**: The main `resolve` function that orchestrates the resolution process

79

- **Resolution Context**: Configuration object containing all resolver settings and helper functions

80

- **Package Resolution**: Logic for resolving package entry points, exports, and imports fields

81

- **File System Integration**: Abstracted file system operations for flexibility across environments

82

- **Error Handling**: Comprehensive error types for different resolution failure scenarios

83

- **Asset Resolution**: Specialized handling for asset files with scaling variants

84

- **Platform Support**: Platform-specific file resolution for React Native development

85

86

## Capabilities

87

88

### Core Resolution

89

90

Main resolution function that handles all module resolution scenarios including relative paths, absolute paths, bare specifiers, and Haste modules.

91

92

```typescript { .api }

93

function resolve(

94

context: ResolutionContext,

95

moduleName: string,

96

platform: string | null

97

): Resolution;

98

99

type Resolution = FileResolution | Readonly<{ type: 'empty' }>;

100

101

type FileResolution = AssetResolution | SourceFileResolution;

102

103

interface SourceFileResolution {

104

readonly type: 'sourceFile';

105

readonly filePath: string;

106

}

107

108

interface AssetResolution {

109

readonly type: 'assetFiles';

110

readonly filePaths: ReadonlyArray<string>;

111

}

112

```

113

114

[Resolution Engine](./resolution-engine.md)

115

116

### Resolution Context

117

118

Configuration system that provides all the settings, file system operations, and helper functions needed for module resolution.

119

120

```typescript { .api }

121

interface ResolutionContext {

122

readonly allowHaste: boolean;

123

readonly assetExts: ReadonlySet<string>;

124

readonly sourceExts: ReadonlyArray<string>;

125

readonly customResolverOptions: CustomResolverOptions;

126

readonly disableHierarchicalLookup: boolean;

127

readonly doesFileExist: DoesFileExist;

128

readonly extraNodeModules?: Readonly<{ [string]: string }> | null;

129

readonly dev: boolean;

130

readonly fileSystemLookup: FileSystemLookup;

131

readonly getPackage: (packageJsonPath: string) => PackageJson | null;

132

readonly getPackageForModule: (absoluteModulePath: string) => PackageForModule | null;

133

readonly mainFields: ReadonlyArray<string>;

134

readonly originModulePath: string;

135

readonly nodeModulesPaths: ReadonlyArray<string>;

136

readonly preferNativePlatform: boolean;

137

readonly resolveAsset: ResolveAsset;

138

readonly redirectModulePath: (modulePath: string) => string | false;

139

readonly resolveHasteModule: (name: string) => string | undefined;

140

readonly resolveHastePackage: (name: string) => string | undefined;

141

readonly resolveRequest?: CustomResolver;

142

readonly dependency?: any;

143

readonly isESMImport?: boolean;

144

readonly unstable_conditionNames: ReadonlyArray<string>;

145

readonly unstable_conditionsByPlatform: Readonly<{ [platform: string]: ReadonlyArray<string> }>;

146

readonly unstable_enablePackageExports: boolean;

147

readonly unstable_logWarning: (message: string) => void;

148

}

149

```

150

151

[Resolution Context](./resolution-context.md)

152

153

### Error Handling

154

155

Comprehensive error types for different resolution failure scenarios with detailed diagnostic information.

156

157

```typescript { .api }

158

class FailedToResolveNameError extends Error {

159

dirPaths: ReadonlyArray<string>;

160

extraPaths: ReadonlyArray<string>;

161

}

162

163

class FailedToResolvePathError extends Error {

164

candidates: FileAndDirCandidates;

165

}

166

167

class InvalidPackageError extends Error {

168

fileCandidates: FileCandidates;

169

indexCandidates: FileCandidates;

170

mainModulePath: string;

171

packageJsonPath: string;

172

}

173

174

class FailedToResolveUnsupportedError extends Error {

175

constructor(message: string);

176

}

177

```

178

179

[Error Handling](./error-handling.md)

180

181

### Package Resolution

182

183

Advanced package resolution supporting modern Node.js features like package.json exports/imports fields and conditional exports.

184

185

```typescript { .api }

186

interface PackageJson {

187

readonly name?: string;

188

readonly main?: string;

189

readonly exports?: ExportsField;

190

readonly imports?: ExportsLikeMap;

191

}

192

193

194

interface PackageInfo {

195

readonly packageJson: PackageJson;

196

readonly rootPath: string;

197

}

198

```

199

200

[Package Resolution](./package-resolution.md)

201

202

### Asset Resolution

203

204

Specialized handling for asset files including support for scaling variants and platform-specific assets.

205

206

```typescript { .api }

207

type ResolveAsset = (

208

dirPath: string,

209

assetName: string,

210

extension: string

211

) => ReadonlyArray<string> | undefined;

212

213

function resolveAsset(

214

context: ResolutionContext,

215

filePath: string

216

): AssetResolution | null;

217

```

218

219

[Asset Resolution](./asset-resolution.md)

220

221

### Custom Resolvers

222

223

Extensibility system allowing custom resolution logic to be integrated into the resolution pipeline.

224

225

```typescript { .api }

226

type CustomResolver = (

227

context: CustomResolutionContext,

228

moduleName: string,

229

platform: string | null

230

) => Resolution;

231

232

interface CustomResolutionContext extends ResolutionContext {

233

readonly resolveRequest: CustomResolver;

234

}

235

236

type CustomResolverOptions = Readonly<{

237

[option: string]: unknown;

238

}>;

239

```

240

241

[Custom Resolvers](./custom-resolvers.md)

242

243

### Utility Functions

244

245

Utility functions for working with resolution candidates and formatting.

246

247

```typescript { .api }

248

function formatFileCandidates(candidates: FileCandidates): string;

249

```

250

251

## Types

252

253

```typescript { .api }

254

type Result<TResolution, TCandidates> =

255

| { readonly type: 'resolved'; readonly resolution: TResolution }

256

| { readonly type: 'failed'; readonly candidates: TCandidates };

257

258

type AssetFileResolution = ReadonlyArray<string>;

259

260

type FileCandidates =

261

| { readonly type: 'asset'; readonly name: string }

262

| {

263

readonly type: 'sourceFile';

264

filePathPrefix: string;

265

readonly candidateExts: ReadonlyArray<string>;

266

};

267

268

interface FileAndDirCandidates {

269

readonly dir: FileCandidates | null;

270

readonly file: FileCandidates | null;

271

}

272

273

type DoesFileExist = (filePath: string) => boolean;

274

275

type FileSystemLookup = (

276

absoluteOrProjectRelativePath: string

277

) => { exists: false } | { exists: true; type: 'f' | 'd'; realPath: string };

278

279

interface PackageForModule extends PackageInfo {

280

readonly packageRelativePath: string;

281

}

282

283

type ExportsLikeMap = Readonly<{

284

[subpathOrCondition: string]: string | ExportsLikeMap | null;

285

}>;

286

287

type ExportMapWithFallbacks = Readonly<{

288

[subpath: string]: string | ExportsLikeMap | null | ExportValueWithFallback;

289

}>;

290

291

type ExportValueWithFallback =

292

| ReadonlyArray<ExportsLikeMap | string>

293

| ReadonlyArray<ReadonlyArray<unknown>>;

294

295

type ExportsField =

296

| string

297

| ReadonlyArray<string>

298

| ExportValueWithFallback

299

| ExportsLikeMap

300

| ExportMapWithFallbacks;

301

302

type FlattenedExportMap = ReadonlyMap<string, string | null>;

303

304

type NormalizedExportsLikeMap = Map<string, null | string | ExportsLikeMap>;

305

```