or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundling.mdcompression.mdindex.mdnaming.mdoptimization.mdpackaging.mdreporting.mdresolution.mdruntime.mdtransformation.mdvalidation.md

resolution.mddocs/

0

# Module Resolution

1

2

The Resolver plugin enables custom module resolution logic for import and require statements. Resolvers determine how module specifiers are resolved to actual file paths and provide the foundation for custom module systems.

3

4

## Capabilities

5

6

### Resolver Class

7

8

Base class for creating module resolution plugins.

9

10

```typescript { .api }

11

/**

12

* Base class for module resolution plugins

13

* @template T - Configuration type for this resolver

14

*/

15

export declare class Resolver<T> {

16

constructor(opts: ResolverOpts<T>);

17

}

18

19

/**

20

* Resolver plugin configuration interface

21

* @template ConfigType - Type of configuration returned by loadConfig

22

*/

23

interface ResolverOpts<ConfigType> {

24

/** Load configuration for this resolver */

25

loadConfig?: (args: {

26

config: Config;

27

options: PluginOptions;

28

logger: PluginLogger;

29

tracer: PluginTracer;

30

}) => Promise<ConfigType> | ConfigType;

31

32

/** Resolve a module specifier to a file path (required) */

33

resolve(args: {

34

dependency: Dependency;

35

options: PluginOptions;

36

logger: PluginLogger;

37

tracer: PluginTracer;

38

specifier: FilePath;

39

pipeline?: string;

40

config: ConfigType;

41

}): Promise<ResolveResult | null>;

42

}

43

```

44

45

**Usage Example:**

46

47

```javascript

48

import { Resolver } from "@parcel/plugin";

49

import path from "path";

50

51

export default new Resolver({

52

// Load resolver configuration

53

loadConfig({config}) {

54

return config.getConfigFrom(/* config path */);

55

},

56

57

// Main resolution logic (required)

58

async resolve({dependency, specifier, options, logger}) {

59

// Handle different types of specifiers

60

if (specifier.startsWith('~')) {

61

// Resolve from node_modules

62

const modulePath = specifier.slice(1);

63

const resolved = path.resolve(options.projectRoot, 'node_modules', modulePath);

64

65

return {

66

filePath: resolved,

67

sideEffects: false

68

};

69

}

70

71

if (specifier.startsWith('./') || specifier.startsWith('../')) {

72

// Relative path resolution

73

const fromDir = path.dirname(dependency.sourcePath);

74

const resolved = path.resolve(fromDir, specifier);

75

76

return {

77

filePath: resolved,

78

sideEffects: true

79

};

80

}

81

82

// Return null to let other resolvers handle this

83

return null;

84

}

85

});

86

```

87

88

### Resolution Results

89

90

```typescript { .api }

91

/**

92

* Result from a module resolution operation

93

*/

94

interface ResolveResult {

95

/** Resolved file path */

96

filePath: FilePath;

97

98

/** Whether this module has side effects */

99

sideEffects?: boolean;

100

101

/** Module resolution priority */

102

priority?: ResolvePriority;

103

104

/** Whether this is an excluded dependency */

105

isExcluded?: boolean;

106

107

/** Code to inline instead of resolving */

108

code?: string;

109

110

/** Query parameters for the resolved module */

111

query?: URLSearchParams;

112

113

/** Pipeline to use for processing this module */

114

pipeline?: string;

115

116

/** Environment for this module */

117

env?: EnvironmentOptions;

118

119

/** Module metadata */

120

meta?: Record<string, any>;

121

122

/** Symbol exports from this module */

123

symbols?: Map<Symbol, SymbolResolution>;

124

}

125

126

/**

127

* Resolution priority levels

128

*/

129

type ResolvePriority = "sync" | "parallel" | "lazy";

130

```

131

132

### Dependency Information

133

134

```typescript { .api }

135

/**

136

* Dependency being resolved

137

*/

138

interface Dependency {

139

/** Module specifier to resolve */

140

specifier: string;

141

142

/** Source file path containing this dependency */

143

sourcePath: FilePath;

144

145

/** Source location of the dependency */

146

loc?: SourceLocation;

147

148

/** Import type */

149

specifierType: SpecifierType;

150

151

/** Whether this is an optional dependency */

152

isOptional?: boolean;

153

154

/** Whether this dependency is async */

155

isAsync?: boolean;

156

157

/** Dependency priority */

158

priority?: DependencyPriority;

159

160

/** Bundle behavior for this dependency */

161

bundleBehavior?: BundleBehavior;

162

163

/** Environment for this dependency */

164

env?: EnvironmentOptions;

165

166

/** Dependency metadata */

167

meta?: Record<string, any>;

168

169

/** Pipeline to use for this dependency */

170

pipeline?: string;

171

172

/** Symbols imported from this dependency */

173

symbols?: Map<Symbol, SymbolResolution>;

174

}

175

176

/**

177

* Types of module specifiers

178

*/

179

type SpecifierType =

180

| "commonjs"

181

| "esm"

182

| "url"

183

| "relative"

184

| "absolute";

185

186

/**

187

* Dependency loading priority

188

*/

189

type DependencyPriority = "sync" | "parallel" | "lazy";

190

191

/**

192

* Bundle inclusion behavior

193

*/

194

type BundleBehavior =

195

| "inline"

196

| "isolated";

197

```

198

199

### Source Location Information

200

201

```typescript { .api }

202

/**

203

* Location information in source code

204

*/

205

interface SourceLocation {

206

/** Source file path */

207

filePath: FilePath;

208

209

/** Start position */

210

start: Position;

211

212

/** End position */

213

end: Position;

214

}

215

216

/**

217

* Position in source code

218

*/

219

interface Position {

220

/** Line number (1-based) */

221

line: number;

222

223

/** Column number (0-based) */

224

column: number;

225

}

226

```

227

228

### Common Resolution Patterns

229

230

**Package Resolution:**

231

```javascript

232

// Resolve from node_modules

233

if (!specifier.startsWith('.')) {

234

const packagePath = await options.packageManager.resolve(specifier, fromPath);

235

return { filePath: packagePath };

236

}

237

```

238

239

**Alias Resolution:**

240

```javascript

241

// Handle path aliases

242

const aliases = config.aliases || {};

243

for (const [alias, target] of Object.entries(aliases)) {

244

if (specifier.startsWith(alias)) {

245

const resolved = specifier.replace(alias, target);

246

return { filePath: path.resolve(options.projectRoot, resolved) };

247

}

248

}

249

```

250

251

**Extension Resolution:**

252

```javascript

253

// Try different file extensions

254

const extensions = ['.js', '.ts', '.jsx', '.tsx'];

255

for (const ext of extensions) {

256

const withExt = specifier + ext;

257

if (await options.inputFS.exists(withExt)) {

258

return { filePath: withExt };

259

}

260

}

261

```