Détail du package

oxc-resolver

oxc-project10.4mMIT11.2.0

Oxc Resolver Node API

readme

OXC Logo

Crates.io npmjs.com Docs.rs Build Status Code Coverage CodSpeed Badge Sponsors Discord chat MIT licensed

Oxc Resolver

Rust port of enhanced-resolve.

Usage

npm package

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'));

Supports WASM

See https://stackblitz.com/edit/oxc-resolver for usage example.

Rust

See docs.rs/oxc_resolver.

Terminology

directory

An 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.

specifier

The string passed to require or import, i.e. require("specifier") or import "specifier"

Errors and Trouble Shooting

  • Error: Package subpath '.' is not defined by "exports" in - occurs when resolving without conditionNames.

Configuration

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.

ESM

Per ESM Resolution algorithm

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"]
}

CJS

Per CJS Resolution algorithm

LOAD_PACKAGE_EXPORTS(X, DIR)

  1. 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"]
}

Cache

To support both CJS and ESM with the same cache:

const esmResolver = new ResolverFactory({
  conditionNames: ['node', 'import'],
});

const cjsResolver = esmResolver.cloneWithOptions({
  conditionNames: ['node', 'require'],
});

Browser Field

From this non-standard spec:

The browser field is provided to JavaScript bundlers or component tools when packaging modules for client side use.

The option is

{
  "aliasFields": ["browser"]
}

Main Field

