0
# Resolution Engine
1
2
The core resolution engine handles all module resolution scenarios including relative paths, absolute paths, bare specifiers, and Haste modules. It orchestrates the entire resolution process through a series of specialized resolvers.
3
4
## Capabilities
5
6
### Main Resolve Function
7
8
The primary entry point for all module resolution operations.
9
10
```typescript { .api }
11
/**
12
* Resolve a module name to a file path or asset collection based on the resolution context
13
* @param context - Resolution context containing configuration and helper functions
14
* @param moduleName - Module name to resolve (relative, absolute, or bare specifier)
15
* @param platform - Target platform (e.g., 'ios', 'android', 'web') for platform-specific resolution
16
* @returns Resolution result containing file path or asset collection
17
*/
18
function resolve(
19
context: ResolutionContext,
20
moduleName: string,
21
platform: string | null
22
): Resolution;
23
```
24
25
**Usage Examples:**
26
27
```javascript
28
const Resolver = require("metro-resolver");
29
30
// Resolve relative import
31
const relativeResult = Resolver.resolve(context, './utils/helper', 'ios');
32
// { type: 'sourceFile', filePath: '/app/src/utils/helper.ios.js' }
33
34
// Resolve bare specifier
35
const packageResult = Resolver.resolve(context, 'lodash', null);
36
// { type: 'sourceFile', filePath: '/node_modules/lodash/index.js' }
37
38
// Resolve asset
39
const assetResult = Resolver.resolve(context, './icon.png', 'ios');
40
// { type: 'assetFiles', filePaths: ['./icon@2x.ios.png', './icon.ios.png'] }
41
42
// Handle empty resolution (excluded module)
43
const emptyResult = Resolver.resolve(context, 'excluded-module', null);
44
// { type: 'empty' }
45
```
46
47
### Resolution Result Types
48
49
Different types of resolution outcomes based on the target module.
50
51
```typescript { .api }
52
type Resolution = FileResolution | Readonly<{ type: 'empty' }>;
53
54
type FileResolution = AssetResolution | SourceFileResolution;
55
56
interface SourceFileResolution {
57
readonly type: 'sourceFile';
58
readonly filePath: string;
59
}
60
61
interface AssetResolution {
62
readonly type: 'assetFiles';
63
readonly filePaths: ReadonlyArray<string>;
64
}
65
```
66
67
### Resolution Process Flow
68
69
The resolver follows a systematic process:
70
71
1. **Custom Resolver Check**: If a custom resolver is provided, delegate to it first
72
2. **Path Type Detection**: Determine if the module name is relative, absolute, or bare specifier
73
3. **Relative/Absolute Resolution**: Resolve using file system lookups for direct paths
74
4. **Subpath Import Resolution**: Handle package.json imports field for `#` prefixed imports
75
5. **Module Redirection**: Apply any path redirections before further resolution
76
6. **Haste Resolution**: Check Haste module map if enabled
77
7. **Package Resolution**: Resolve bare specifiers through node_modules hierarchy
78
8. **Error Handling**: Throw appropriate errors for failed resolutions
79
80
### Platform-Specific Resolution
81
82
The resolver supports platform-specific file resolution for React Native development.
83
84
**Resolution Priority:**
85
1. Platform-specific file (e.g., `Component.ios.js`)
86
2. Native platform file (e.g., `Component.native.js`) if `preferNativePlatform` is true
87
3. Generic file (e.g., `Component.js`)
88
89
**Usage Example:**
90
91
```javascript
92
// With platform = 'ios', the resolver will try:
93
// 1. ./Component.ios.js
94
// 2. ./Component.native.js (if preferNativePlatform: true)
95
// 3. ./Component.js
96
const result = Resolver.resolve(context, './Component', 'ios');
97
```
98
99
### Extension Resolution
100
101
The resolver attempts multiple extensions based on configuration.
102
103
**Resolution Order:**
104
1. Exact filename match (no extension)
105
2. Source extensions in order (`.js`, `.ts`, `.tsx`, etc.)
106
3. Asset extensions for asset files (`.png`, `.jpg`, etc.)
107
108
### Hierarchical Lookup
109
110
For bare specifiers, the resolver searches through the node_modules hierarchy.
111
112
**Search Order:**
113
1. Current directory's node_modules
114
2. Parent directory's node_modules
115
3. Continue up the directory tree
116
4. Global node_modules paths from context
117
118
**Example Hierarchy:**
119
```
120
/project/src/components/Button.js
121
-> /project/src/components/node_modules/package
122
-> /project/src/node_modules/package
123
-> /project/node_modules/package
124
-> /node_modules/package
125
```
126
127
### Empty Module Resolution
128
129
The resolver can return empty resolutions for excluded modules.
130
131
```typescript { .api }
132
interface EmptyResolution {
133
readonly type: 'empty';
134
}
135
```
136
137
This is useful for:
138
- Conditional compilation
139
- Platform-specific exclusions
140
- Build-time module replacement
141
142
**Usage Example:**
143
144
```javascript
145
// If redirectModulePath returns false for a module
146
const context = {
147
// ... other config
148
redirectModulePath: (path) => {
149
if (path.includes('server-only')) return false;
150
return path;
151
}
152
};
153
154
const result = Resolver.resolve(context, 'server-only-module', null);
155
// { type: 'empty' }
156
```