Browse by type
<img alt="Oxc logo" src="https://oxc.rs/oxc-dark.svg" height="60">
[![Crates.io][crates-badge]][crates-url] [![npmjs.com][npm-badge]][npm-url]
[![Docs.rs][docs-badge]][docs-url] [![Build Status][ci-badge]][ci-url] [![Code Coverage][code-coverage-badge]][code-coverage-url] [![CodSpeed Badge][codspeed-badge]][codspeed-url] [![Sponsors][sponsors-badge]][sponsors-url] [![Discord chat][discord-badge]][discord-url] [![MIT licensed][license-badge]][license-url]
Rust port of [enhanced-resolve], [tsconfig-paths-webpack-plugin] and [tsconfck]
tsconfig.extendstsconfig.compilerOptions.pathstsconfig.referencesFileSystem trait.tracing instrumentation.See index.d.ts for resolveSync and ResolverFactory API.
Quick example:
import assert from "assert";
import path from "path";
import resolve, { ResolverFactory } from "./index.js";
// `resolve`
assert(resolve.sync(process.cwd(), "./index.js").path, path.join(cwd, "index.js"));
// `ResolverFactory`
const resolver = new ResolverFactory();
assert(resolver.sync(process.cwd(), "./index.js").path, path.join(cwd, "index.js"));
For file-based resolution with automatic tsconfig discovery, use resolveFileSync or resolveFileAsync:
const resolver = new ResolverFactory();
// Resolves from a file path (not directory)
const result = resolver.resolveFileSync("/path/to/file.ts", "./module");
// Async version
const result = await resolver.resolveFileAsync("/path/to/file.ts", "./module");
Key Differences:
sync(directory, specifier) - Takes a directory path, uses manually configured tsconfig if providedresolveFileSync(file, specifier) - Takes a file path, automatically discovers tsconfig.json by traversing parent directoriesWhy use resolveFileSync?
When resolving from a specific file (e.g., in bundlers, linters, or language servers), resolveFileSync automatically finds the correct tsconfig.json by:
include, exclude, and files fields to determine which tsconfig appliespaths aliases work correctly based on the file's contextSee https://stackblitz.com/edit/oxc-resolver for usage example.
See docs.rs/oxc_resolver.
yarn command, where the value process.versions.pnp is set..pnp.cjs manifest file exists in the closest directory, searched from the current working directory,directoryAn absolute path to a directory where the specifier is resolved against.
For CommonJS modules, it is the __dirname variable that contains the absolute path to the folder containing current module.
For ECMAScript modules, it is the value of import.meta.url.
Behavior is undefined when given a path to a file.
specifierThe string passed to require or import, i.e. require("specifier") or import "specifier"
Error: Package subpath '.' is not defined by "exports" in - occurs when resolving without conditionNames.The following usages apply to both Rust and Node.js; the code snippets are written in JavaScript.
To handle the exports field in package.json, ESM and CJS need to be differentiated.
defaultConditions is the conditional environment name array, ["node", "import"].
This means when the caller is an ESM import (import "module"), resolve options should be
{
"conditionNames": ["node", "import"]
}
LOAD_PACKAGE_EXPORTS(X, DIR)
- let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH,
package.json"exports", ["node", "require"]) defined in the ESM resolver.
This means when the caller is a CJS require (require("module")), resolve options should be
{
"conditionNames": ["node", "require"]
}
To support both CJS and ESM with the same cache:
const esmResolver = new ResolverFactory({
conditionNames: ["node", "import"],
});
const cjsResolver = esmResolver.cloneWithOptions({
conditionNames: ["node", "require"],
});
From this non-standard spec:
The
browserfield is provided to JavaScript bundlers or component tools when packaging modules for client side use.
The option is
{
"aliasFields": ["browser"]
}
{
"mainFields": ["module", "main"]
}
Quoting esbuild's documentation:
main - This is the standard field for all packages that are meant to be used with node. The name main is hard-coded in to node's module resolution logic itself. Because it's intended for use with node, it's reasonable to expect that the file path in this field is a CommonJS-style module.module - This field came from a proposal for how to integrate ECMAScript modules into node. Because of this, it's reasonable to expect that the file path in this field is an ECMAScript-style module. This proposal wasn't adopted by node (node uses "type": "module" instead) but it was adopted by major bundlers because ECMAScript-style modules lead to better tree shaking, or dead code removal.browser - This field came from a proposal that allows bundlers to replace node-specific files or modules with their browser-friendly versions. It lets you specify an alternate browser-specific entry point. Note that it is possible for a package to use both the browser and module field together (see the note below).The following options are aligned with [enhanced-resolve], and is implemented for Rust crate usage.
See index.d.ts for Node.js usage.
| Field | Default | Description |
|---|---|---|
| alias | {} | A hash map of module alias configurations |
| aliasFields | [] | A list of alias fields in description files |
| extensionAlias | {} | An object which maps extension to extension aliases |
| conditionNames | [] | A list of exports field condition names |
| enforceExtension | false | Enforce that an extension from extensions must be used |
| exportsFields | ["exports"] | A list of exports fields in description files |
| extensions | [".js", ".json", ".node"] | A list of extensions which should be tried for files |
| fallback | {} | Same as alias, but only used if default resolving fails |
| fileSystem | The file system which should be used | |
| fullySpecified | false | Request passed to resolve is already fully specified and extensions or main files are not resolved for it (they are still resolved for internal requests) |
| mainFields | ["main"] | A list of main fields in description files |
| mainFiles | ["index"] | A list of main files in directories |
| modules | ["node_modules"] | A list of directories to resolve modules from, can be absolute path or folder name. Absolute NODE_PATH entries are appended automatically when set. |
| resolveToContext | false | Resolve to a context instead of a file |
| preferRelative | false | Prefer to resolve module requests as relative request and fallback to resolving as module |
| preferAbsolute | false | Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots |
| restrictions | [] | A list of resolve restrictions |
| roots | [] | A list of root paths |
| symlinks | true | Whether to resolve symlinks to their symlinked location |
| allowPackageExportsInDirectoryResolve | false | Allow exports field in require('../directory'). Not part of enhanced-resolve. |
| Field | Default | Description |
|---|---|---|
| tsconfig | None | TypeScript related config for resolver |
| tsconfig.configFile | A relative path to the tsconfig file based on cwd, or an absolute path to the tsconfig file. |
|
| tsconfig.references | [] |
- 'auto': inherits from TypeScript config |
string []: relative path (based on directory of the referencing tsconfig file) or absolute path of referenced project's tsconfig || Field | Default
browse all types & interfaces →
$ claude mcp add oxc-resolver \
-- python -m otcore.mcp_server <graph>