
Product
Introducing Rust Support in Socket
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.
unrs-resolver
Advanced tools
[!NOTE]
This is a fork of oxc-resolver and rspack-resolver, and will be used in eslint-plugin-import-x and eslint-import-resolver-typescript cause 100% compatible with enhanced-resolve is the non-goal of oxc-resolver itself, we add enhanced-resolve specific features like
pnp support
.We also fix several bugs reported by eslint-plugin-import-x and eslint-import-resolver-typescript users:
- takes
paths
andreferences
into account at the same timereferences
should take higher priority- support
pnpapi
core module and package deep link- enable more targets support
- absolute path aliasing should not be skipped
- use napi-postinstall for legacy npm versions
- Raspberry PI 4 aarch64 compatibility issue and import-js/eslint-import-resolver-typescript#406 due to mimalloc-safe
- support
load_as_directory
forpnp
mode- resolve parent base url correctly by normalizing as absolute path
The list could be longer in the future, but we don't want to make it too long here.
We also sync with oxc-resolver and rspack-resolver regularly to keep up with the latest changes:
Last but not least, we prepare some bug fix PRs first on our side and PR back into upstream projects, and we will keep doing this in the future:
oxc-resolver
: #84 with oxc-resolver#455rspack-resolver
: #7 with rspack-resolver#54, which is eventually replaced by oxc-resolver#443
Rust port of enhanced-resolve.
tsconfig.extends
tsconfig.compilerOptions.paths
tsconfig.references
FileSystem
trait.tracing
instrumentation.See index.d.ts
for resolveSync
and ResolverFactory
API.
Quick example:
import assert from 'node:assert';
import path from 'node:path';
import resolve, { ResolverFactory } from 'unrs-resolver';
// `resolve`
assert(resolve.sync(process.cwd(), './index.js').path, path.resolve('index.js'));
// `ResolverFactory`
const resolver = new ResolverFactory();
assert(resolver.sync(process.cwd(), './index.js').path, path.resolve('index.js'));
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"
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
browser
field 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 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 |
descriptionFiles | ["package.json"] | A list of description files to read from |
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, if possible. |
Field | Default | Description |
---|---|---|
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 |
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
.
OXC_LOG=DEBUG your_program
RD_LOG='oxc_resolver' rolldown build
Tests are ported from
Test cases are located in ./src/tests
, fixtures are located in ./tests
crates/oxc_resolver/src/request.rs
)crates/oxc_resolver/src/path.rs
)Irrelevant tests
1stG | UnRs | UnTS |
---|---|---|
1stG | UnRs | UnTS |
---|---|---|
unrs_resolver
is free and open-source software licensed under the MIT License.
UnRS 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 |
oxc-project/oxc-resolver | MIT |
web-infra-dev/rspack-resolver | MIT |
FAQs
UnRS Resolver Node API with PNP support
The npm package unrs-resolver receives a total of 10,254,065 weekly downloads. As such, unrs-resolver popularity was classified as popular.
We found that unrs-resolver demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.
Product
Socket’s precomputed reachability slashes false positives by flagging up to 80% of vulnerabilities as irrelevant, with no setup and instant results.
Product
Socket is launching experimental protection for Chrome extensions, scanning for malware and risky permissions to prevent silent supply chain attacks.