### Initialize and Install Project Dependencies Source: https://github.com/oxc-project/oxc-resolver/blob/main/CONTRIBUTING.md Run these commands to set up the project environment and install necessary dependencies. ```bash just init just install just ready ``` -------------------------------- ### Run Rust Examples and Tests Source: https://github.com/oxc-project/oxc-resolver/blob/main/CONTRIBUTING.md Commands for executing examples with a specified path and running tests within the Rust environment. ```bash just example /path/to/directory specifier ``` ```bash just test ``` -------------------------------- ### Implement Custom FileSystem with MemoryFileSystem Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Implement the `FileSystem` trait to provide a custom backing store. This example shows a `MemoryFileSystem` for testing purposes. It requires implementing methods like `read`, `metadata`, and `read_link`. ```rust use std::{io, path::{Path, PathBuf}}; use oxc_resolver::{FileMetadata, FileSystem, ResolveError, ResolverGeneric, ResolveOptions}; struct MemoryFileSystem { // Map from path string to file contents files: std::collections::HashMap>, } impl FileSystem for MemoryFileSystem { fn new() -> Self { Self { files: Default::default() } } fn read(&self, path: &Path) -> io::Result> { self.files .get(&path.to_string_lossy().to_string()) .cloned() .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "file not found")) } fn read_to_string(&self, path: &Path) -> io::Result { let bytes = self.read(path)?; String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) } fn metadata(&self, path: &Path) -> io::Result { let key = path.to_string_lossy().to_string(); if self.files.contains_key(&key) { return Ok(FileMetadata::new(true, false, false)); } // Check if any file starts with this as a prefix (directory detection) let dir_prefix = format!("{}/", key.trim_end_matches('/')); if self.files.keys().any(|k| k.starts_with(&dir_prefix)) { return Ok(FileMetadata::new(false, true, false)); } Err(io::Error::new(io::ErrorKind::NotFound, "not found")) } fn symlink_metadata(&self, path: &Path) -> io::Result { self.metadata(path) } fn read_link(&self, _path: &Path) -> Result { Err(io::Error::new(io::ErrorKind::NotFound, "no symlinks").into()) } fn canonicalize(&self, path: &Path) -> io::Result { Ok(path.to_path_buf()) } } // Use it with the generic resolver let mut vfs = MemoryFileSystem { files: Default::default() }; vfs.files.insert( "/project/src/index.js".to_string(), b"export default 42;".to_vec(), ); vfs.files.insert( "/project/src/package.json".to_string(), br#"{"name":"app","main":"index.js"}"#.to_vec(), ); let resolver = ResolverGeneric::new_with_file_system(vfs, ResolveOptions::default()); let result = resolver.resolve("/project/src", "./index.js").unwrap(); assert_eq!(result.path(), Path::new("/project/src/index.js")); ``` -------------------------------- ### npm package - File-based Resolution Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Provides examples for file-based resolution using `resolveFileSync` and `resolveFileAsync`, which automatically discover tsconfig.json. ```APIDOC ## File-based Resolution ### Description Resolves a module specifier from a specific file path, automatically discovering and using the relevant tsconfig.json. ### Method `resolver.resolveFileSync(file, specifier)` (synchronous) `resolver.resolveFileAsync(file, specifier)` (asynchronous) ### Parameters - **file** (string) - The absolute path to the file to resolve from. - **specifier** (string) - The module specifier to resolve. ### Request Example ```javascript const resolver = new ResolverFactory(); // Synchronous resolution const syncResult = resolver.resolveFileSync("/path/to/file.ts", "./module"); // Asynchronous resolution const asyncResult = await resolver.resolveFileAsync("/path/to/file.ts", "./module"); ``` ### Key Differences - `sync(directory, specifier)`: Resolves from a directory and uses manually configured tsconfig. - `resolveFileSync(file, specifier)`: Resolves from a file and automatically discovers tsconfig.json by traversing parent directories. ``` -------------------------------- ### ResolverFactory#resolveFileSync / resolveFileAsync - Resolve from a file with auto tsconfig discovery (JS) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Explains how to resolve modules starting from a specific file, with automatic `tsconfig.json` discovery. This is crucial for accurate path-alias resolution in monorepos or projects using project references. ```APIDOC ## ResolverFactory#resolveFileSync / resolveFileAsync - Resolve from a file with auto tsconfig discovery (JS) ### Description Explains how to resolve modules starting from a specific file, with automatic `tsconfig.json` discovery. This is crucial for accurate path-alias resolution in monorepos or projects using project references. ### Usage ```javascript import path from "node:path"; import { ResolverFactory } from "oxc-resolver"; const resolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".ts", ".tsx", ".js"], tsconfig: "auto", // auto-discover tsconfig from the file location }); const containingFile = path.resolve("./packages/app/src/index.ts"); // Sync const result = resolver.resolveFileSync(containingFile, "@ui/Button"); if (!result.error) { console.log(result.path); // /project/packages/ui/src/Button.tsx (resolved via tsconfig paths) } // Async const asyncResult = await resolver.resolveFileAsync(containingFile, "../utils/format"); console.log(asyncResult.path); ``` ``` -------------------------------- ### Resolve files with auto tsconfig discovery in JS Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Demonstrates using resolveFileSync and resolveFileAsync with the 'auto' tsconfig option for automatic discovery. This is crucial for correct path-alias resolution in monorepo or project-reference setups. ```javascript import path from "node:path"; import { ResolverFactory } from "oxc-resolver"; const resolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".ts", ".tsx", ".js"], tsconfig: "auto", // auto-discover tsconfig from the file location }); const containingFile = path.resolve("./packages/app/src/index.ts"); // Sync const result = resolver.resolveFileSync(containingFile, "@ui/Button"); if (!result.error) { console.log(result.path); // /project/packages/ui/src/Button.tsx (resolved via tsconfig paths) } // Async const asyncResult = await resolver.resolveFileAsync(containingFile, "../utils/format"); console.log(asyncResult.path); ``` -------------------------------- ### Invalidate File-System Cache Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Clear all cached directory entries and `package.json` data using `clear_cache`. Call this when the file system changes, for example, after an `npm install`. The caller must guarantee no concurrent resolution is in progress. ```rust use oxc_resolver::{ResolveOptions, Resolver}; let resolver = Resolver::new(ResolveOptions::default()); // ... perform resolutions ... // After file-system changes: resolver.clear_cache(); ``` -------------------------------- ### Build and Test Napi Module Source: https://github.com/oxc-project/oxc-resolver/blob/main/CONTRIBUTING.md Commands to build the Napi module and run its associated tests. ```bash pnpm run build ``` ```bash pnpm test ``` -------------------------------- ### Basic Resolution with Oxc Resolver (npm) Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Demonstrates basic usage of the `resolve` and `ResolverFactory` APIs from the npm package for synchronous resolution. Ensure `cwd` is correctly set for path joining. ```javascript 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")); ``` -------------------------------- ### Resolver::clear_cache Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Invalidates the entire file system cache, including directory entries and package.json data. This should be called after file system changes, such as after an `npm install`. ```APIDOC ## Resolver::clear_cache ### Description Clears the internal file system cache. Use this after modifying the file system to ensure accurate resolution. ### Method `clear_cache` ### Parameters None ### Request Example ```rust use oxc_resolver::{ResolveOptions, Resolver}; let resolver = Resolver::new(ResolveOptions::default()); // ... perform resolutions ... // After file-system changes: resolver.clear_cache(); ``` ### Response None. This method modifies the internal state of the `Resolver`. ``` -------------------------------- ### ResolverFactory - Create a JS resolver instance Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Demonstrates how to create instances of the resolver using ResolverFactory, with options for module type, conditions, extensions, and aliases. It also shows how to clone resolvers with different options and clear the cache. ```APIDOC ## ResolverFactory - Create a JS resolver instance ### Description Demonstrates how to create instances of the resolver using `ResolverFactory`, with options for module type, conditions, extensions, and aliases. It also shows how to clone resolvers with different options and clear the cache. ### Usage ```javascript import { ResolverFactory } from "oxc-resolver"; // ESM resolver const esmResolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".js", ".ts", ".mjs"], extensionAlias: { ".js": [".ts", ".js"] }, aliasFields: ["browser"], tsconfig: { configFile: "./tsconfig.json", references: "auto" }, moduleType: true, }); // Clone with CJS conditions, sharing the same internal cache const cjsResolver = esmResolver.cloneWithOptions({ conditionNames: ["node", "require"], }); // Clear cache after file-system changes esmResolver.clearCache(); ``` ``` -------------------------------- ### Rust API Usage Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Demonstrates how to initialize and use the Resolver in Rust for module resolution. ```APIDOC ## Rust API Usage ### Description This snippet shows the basic initialization and usage of the `Resolver` in Rust. ### Method ```rust use oxc_resolver::{ResolveOptions, Resolver}; let options = ResolveOptions::default(); let resolver = Resolver::new(options); let resolution = resolver.resolve("/path/to/project", "./module"); ``` ``` -------------------------------- ### File-based Resolution with tsconfig Discovery (npm) Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Shows how to use `resolveFileSync` and `resolveFileAsync` for resolving modules from a specific file path, with automatic tsconfig discovery. `resolveFileSync` is preferred when the resolution context is a file, not a directory. ```javascript 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"); ``` -------------------------------- ### Configure Resolver Options in Rust Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Shows how to incrementally build ResolveOptions, specifying condition names, file extensions, and main fields for module resolution. ```rust let options = ResolveOptions { condition_names: vec!["node".to_string(), "import".to_string()], extensions: vec![ ".js".to_string(), ".ts".to_string()], main_fields: vec!["module".to_string(), "main".to_string()], ..Default::default() }; ``` -------------------------------- ### npm package - Basic Resolution Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Demonstrates basic usage of the `resolve` function and `ResolverFactory` for synchronous module resolution. ```APIDOC ## Basic Resolution ### Description Synchronously resolves a module specifier from a given directory. ### Method `resolve.sync(directory, specifier)` or `resolver.sync(directory, specifier)` ### Parameters - **directory** (string) - The absolute path to the directory to resolve from. - **specifier** (string) - The module specifier to resolve. ### Request Example ```javascript import assert from "assert"; import path from "path"; import resolve, { ResolverFactory } from "./index.js"; const cwd = process.cwd(); // Using resolve.sync assert(resolve.sync(cwd, "./index.js").path, path.join(cwd, "index.js")); // Using ResolverFactory const resolver = new ResolverFactory(); assert(resolver.sync(cwd, "./index.js").path, path.join(cwd, "index.js")); ``` ### Response #### Success Response (200) - **path** (string) - The absolute path to the resolved module. ``` -------------------------------- ### Run all checks with `just ready` Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Always run `just ready` as the last step after code has been committed to the repository to ensure all checks pass. ```bash just ready ``` -------------------------------- ### ResolverFactory#sync / ResolverFactory#async - Resolve from a directory (JS) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Shows how to resolve modules from a specified directory using synchronous (`sync`) and asynchronous (`async`) methods. It covers handling results, including errors, built-in modules, and resolved paths. ```APIDOC ## ResolverFactory#sync / ResolverFactory#async - Resolve from a directory (JS) ### Description Shows how to resolve modules from a specified directory using synchronous (`sync`) and asynchronous (`async`) methods. It covers handling results, including errors, built-in modules, and resolved paths. ### Usage ```javascript import path from "node:path"; import { ResolverFactory } from "oxc-resolver"; const resolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".js", ".ts"], alias: { "@/": ["./src/"] }, builtinModules: true, }); const dir = path.resolve("./src"); // Synchronous const syncResult = resolver.sync(dir, "react"); if (syncResult.error) { console.error("Error:", syncResult.error); } else if (syncResult.builtin) { // { resolved: "node:fs", isRuntimeModule: false } console.log("Builtin:", syncResult.builtin.resolved); } else { console.log("Path:", syncResult.path); // /project/node_modules/react/index.js console.log("Module type:", syncResult.moduleType); // "module" | "commonjs" | "json" | "wasm" | "addon" console.log("package.json:", syncResult.packageJsonPath); } // Asynchronous const asyncResult = await resolver.async(dir, "lodash/merge"); console.log(asyncResult.path); ``` ``` -------------------------------- ### Format code with `just fmt` Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Use `just fmt` to format the code, applying both `cargo fmt` and `vp fmt`. ```bash just fmt ``` -------------------------------- ### Create JS resolver instances with ResolverFactory Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Shows how to create ESM and CJS resolvers using ResolverFactory, including options for condition names, extensions, aliases, and tsconfig. Demonstrates cloning resolvers with different options and clearing the cache. ```javascript import { ResolverFactory } from "oxc-resolver"; // ESM resolver const esmResolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".js", ".ts", ".mjs"], extensionAlias: { ".js": [".ts", ".js"] }, aliasFields: ["browser"], tsconfig: { configFile: "./tsconfig.json", references: "auto" }, moduleType: true, }); // Clone with CJS conditions, sharing the same internal cache const cjsResolver = esmResolver.cloneWithOptions({ conditionNames: ["node", "require"], }); // Clear cache after file-system changes esmResolver.clearCache(); ``` -------------------------------- ### Oxc Resolver Configuration Options (JS) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Demonstrates extensive configuration options for `ResolverFactory`, including tsconfig, aliases, condition names, extensions, fallbacks, and more. Use to customize resolution behavior. ```javascript import { ResolverFactory, EnforceExtension } from "oxc-resolver"; const resolver = new ResolverFactory({ // tsconfig: path string or { configFile, references } or "auto" tsconfig: { configFile: "./tsconfig.json", references: "auto" }, // Path aliases: null/undefined values become AliasValue::Ignore alias: { "@/": ["./src/"], "legacy": [null], // ignore this specifier }, // Browser field substitution for bundlers aliasFields: ["browser"], // exports field conditions conditionNames: ["node", "import"], // Force explicit file extensions enforceExtension: EnforceExtension.Disabled, // Custom exports fields path (e.g. nested in package.json) exportsFields: [["exports"]], // Map .js imports to .ts sources extensionAlias: { ".js": [".ts", ".js"], ".mjs": [".mts", ".mjs"] }, extensions: [".ts", ".tsx", ".js", ".jsx", ".json"], // Fallback when resolution fails fallback: { "path": ["./polyfills/path.js"] }, fullySpecified: false, mainFields: ["module", "main"], mainFiles: ["index"], modules: ["node_modules"], preferRelative: false, preferAbsolute: false, // Restrict resolution to paths matching the restriction restrictions: [{ path: "/project" }], roots: ["/project/public"], symlinks: true, nodePath: true, builtinModules: false, // set true to get { builtin } in results moduleType: false, // set true to get moduleType in results allowPackageExportsInDirectoryResolve: false, }); ``` -------------------------------- ### Rust Resolver Initialization and Resolution Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Initialize the Rust resolver with default options and perform a module resolution. Ensure `oxc_resolver` is imported. ```rust use oxc_resolver::{ResolveOptions, Resolver}; let options = ResolveOptions::default(); let resolver = Resolver::new(options); let resolution = resolver.resolve("/path/to/project", "./module"); ``` -------------------------------- ### Configuration: NapiResolveOptions — All options (JS) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Provides a comprehensive list of all available configuration options for the `ResolverFactory` when used in JavaScript. ```APIDOC ## Configuration: `NapiResolveOptions` — All options (JS) ```javascript import { ResolverFactory, EnforceExtension } from "oxc-resolver"; const resolver = new ResolverFactory({ // tsconfig: path string or { configFile, references } or "auto" tsconfig: { configFile: "./tsconfig.json", references: "auto" }, // Path aliases: null/undefined values become AliasValue::Ignore alias: { "@/": ["./src/"], "legacy": [null], // ignore this specifier }, // Browser field substitution for bundlers aliasFields: ["browser"], // exports field conditions conditionNames: ["node", "import"], // Force explicit file extensions enforceExtension: EnforceExtension.Disabled, // Custom exports fields path (e.g. nested in package.json) exportsFields: [["exports"]], // Map .js imports to .ts sources extensionAlias: { ".js": [".ts", ".js"], ".mjs": [".mts", ".mjs"] }, extensions: [".ts", ".tsx", ".js", ".jsx", ".json"], // Fallback when resolution fails fallback: { "path": ["./polyfills/path.js"] }, fullySpecified: false, mainFields: ["module", "main"], mainFiles: ["index"], modules: ["node_modules"], preferRelative: false, preferAbsolute: false, // Restrict resolution to paths matching the restriction restrictions: [{ path: "/project" }], roots: ["/project/public"], symlinks: true, nodePath: true, builtinModules: false, // set true to get { builtin } in results moduleType: false, // set true to get moduleType in results allowPackageExportsInDirectoryResolve: false, }); ``` ``` -------------------------------- ### Run all tests with `just test` Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Execute all tests, including both Rust and Node.js tests, using the `just test` command. ```bash just test ``` -------------------------------- ### Run clippy with strict settings Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Execute `just lint` to run clippy with strict settings, ensuring code quality. ```bash just lint ``` -------------------------------- ### Main Field Configuration Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Configure the resolver to prioritize 'module' and 'main' fields for package entry points, aligning with Node.js and bundler conventions. ```json { "mainFields": ["module", "main"] } ``` -------------------------------- ### Top-Level Default Sync Resolver (JS) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt A zero-config synchronous resolver exported directly from the package. Equivalent to `new ResolverFactory().sync(...)`. Requires 'oxc-resolver' and 'node:path'. ```javascript import path from "node:path"; import resolve from "oxc-resolver"; const result = resolve.sync(path.resolve("."), "./src/index.js"); if (result.error) { console.error(result.error); } else { console.log(result.path); // /project/src/index.js } ``` -------------------------------- ### Node.js API Usage Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Illustrates how to use the oxc-resolver Node.js bindings for simple and advanced module resolution. ```APIDOC ## Node.js API Usage ### Description This snippet demonstrates how to use the `oxc-resolver` Node.js bindings for both simple synchronous resolution and more advanced configurations. ### Simple Resolve ```javascript import resolve from "oxc-resolver"; const result = resolve.sync(process.cwd(), "./module"); ``` ### Advanced Usage ```javascript import { ResolverFactory } from "oxc-resolver"; const resolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".js", ".ts", ".json"], }); ``` ``` -------------------------------- ### Resolve modules synchronously and asynchronously in JS Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Illustrates using ResolverFactory's sync and async methods to resolve modules from a given directory. Covers handling errors, identifying builtin modules, and accessing resolution details like path, module type, and package.json location. ```javascript import path from "node:path"; import { ResolverFactory } from "oxc-resolver"; const resolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".js", ".ts"], alias: { "@/": ["./src/"] }, builtinModules: true, }); const dir = path.resolve("./src"); // Synchronous const syncResult = resolver.sync(dir, "react"); if (syncResult.error) { console.error("Error:", syncResult.error); } else if (syncResult.builtin) { // { resolved: "node:fs", isRuntimeModule: false } console.log("Builtin:", syncResult.builtin.resolved); } else { console.log("Path:", syncResult.path); // /project/node_modules/react/index.js console.log("Module type:", syncResult.moduleType); // "module" | "commonjs" | "json" | "wasm" | "addon" console.log("package.json:", syncResult.packageJsonPath); } // Asynchronous const asyncResult = await resolver.async(dir, "lodash/merge"); console.log(asyncResult.path); ``` -------------------------------- ### Handle Resolver Errors in Rust Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Demonstrates how to match on different ResolveError kinds, specifically handling 'NotFound' errors separately from other potential resolution issues. ```rust use oxc_resolver::{ResolveError, ResolveErrorKind}; match resolver.resolve(path, specifier) { Ok(resolution) => { /* handle success */ }, Err(ResolveError { kind: ResolveErrorKind::NotFound, .. }) => { /* handle not found */ }, Err(err) => { /* handle other errors */ } } ``` -------------------------------- ### Full ResolveOptions Reference Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Configure resolution behavior using `ResolveOptions`, which is compatible with webpack's `enhanced-resolve`. Builder methods provide a fluent API for constructing options. ```rust use oxc_resolver::{ AliasValue, EnforceExtension, ResolveOptions, Restriction, TsconfigDiscovery, TsconfigOptions, TsconfigReferences, }; use std::path::PathBuf; let options = ResolveOptions { // TypeScript: manual or auto tsconfig discovery tsconfig: Some(TsconfigDiscovery::Manual(TsconfigOptions { config_file: PathBuf::from("/project/tsconfig.json"), references: TsconfigReferences::Auto, })), // Aliases: "@utils" -> "./src/utils", "legacy-pkg" -> false (ignore) alias: vec![ ("@utils".into(), vec![AliasValue::Path("./src/utils".into())]), ("legacy-pkg".into(), vec![AliasValue::Ignore]), ], // browser field substitution alias_fields: vec![vec!["browser".into()]], // exports condition matching condition_names: vec!["node".into(), "import".into()], // try .ts before .js extensions: vec![ ".ts".into(), ".tsx".into(), ".js".into(), ".jsx".into()], // .js imports may resolve to .ts sources extension_alias: vec![(".js".into(), vec![ ".ts".into(), ".js".into()])], // prefer module/main fields main_fields: vec!["module".into(), "main".into()], // fallback when resolution fails fallback: vec![("assert".into(), vec![AliasValue::Path("./polyfills/assert".into())])], // resolve symlinks to real paths symlinks: true, // detect module type (module/commonjs) module_type: true, // restrict resolution to a specific directory restrictions: vec![Restriction::Path(PathBuf::from("/project"))], ..ResolveOptions::default() } // Builder-style fluent API .with_condition_names(&["node", "import"]) .with_extension(".jsonc") .with_main_field("module") .with_prefer_relative(true) .with_symbolic_link(false); ``` -------------------------------- ### Resolver::new / ResolverGeneric::new_with_file_system Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Constructs a resolver instance. `Resolver` is an alias for `ResolverGeneric`. `new_with_file_system` allows injecting custom file systems. Supports ESM and CJS resolution with various options like condition names, extensions, aliases, and tsconfig discovery. ```APIDOC ## Resolver::new / ResolverGeneric::new_with_file_system — Create a resolver Construct a resolver from `ResolveOptions`. `Resolver` is an alias for `ResolverGeneric`. Use `new_with_file_system` to inject a custom or in-memory file system. ### Parameters - **options** (`ResolveOptions`): Configuration options for the resolver. ### Returns - `Resolver` or `ResolverGeneric`: An instance of the resolver. ### Request Example ```rust use oxc_resolver::{ AliasValue, ResolveOptions, Resolver, TsconfigDiscovery, TsconfigOptions, TsconfigReferences, }; use std::path::PathBuf; // ESM resolver with tsconfig path alias support let resolver = Resolver::new(ResolveOptions { condition_names: vec!["node".into(), "import".into()], extensions: vec![ ".js".into(), ".ts".into() ], extension_alias: vec![(".js".into(), vec![ ".ts".into(), ".js".into() ])], alias_fields: vec![vec!["browser".into()]], alias: vec![ ("@/".into(), vec![AliasValue::Path("./src/".into())]), ], tsconfig: Some(TsconfigDiscovery::Manual(TsconfigOptions { config_file: PathBuf::from("tsconfig.json"), references: TsconfigReferences::Auto, })), ..ResolveOptions::default() }); // CJS resolver sharing cache with the ESM resolver let cjs_resolver = resolver.clone_with_options(ResolveOptions { condition_names: vec!["node".into(), "require".into()], ..ResolveOptions::default() }); ``` ``` -------------------------------- ### ResolveOptions Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Provides a comprehensive reference for all available resolution options, compatible with webpack's `enhanced-resolve`. A fluent API is available for constructing these options. ```APIDOC ## ResolveOptions ### Description Configuration object for controlling module resolution behavior. All options are compatible with webpack's `enhanced-resolve`. ### Fields - `tsconfig` (Option): Configuration for TypeScript configuration file discovery. - `alias` (Vec<(String, Vec)>): Defines path aliases for module resolution. - `alias_fields` (Vec>): Specifies fields in `package.json` to use for aliasing (e.g., `"browser"`). - `condition_names` (Vec): List of condition names for package exports matching (e.g., `"node"`, `"import"`). - `extensions` (Vec): File extensions to try when resolving modules (e.g., `".ts"`, `".js"`). - `extension_alias` (Vec<(String, Vec)>): Maps file extensions to alternative extensions for resolution (e.g., `".js"` can resolve to `".ts"`). - `main_fields` (Vec): Fields to look for in `package.json` to determine the main entry point (e.g., `"module"`, `"main"`). - `fallback` (Vec<(String, Vec)>): Provides fallback resolution paths when a module cannot be found. - `symlinks` (bool): Whether to resolve symlinks to their real paths. - `module_type` (bool): Whether to detect module type (CommonJS or ESM). - `restrictions` (Vec): Restricts resolution to specific directories or patterns. ### Builder API Methods like `with_condition_names`, `with_extension`, `with_main_field`, `with_prefer_relative`, `with_symbolic_link` allow for fluent construction of `ResolveOptions`. ### Request Example ```rust use oxc_resolver::{ AliasValue, EnforceExtension, ResolveOptions, Restriction, TsconfigDiscovery, TsconfigOptions, TsconfigReferences, }; use std::path::PathBuf; let options = ResolveOptions { // TypeScript: manual or auto tsconfig discovery tsconfig: Some(TsconfigDiscovery::Manual(TsconfigOptions { config_file: PathBuf::from("/project/tsconfig.json"), references: TsconfigReferences::Auto, })), // Aliases: "@utils" -> "./src/utils", "legacy-pkg" -> false (ignore) alias: vec![ ("@utils".into(), vec![AliasValue::Path("./src/utils".into())]), ("legacy-pkg".into(), vec![AliasValue::Ignore]), ], // browser field substitution alias_fields: vec![vec!["browser".into()]], // exports condition matching condition_names: vec!["node".into(), "import".into()], // try .ts before .js extensions: vec![ ".ts".into(), ".tsx".into(), ".js".into(), ".jsx".into() ], // .js imports may resolve to .ts sources extension_alias: vec![(".js".into(), vec![ ".ts".into(), ".js".into() ])], // prefer module/main fields main_fields: vec!["module".into(), "main".into()], // fallback when resolution fails fallback: vec![("assert".into(), vec![AliasValue::Path("./polyfills/assert".into())])], // resolve symlinks to real paths symlinks: true, // detect module type (module/commonjs) module_type: true, // restrict resolution to a specific directory restrictions: vec![Restriction::Path(PathBuf::from("/project"))], ..ResolveOptions::default() } // Builder-style fluent API .with_condition_names(&["node", "import"]) .with_extension(".jsonc") .with_main_field("module") .with_prefer_relative(true) .with_symbolic_link(false); ``` ``` -------------------------------- ### Resolve with Dependency Tracking Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Use `resolve_with_context` to track file system paths probed during resolution. This is useful for build tools that need to invalidate caches when files change. ```rust use oxc_resolver::{ResolveContext, ResolveOptions, Resolver}; use std::path::Path; let resolver = Resolver::new(ResolveOptions::default()); let mut ctx = ResolveContext::default(); match resolver.resolve_with_context( Path::new("/project/src"), "./components/Button", None, &mut ctx, ) { Ok(resolution) => { println!("Resolved: {}", resolution.path().display()); println!("Files checked: {:?}", ctx.file_dependencies); println!("Missing files: {:?}", ctx.missing_dependencies); } Err(err) => eprintln!("Error: {err}"), } ``` -------------------------------- ### Perform cargo check with all features Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Use `just check` to perform a cargo check with all features enabled. ```bash just check ``` -------------------------------- ### sync — Top-level default sync resolver (JS) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt A zero-config synchronous resolver exported directly from the package. It is equivalent to `new ResolverFactory().sync(...)`. ```APIDOC ## `sync` — Top-level default sync resolver (JS) A zero-config synchronous resolver exported directly from the package—equivalent to `new ResolverFactory().sync(...)`. ```javascript import path from "node:path"; import resolve from "oxc-resolver"; const result = resolve.sync(path.resolve("."), "./src/index.js"); if (result.error) { console.error(result.error); } else { console.log(result.path); // /project/src/index.js } ``` ``` -------------------------------- ### Enable Debug Tracing in Node.js Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Command to enable detailed tracing logs for oxc-resolver when running a Node.js program. ```bash OXC_LOG=DEBUG node your_program.js ``` -------------------------------- ### Resolver Caching with Different Conditions Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Create a base resolver for ESM and clone it with different options for CJS to support both with the same cache. ```javascript const esmResolver = new ResolverFactory({ conditionNames: ["node", "import"], }); const cjsResolver = esmResolver.cloneWithOptions({ conditionNames: ["node", "require"], }); ``` -------------------------------- ### Node.js Advanced Resolver Configuration Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Configure and create an advanced resolver instance in Node.js using `ResolverFactory`. Specify options like `conditionNames` and `extensions`. ```javascript // Advanced usage const resolver = new ResolverFactory({ conditionNames: ["node", "import"], extensions: [".js", ".ts", ".json"], }); ``` -------------------------------- ### Enable Debug Tracing in Rust Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Command to enable detailed tracing logs for the oxc_resolver crate when running tests. ```bash RUST_LOG=oxc_resolver=debug cargo test ``` -------------------------------- ### Create ESM and CJS Resolvers with Tsconfig Aliases (Rust) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Constructs an ESM resolver with tsconfig path alias support and clones it for a CJS resolver. Requires `oxc_resolver` crate. ```rust use oxc_resolver::{ AliasValue, ResolveOptions, Resolver, TsconfigDiscovery, TsconfigOptions, TsconfigReferences, }; use std::path::PathBuf; // ESM resolver with tsconfig path alias support let resolver = Resolver::new(ResolveOptions { condition_names: vec!["node".into(), "import".into()], extensions: vec![ ".js".into(), ".ts".into() ], extension_alias: vec![(".js".into(), vec![ ".ts".into(), ".js".into() ])], alias_fields: vec![vec!["browser".into()]], alias: vec![ ("@/".into(), vec![AliasValue::Path("./src/".into())]), ], tsconfig: Some(TsconfigDiscovery::Manual(TsconfigOptions { config_file: PathBuf::from("tsconfig.json"), references: TsconfigReferences::Auto, })), ..ResolveOptions::default() }); // CJS resolver sharing cache with the ESM resolver let cjs_resolver = resolver.clone_with_options(ResolveOptions { condition_names: vec!["node".into(), "require".into()], ..ResolveOptions::default() }); ``` -------------------------------- ### Oxc Resolver Tracing Output Format Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Illustrates the structured format of debugging logs produced by oxc-resolver when tracing is enabled. Useful for diagnosing resolution issues. ```text 2024-06-11T07:12:20.003537Z DEBUG oxc_resolver: options: ResolveOptions { ... }, path: "...", specifier: "...", ret: "..." at src/lib.rs:212 in oxc_resolver::resolve with path: "...", specifier: "..." ``` -------------------------------- ### Resolver::clone_with_options Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Clones a resolver instance with new options while sharing the underlying file system cache. This is efficient for scenarios requiring different resolution strategies (e.g., ESM vs. CJS) within the same process. ```APIDOC ## Resolver::clone_with_options ### Description Creates a new resolver with specified options, reusing the existing file system cache for efficiency. ### Method `clone_with_options` ### Parameters - `options` (ResolveOptions): The new resolution options to apply to the cloned resolver. ### Request Example ```rust use oxc_resolver::{ResolveOptions, Resolver}; let esm_resolver = Resolver::new(ResolveOptions { condition_names: vec!["node".into(), "import".into()], extensions: vec![ ".js".into(), ".mjs".into() ], ..ResolveOptions::default() }); // Shares internal cache — no redundant file-system reads let cjs_resolver = esm_resolver.clone_with_options(ResolveOptions { condition_names: vec!["node".into(), "require".into()], extensions: vec![ ".js".into(), ".cjs".into() ], ..ResolveOptions::default() }); // In tests, you would assert cache sharing like this: // assert!(esm_resolver.shares_cache_with(&cjs_resolver)); ``` ### Response - `Resolver`: A new `Resolver` instance with the provided options and shared cache. ``` -------------------------------- ### Browser Field Configuration Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Configure the resolver to use the 'browser' field for client-side module packaging, as per the non-standard spec. ```json { "aliasFields": ["browser"] } ``` -------------------------------- ### Enable oxc_resolver Debugging with Rolldown Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Configure the RD_LOG environment variable to 'oxc_resolver' to enable debugging output for oxc_resolver during a Rolldown build. ```bash RD_LOG='oxc_resolver' rolldown build ``` -------------------------------- ### Debugging Oxc Resolver with Tracing (Bash/Rust) Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Enables detailed debugging logs for oxc-resolver. Use `OXC_LOG=DEBUG` for Node.js, `RD_LOG='oxc_resolver'` for Rolldown, or `RUST_LOG=oxc_resolver=debug` for Rust applications. ```bash # NAPI (Node.js) — emit debug logs to stderr OXC_LOG=DEBUG node my_script.js # Rolldown integration RD_LOG='oxc_resolver' rolldown build # Rust (tracing subscriber must be initialized) RUST_LOG=oxc_resolver=debug cargo run ``` -------------------------------- ### Enable oxc_resolver Debugging with NAPI Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Set the OXC_LOG environment variable to DEBUG to enable tracing information for the oxc_resolver::resolve function when using NAPI. ```bash OXC_LOG=DEBUG your_program ``` -------------------------------- ### Node.js Simple Resolve Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md Perform a simple synchronous module resolution in Node.js using the `oxc-resolver` package. Ensure `resolve` is imported. ```javascript import resolve, { ResolverFactory } from "oxc-resolver"; // Simple resolve const result = resolve.sync(process.cwd(), "./module"); ``` -------------------------------- ### ESM Resolution Options Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Use these options when the caller is an ESM import. Corresponds to the ESM Resolution algorithm's default conditions. ```json { "conditionNames": ["node", "import"] } ``` -------------------------------- ### Resolver::resolve_with_context Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Resolves a module path with dependency tracking. It collects file system paths probed during resolution, which is useful for cache invalidation in build tools. ```APIDOC ## Resolver::resolve_with_context ### Description Resolves a module path and tracks file system interactions for cache invalidation. ### Method `resolve_with_context` ### Parameters - `path` (Path): The base path for resolution. - `request` (str): The module path to resolve. - `options` (Option): Optional resolution options. - `ctx` (ResolveContext): A mutable reference to a ResolveContext to collect dependencies. ### Request Example ```rust use oxc_resolver::{ResolveContext, ResolveOptions, Resolver}; use std::path::Path; let resolver = Resolver::new(ResolveOptions::default()); let mut ctx = ResolveContext::default(); match resolver.resolve_with_context( Path::new("/project/src"), "./components/Button", None, &mut ctx, ) { Ok(resolution) => { println!("Resolved: {}", resolution.path().display()); println!("Files checked: {:?}", ctx.file_dependencies); println!("Missing files: {:?}", ctx.missing_dependencies); } Err(err) => eprintln!("Error: {err}"), } ``` ### Response #### Success Response - `Resolution`: An object containing the resolved path and other resolution information. - `ResolveContext`: Updated with `file_dependencies` and `missing_dependencies`. ``` -------------------------------- ### Import JavaScript Modules from vite-plus Source: https://github.com/oxc-project/oxc-resolver/blob/main/AGENTS.md When importing JavaScript modules, always use 'vite-plus' as the source instead of 'vite' or 'vitest'. This ensures you are using the project's managed dependencies. ```javascript import { defineConfig } from 'vite-plus'; ``` ```javascript import { expect, test, vi } from 'vite-plus/test'; ``` -------------------------------- ### Handle ResolveError enum in Rust Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Demonstrates how to match against different ResolveError variants to handle various resolution failures, such as builtin modules, ignored modules, not found errors, and package.json issues. ```rust use oxc_resolver::{ResolveError, ResolveOptions, Resolver}; use std::path::Path; let resolver = Resolver::new(ResolveOptions { builtin_modules: true, ..ResolveOptions::default() }); match resolver.resolve(Path::new("/project"), "fs") { // Built-in module: treat as external Err(ResolveError::Builtin { resolved, is_runtime_module }) => { println!("Builtin: {resolved}, runtime prefix: {is_runtime_module}"); // "node:fs", false } // Module ignored via browser field false value Err(ResolveError::Ignored(path)) => { println!("Ignored: {}", path.display()); } // Module not found Err(ResolveError::NotFound(specifier)) => { eprintln!("Cannot find module '{}'", specifier); } // exports field does not export the requested subpath Err(ResolveError::PackagePathNotExported { subpath, package_path, conditions, .. }) => { eprintln!("'{{subpath}}' not exported from {}", package_path.display()); } // Broken package.json Err(ResolveError::Json(err)) => { eprintln!("JSON error in {}: {}", err.path.display(), err.message); } // Tsconfig circular extends Err(ResolveError::TsconfigCircularExtend(paths)) => { eprintln!("Circular tsconfig: {paths}"); } Ok(resolution) => println!("OK: {}", resolution.path().display()), Err(other) => eprintln!("Other error: {other}"), } ``` -------------------------------- ### Share Cache Across Resolver Variants Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Clone a resolver with different options while reusing the same underlying file-system cache using `clone_with_options`. This is ideal for supporting both ESM and CJS resolution in a single process without duplicating I/O. ```rust use oxc_resolver::{ResolveOptions, Resolver}; let esm_resolver = Resolver::new(ResolveOptions { condition_names: vec!["node".into(), "import".into()], extensions: vec![ ".js".into(), ".mjs".into()], ..ResolveOptions::default() }); // Shares internal cache — no redundant file-system reads let cjs_resolver = esm_resolver.clone_with_options(ResolveOptions { condition_names: vec!["node".into(), "require".into()], extensions: vec![ ".js".into(), ".cjs".into()], ..ResolveOptions::default() }); assert!( // Both resolvers share the same Arc true, // use resolver.shares_cache_with(&cjs_resolver) in tests ); ``` -------------------------------- ### CJS Resolution Options Source: https://github.com/oxc-project/oxc-resolver/blob/main/README.md Use these options when the caller is a CJS require. Corresponds to the CJS Resolution algorithm's default conditions. ```json { "conditionNames": ["node", "require"] } ``` -------------------------------- ### ResolverFactory#resolveDtsSync / resolveDtsAsync Source: https://context7.com/oxc-project/oxc-resolver/llms.txt Resolves .d.ts / .d.mts / .d.cts files using TypeScript's moduleResolution: "bundler" algorithm. This is useful for language servers and type-checking tools to locate declaration files independently of the runtime module. ```APIDOC ## `ResolverFactory#resolveDtsSync` / `resolveDtsAsync` — Resolve TypeScript declaration files Resolves `.d.ts` / `.d.mts` / `.d.cts` files using TypeScript's `moduleResolution: "bundler"` algorithm. Used by language servers and type-checking tools to locate declaration files independently of the runtime module. ```javascript import path from "node:path"; import { ResolverFactory } from "oxc-resolver"; const resolver = new ResolverFactory({ conditionNames: ["import", "types"], }); const containingFile = path.resolve("./src/index.ts"); // Sync DTS resolution const result = resolver.resolveDtsSync(containingFile, "magic-string"); if (!result.error) { console.log(result.path); // /project/node_modules/magic-string/dist/magic-string.es.d.mts } // Async DTS resolution const asyncResult = await resolver.resolveDtsAsync(containingFile, "vue"); console.log(asyncResult.path); // .../vue/dist/vue.d.ts ``` ```