Resolve like require.resolve() on behalf of files asynchronously and synchronously
—
Synchronous module resolution that implements the Node.js require.resolve() algorithm without callbacks, throwing errors instead of passing them to callback functions. Ideal for build-time processing and initialization scenarios.
Main synchronous resolution function that resolves module path strings into absolute file paths.
/**
* Synchronously resolve module path string
* @param {string} id - Module path string to resolve
* @param {object} [options] - Resolution options
* @returns {string} Resolved absolute path to the module
* @throws {Error} Resolution or validation errors
*/
function resolveSync(id, options);Usage Examples:
const resolve = require('resolve');
// Basic resolution
try {
const res = resolve.sync('lodash', { basedir: __dirname });
console.log(res); // /path/to/node_modules/lodash/index.js
} catch (err) {
console.error('Resolution failed:', err.message);
}
// Relative path resolution
const helperPath = resolve.sync('./utils/helper', {
basedir: '/project/src',
extensions: ['.js', '.json']
});
console.log(helperPath); // /project/src/utils/helper.js
// Alternative import method
const resolveSync = require('resolve/sync');
const modulePath = resolveSync('express', { basedir: __dirname });interface SyncResolveOptions {
/** Directory to begin resolving from (default: dirname of calling file) */
basedir?: string;
/** File extensions to search in order (default: ['.js']) */
extensions?: string[];
/** Include Node.js core modules in search (default: true) */
includeCoreModules?: boolean;
/** Don't resolve basedir to real path before resolving (default: true) */
preserveSymlinks?: boolean;
/** Directory names to search for modules (default: 'node_modules') */
moduleDirectory?: string | string[];
}Custom synchronous file system operations for testing, virtualization, or alternative storage backends.
interface SyncFileSystemOptions {
/** Custom sync file reading function */
readFileSync?: (file: string) => Buffer | string;
/** Custom sync file existence test function */
isFile?: (file: string) => boolean;
/** Custom sync directory existence test function */
isDirectory?: (dir: string) => boolean;
/** Custom sync symlink resolution function */
realpathSync?: (path: string) => string;
}Usage Example:
const fs = require('fs');
const resolve = require('resolve');
const res = resolve.sync('custom-module', {
basedir: __dirname,
readFileSync: (file) => {
console.log('Reading:', file);
return fs.readFileSync(file);
},
isFile: (file) => {
try {
const stat = fs.statSync(file);
return stat.isFile();
} catch {
return false;
}
}
});Transform package.json contents and handle custom package processing logic synchronously.
interface SyncPackageOptions {
/** Custom sync package.json reading function */
readPackageSync?: ReadPackageSyncFunction;
/** Transform package.json contents before looking at main field */
packageFilter?: (pkg: object, dir: string) => object;
/** Transform paths within packages */
pathFilter?: (pkg: object, path: string, relativePath: string) => string;
/** Custom package candidate path iterator */
packageIterator?: PackageIteratorFunction;
}
/**
* Custom sync package.json reading function
*/
interface ReadPackageSyncFunction {
(readFileSync: Function, pkgfile: string): object | undefined;
}
/**
* Custom package candidate path iterator
*/
interface PackageIteratorFunction {
(request: string, start: string, getPackageCandidates: () => string[], opts: SyncResolveOptions): string[];
}Usage Example:
const resolve = require('resolve');
const res = resolve.sync('my-package', {
basedir: __dirname,
packageFilter: (pkg, dir) => {
// Note: In sync version, second parameter is dir, not pkgfile
// This will change to pkgfile in v2
if (pkg.name === 'my-package') {
pkg.main = 'dist/index.js';
}
return pkg;
},
pathFilter: (pkg, path, relativePath) => {
if (pkg.name === 'my-package' && path.endsWith('.js')) {
return path.replace('.js', '.min.js');
}
return path;
}
});Control module search paths and path resolution behavior.
interface SyncPathOptions {
/** Custom require.paths array or function for path resolution */
paths?: string[] | PathsFunction;
}
/**
* Function for custom path resolution logic
*/
interface PathsFunction {
(request: string, start: string, getNodeModulesDirs: () => string[], opts: SyncResolveOptions): string[];
}Usage Example:
const resolve = require('resolve');
const res = resolve.sync('custom-lib', {
basedir: __dirname,
paths: (request, start, getNodeModulesDirs, opts) => {
const standardPaths = getNodeModulesDirs();
return ['/custom/modules', ...standardPaths];
}
});All sync resolution errors are thrown synchronously instead of being passed to callbacks.
interface ResolveError extends Error {
/** Error code indicating the type of resolution failure */
code: 'MODULE_NOT_FOUND' | 'INVALID_PACKAGE_MAIN';
/** Original error message */
message: string;
}MODULE_NOT_FOUND: The specified module path could not be resolved.
const resolve = require('resolve');
try {
resolve.sync('nonexistent-module', { basedir: __dirname });
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
console.error('Module not found:', err.message);
// "Cannot find module 'nonexistent-module' from '/current/directory'"
}
}INVALID_PACKAGE_MAIN: A package.json was encountered with an invalid main property.
try {
resolve.sync('broken-package', { basedir: __dirname });
} catch (err) {
if (err.code === 'INVALID_PACKAGE_MAIN') {
console.error('Invalid package main:', err.message);
// 'package "broken-package" `main` must be a string'
}
}The sync resolver uses the following default options when not specified:
const defaultOptions = {
paths: [],
basedir: __dirname, // Directory of calling file
extensions: ['.js'],
includeCoreModules: true,
readFileSync: fs.readFileSync,
isFile: function(file) {
try {
const stat = fs.statSync(file, { throwIfNoEntry: false });
return !!stat && (stat.isFile() || stat.isFIFO());
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
},
isDirectory: function(dir) {
try {
const stat = fs.statSync(dir, { throwIfNoEntry: false });
return !!stat && stat.isDirectory();
} catch (e) {
if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
throw e;
}
},
realpathSync: function(file) {
try {
const realpath = typeof fs.realpathSync.native === 'function'
? fs.realpathSync.native
: fs.realpathSync;
return realpath(file);
} catch (realPathErr) {
if (realPathErr.code !== 'ENOENT') throw realPathErr;
}
return file;
},
readPackageSync: function(readFileSync, pkgfile) {
const body = readFileSync(pkgfile);
try {
return JSON.parse(body);
} catch (jsonErr) {
// Return undefined for invalid JSON
}
},
moduleDirectory: 'node_modules',
preserveSymlinks: true
};Install with Tessl CLI
npx tessl i tessl/npm-resolve