{
  "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).

Options

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 list of module alias configurations or an object which maps key to value
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 a 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
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

Unimplemented Options

Field Default Description
descriptionFiles ["package.json"] A list of description files to read from
cachePredicate function() { return true }; A function which decides whether a request should be cached or not. An object is passed to the function with path and request properties.
cacheWithContext true If unsafe cache is enabled, includes request.context in the cache key
plugins [] A list of additional resolve plugins which should be applied
resolver undefined A prepared Resolver to which the plugins are attached
unsafeCache false Use this cache object to unsafely cache the successful requests

Debugging

The following environment variable emits tracing information for the oxc_resolver::resolve function.

e.g.

2024-06-11T07:12:20.003537Z DEBUG oxc_resolver: options: ResolveOptions { ... }, path: "...", specifier: "...", ret: "..."
    at /path/to/oxc_resolver-1.8.1/src/lib.rs:212
    in oxc_resolver::resolve with path: "...", specifier: "..."

The input values are options, path and specifier, the returned value is ret.

NAPI

OXC_LOG=DEBUG your_program

Rolldown

RD_LOG='oxc_resolver' rolldown build

Test

Tests are ported from

Test cases are located in ./src/tests, fixtures are located in ./tests

  • [x] alias.test.js
  • [x] browserField.test.js
  • [x] dependencies.test.js
  • [x] exportsField.test.js
  • [x] extension-alias.test.js
  • [x] extensions.test.js
  • [x] fallback.test.js
  • [x] fullSpecified.test.js
  • [x] identifier.test.js (see unit test in crates/oxc_resolver/src/request.rs)
  • [x] importsField.test.js
  • [x] incorrect-description-file.test.js (need to add ctx.fileDependencies)
  • [x] missing.test.js
  • [x] path.test.js (see unit test in crates/oxc_resolver/src/path.rs)
  • [ ] plugins.test.js
  • [ ] pnp.test.js
  • [x] resolve.test.js
  • [x] restrictions.test.js (partially done, regex is not supported yet)
  • [x] roots.test.js
  • [x] scoped-packages.test.js
  • [x] simple.test.js
  • [x] symlink.test.js

Irrelevant tests

  • CachedInputFileSystem.test.js
  • SyncAsyncFileSystemDecorator.test.js
  • forEachBail.test.js
  • getPaths.test.js
  • pr-53.test.js
  • unsafe-cache.test.js
  • yield.test.js

Sponsored By

My sponsors

📖 License

oxc_resolver is free and open-source software licensed under the MIT License.

Oxc partially copies code from the following projects.

Project License
webpack/enhanced-resolve MIT
dividab/tsconfig-paths MIT
parcel-bundler/parcel MIT
tmccombs/json-comments-rs Apache 2.0

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

11.2.0 - 2025-06-05

Features

  • (napi) add tracing-subscriber feature; turned on by default (#546)

11.1.0 - 2025-06-01

Features

  • support module type for TS files (#538)

11.0.0 - 2025-05-28

Features

  • implement module type resolution algorithm ESM_FILE_FORMAT from the spec (#535)

Documentation

  • (README) clarify algorithm specification

Chore

  • (deps) lock file maintenance rust crates (#530)

10.0.0 - 2025-05-20

Features

  • (napi) upgrade NAPI-RS to 3.0.0-beta.1 (#525)

Refactor

  • [breaking] set clippy avoid-breaking-exported-api = false (#519)

Chore

  • (deps) lock file maintenance (#523)
  • (deps) update dependency rust to v1.87.0 (#520)
  • sync napi cfg on global_allocator
  • (napi) adjust mimalloc features (#515)

9.0.1 - 2025-05-09

Bug Fixes

  • oxc_resolver_napi dependency version

9.0.0 - 2025-05-09

Bug Fixes

  • hash import does not need to load from node_modules (#501)

Chore

  • add --tsconfig to example (#505)
  • publish oxc_napi_resolver (#496)

8.0.0 - 2025-05-01

Bug Fixes

  • fix incorrect return of package.json when a workspace module has node_modules (#482)

Performance

  • cache whether a path is node_modules or inside node_modules (#490)
  • remove a useless load_as_directory call (#487)

Refactor

  • [breaking] remove description_files option (#488)
  • [breaking] remove modules options (#484)

7.0.0 - 2025-04-29

Bug Fixes

  • return the enclosing package.json if it is inside node_modules (#476)

Refactor

  • add Debug to FsCachedPath (#478)

6.0.1 - 2025-04-25

Bug Fixes

  • handle package.json and tsconfig.json with BOM (#463)

Performance

  • avoid double call to parse_package_specifier (#465)

6.0.0 - 2025-04-22

Bug Fixes

  • properly handle DOS device paths in strip_windows_prefix (#455)

5.3.0 - 2025-04-19

Features

  • deserialize preserve_value_imports and imports_not_used_as_values from compilerOptions (#457)
  • deserialize target from compilerOptions (#456)

5.2.0 - 2025-04-08

Bug Fixes

  • resolve ${configDir} in tsconfig compilerOptions.baseUrl (#450)

5.1.1 - 2025-04-04

Bug Fixes

  • handle query and fragment in pacakge.json exports and imports field (#443)

5.1.0 - 2025-04-02

Features

  • resolve emitDecoratorMetadata in tsconfig (#439)

Documentation

  • fix an incorrect comment on Context::missing_dependencies

5.0.0 - 2025-03-07

Features

  • [breaking] Rust Edition 2024 (#402)
  • deserialize verbatim_module_syntax from compilerOptions (#411)

Refactor

  • remove papaya .collector(seize::Collector::new()) call (#393)

4.2.0 - 2025-02-19

Features

  • support wildcard * in alias plugin (#388)

4.1.0 - 2025-02-14

Features

  • merge options from extends tsconfig.json (#375)
  • add more fields in tsconfig#CompilerOptionsSerde (#374)

Bug Fixes

  • fix bench

4.0.0 - 2025-01-20

Features

  • [breaking] generic fs cache type Resolver = ResolverGeneric<FsCache<FileSystemOs>> (#358)
  • [breaking] PackageJson and TsConfig traits (#360)

Performance

  • use papaya instead of dashmap (#356)

3.0.3 - 2024-12-14

Bug Fixes

  • try browsers field and alias before resolving directory in node_modules (#349)

3.0.2 - 2024-12-13

Bug Fixes

  • special case for aliasing @/ (#348)
  • normalize resolved result on Windows for root (#345)

Refactor

  • replace UnsafeCell with RefCell (#346)

3.0.1 - 2024-12-12

Performance

  • try directory first in node_modules (#340)

3.0.0 - 2024-12-11

Added

  • [breaking] replace FileSystem::canonicalize with FileSystem::read_link (#331)

Other

  • guard load_alias on hot path (#339)

2.1.1 - 2024-11-22

Performance

  • reduce hash while resolving package.json (#319)
  • reduce memory allocation while normalizing package path (#318)
  • reduce memory allocation while resolving package.json (#317)
  • use path.as_os_str().hash() instead of path.hash() (#316)
  • reduce memory allocation by using a thread_local path for path methods (#315)

Other

  • remove the deprecated simdutf8 aarch64_neon feature
  • mention extension must start with a . in with_extension (#313)

2.1.0 - 2024-11-20

Added

  • add Resolver::resolve_tsconfig API (#312)

Fixed

  • don't panic when resolving / with roots (#310)
  • use same UNC path normalization logic with libuv (#306)

Other

  • (deps) update rust crates to v1.0.215
  • fix symlink test init on windows (#307)

2.0.1 - 2024-11-08

Other

  • cargo upgrade && pnpm upgrade
  • bring back the symlink optimization (#298)
  • (deps) update rust crate criterion2 to v2

2.0.0 - 2024-10-22

Added

  • [breaking] add add ResolveError::Builtin::is_runtime_module (#272)

Fixed

  • use fs::canonicalize to cover symlink edge cases (#284)
  • extensionAlias cannot resolve mathjs (#273)

1.12.0 - 2024-09-25

Added

  • [breaking] mark ResolveError #[non_exhaustive] (#252)
  • show tried extension aliases in ResolveError::ExtensionAlias (#251)
  • give a specific error for matched alias not found (#238)

1.11.0 - 2024-08-26

Added

  • use simdutf8 to validate UTF-8 when reading files (#237)
  • Yarn PnP (behind a feature flag) (#217)

1.10.2 - 2024-07-16

Chore

  • Release FreeBSD

1.10.1 - 2024-07-15

Fixed

  • resolve module ipaddr.js correctly when extensionAlias is provided (#228)

1.10.0 - 2024-07-11

Added

  • (napi) expose module type info in ResolveResult (#223)

Fixed

  • remove #[cfg(target_os = "windows")] logic in canonicalize (#221)

Other

  • update cargo deny (#222)
  • pin crate-ci/typos version

1.9.4 - 2024-07-10

Other

  • use custom canonicalize impl to avoid useless syscall (#220)
  • add symlink fixtures (#219)

1.9.3 - 2024-07-03

Fixed

  • tsconfig project reference it self should throw error (#211)

Other

  • (napi) make napi binary smaller with minimal tracing features (#213)
  • (napi) remove tokio (#212)
  • (deps) update rust crate dashmap to v6 (#209)

1.9.2 - 2024-06-30

Added

  • (napi) add tracing via OXC_LOG:DEBUG (#202)

Other

  • document directory is an absolute path for resolve(directory, specifier) (#206)
  • add a broken tsconfig test (#205)
  • improve code coverage for src/error.rs (#204)
  • skip resolving extension alias when options.extension_alias is empty (#203)
  • add npm badge to crates.io

1.9.1 - 2024-06-29

Added

  • strip symbols and enable LTO (#197)

Other

  • improve call to Path::ends_with (#199)
  • list [profile.release] explicitly (#198)

1.9.0 - 2024-06-28

Added

  • export package.json type and sideEffects field by default for bundlers (#196)

1.8.4 - 2024-06-27

Other

  • skip searching for package.json when alias_fields is not provided (#194)

1.8.3 - 2024-06-26

  • (napi) release wasi build

1.8.2 - 2024-06-24

Added

  • (napi) add async API (#191)

1.8.1 - 2024-05-31

Fixed

  • alias value should try fragment as path (#172)

1.8.0 - 2024-05-27

Added

  • [breaking] remove the constraint on packages exports default must be the last one (#171)
  • [breaking] return ResolveError:Builtin("node:{specifier}") from package imports and exports (#165)

Fixed

  • alias not found should return error (#168)

Other

  • add panic test for extensions without a leading dot (#150)
  • add test case for empty alias fields (#149)

1.7.0 - 2024-04-24

Added

  • add imports_fields option (#138)
  • substitute path that starts with ${configDir}/ in tsconfig.compilerOptions.paths (#136)

Fixed

  • RootsPlugin debug_assert on windows (#145)
  • RootsPlugin should fall through if it fails to resolve the roots (#144)
  • lazily read package.json.exports for shared resolvers (#137)

Other

  • remove PartialEq and Eq from Specifier (#148)
  • add test case for tsconfig paths alias fall through (#147)
  • use cargo shear
  • fix test not failing the jobs property (#146)
  • lazily read package.json.browser_fields for shared resolvers (#142)
  • avoid an extra allocation in load_extensions
  • ignore code coverage for Display on ResolveOptions (#140)
  • remove the browser field lookup in resolve_esm_match (#141)
  • remove the extra condition_names from package_exports_resolve

1.6.7 - 2024-04-22

Fixed

  • incorrect resolution when using shared resolvers with different main_fields (#134)

1.6.6 - 2024-04-22

Other

  • print resolve options while debug tracing (#133)

1.6.5 - 2024-04-10

Fixed

  • canonicalize is not supported on wasi target (#124)

Other

  • document feature flags

1.6.4 - 2024-03-29

Docs

  • improve terminology and clarify contexts