Giter Club home page Giter Club logo

resolve's Introduction

resolve Version Badge

implements the node require.resolve() algorithm such that you can require.resolve() on behalf of a file asynchronously and synchronously

github actions coverage dependency status dev dependency status License Downloads

npm badge

example

asynchronously resolve:

var resolve = require('resolve/async'); // or, require('resolve')
resolve('tap', { basedir: __dirname }, function (err, res) {
    if (err) console.error(err);
    else console.log(res);
});
$ node example/async.js
/home/substack/projects/node-resolve/node_modules/tap/lib/main.js

synchronously resolve:

var resolve = require('resolve/sync'); // or, `require('resolve').sync
var res = resolve('tap', { basedir: __dirname });
console.log(res);
$ node example/sync.js
/home/substack/projects/node-resolve/node_modules/tap/lib/main.js

methods

var resolve = require('resolve');
var async = require('resolve/async');
var sync = require('resolve/sync');

For both the synchronous and asynchronous methods, errors may have any of the following err.code values:

  • MODULE_NOT_FOUND: the given path string (id) could not be resolved to a module
  • INVALID_BASEDIR: the specified opts.basedir doesn't exist, or is not a directory
  • INVALID_PACKAGE_MAIN: a package.json was encountered with an invalid main property (eg. not a string)

resolve(id, opts={}, cb)

Asynchronously resolve the module path string id into cb(err, res [, pkg]), where pkg (if defined) is the data from package.json.

options are:

  • opts.basedir - directory to begin resolving from

  • opts.package - package.json data applicable to the module being loaded

  • opts.extensions - array of file extensions to search in order

  • opts.includeCoreModules - set to false to exclude node core modules (e.g. fs) from the search

  • opts.readFile - how to read files asynchronously

  • opts.isFile - function to asynchronously test whether a file exists

  • opts.isDirectory - function to asynchronously test whether a file exists and is a directory

  • opts.realpath - function to asynchronously resolve a potential symlink to its real path

  • opts.readPackage(readFile, pkgfile, cb) - function to asynchronously read and parse a package.json file

    • readFile - the passed opts.readFile or fs.readFile if not specified
    • pkgfile - path to package.json
    • cb - callback. a SyntaxError error argument will be ignored, all other error arguments will be treated as an error.
  • opts.packageFilter(pkg, pkgfile, dir) - transform the parsed package.json contents before looking at the "main" field

    • pkg - package data
    • pkgfile - path to package.json
    • dir - directory that contains package.json
  • opts.pathFilter(pkg, path, relativePath) - transform a path within a package

    • pkg - package data
    • path - the path being resolved
    • relativePath - the path relative from the package.json location
    • returns - a relative path that will be joined from the package.json location
  • opts.paths - require.paths array to use if nothing is found on the normal node_modules recursive walk (probably don't use this)

    For advanced users, paths can also be a opts.paths(request, start, opts) function

    • request - the import specifier being resolved
    • start - lookup path
    • getNodeModulesDirs - a thunk (no-argument function) that returns the paths using standard node_modules resolution
    • opts - the resolution options
  • opts.packageIterator(request, start, opts) - return the list of candidate paths where the packages sources may be found (probably don't use this)

    • request - the import specifier being resolved
    • start - lookup path
    • getPackageCandidates - a thunk (no-argument function) that returns the paths using standard node_modules resolution
    • opts - the resolution options
  • opts.moduleDirectory - directory (or directories) in which to recursively look for modules. default: "node_modules"

  • opts.preserveSymlinks - if true, doesn't resolve basedir to real path before resolving. This is the way Node resolves dependencies when executed with the --preserve-symlinks flag.

default opts values:

{
    paths: [],
    basedir: __dirname,
    extensions: ['.js'],
    includeCoreModules: true,
    readFile: fs.readFile,
    isFile: function isFile(file, cb) {
        fs.stat(file, function (err, stat) {
            if (!err) {
                return cb(null, stat.isFile() || stat.isFIFO());
            }
            if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
            return cb(err);
        });
    },
    isDirectory: function isDirectory(dir, cb) {
        fs.stat(dir, function (err, stat) {
            if (!err) {
                return cb(null, stat.isDirectory());
            }
            if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false);
            return cb(err);
        });
    },
    realpath: function realpath(file, cb) {
        var realpath = typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath;
        realpath(file, function (realPathErr, realPath) {
            if (realPathErr && realPathErr.code !== 'ENOENT') cb(realPathErr);
            else cb(null, realPathErr ? file : realPath);
        });
    },
    readPackage: function defaultReadPackage(readFile, pkgfile, cb) {
        readFile(pkgfile, function (readFileErr, body) {
            if (readFileErr) cb(readFileErr);
            else {
                try {
                    var pkg = JSON.parse(body);
                    cb(null, pkg);
                } catch (jsonErr) {
                    cb(jsonErr);
                }
            }
        });
    },
    moduleDirectory: 'node_modules',
    preserveSymlinks: false
}

resolve.sync(id, opts)

Synchronously resolve the module path string id, returning the result and throwing an error when id can't be resolved.

options are:

  • opts.basedir - directory to begin resolving from

  • opts.extensions - array of file extensions to search in order

  • opts.includeCoreModules - set to false to exclude node core modules (e.g. fs) from the search

  • opts.readFileSync - how to read files synchronously

  • opts.isFile - function to synchronously test whether a file exists

  • opts.isDirectory - function to synchronously test whether a file exists and is a directory

  • opts.realpathSync - function to synchronously resolve a potential symlink to its real path

  • opts.readPackageSync(readFileSync, pkgfile) - function to synchronously read and parse a package.json file. a thrown SyntaxError will be ignored, all other exceptions will propagate.

    • readFileSync - the passed opts.readFileSync or fs.readFileSync if not specified
    • pkgfile - path to package.json
  • opts.packageFilter(pkg, pkgfile, dir) - transform the parsed package.json contents before looking at the "main" field

    • pkg - package data
    • pkgfile - path to package.json
    • dir - directory that contains package.json
  • opts.pathFilter(pkg, path, relativePath) - transform a path within a package

    • pkg - package data
    • path - the path being resolved
    • relativePath - the path relative from the package.json location
    • returns - a relative path that will be joined from the package.json location
  • opts.paths - require.paths array to use if nothing is found on the normal node_modules recursive walk (probably don't use this)

    For advanced users, paths can also be a opts.paths(request, start, opts) function

    • request - the import specifier being resolved
    • start - lookup path
    • getNodeModulesDirs - a thunk (no-argument function) that returns the paths using standard node_modules resolution
    • opts - the resolution options
  • opts.packageIterator(request, start, opts) - return the list of candidate paths where the packages sources may be found (probably don't use this)

    • request - the import specifier being resolved
    • start - lookup path
    • getPackageCandidates - a thunk (no-argument function) that returns the paths using standard node_modules resolution
    • opts - the resolution options
  • opts.moduleDirectory - directory (or directories) in which to recursively look for modules. default: "node_modules"

  • opts.preserveSymlinks - if true, doesn't resolve basedir to real path before resolving. This is the way Node resolves dependencies when executed with the --preserve-symlinks flag.

default opts values:

{
    paths: [],
    basedir: __dirname,
    extensions: ['.js'],
    includeCoreModules: true,
    readFileSync: fs.readFileSync,
    isFile: function isFile(file) {
        try {
            var stat = fs.statSync(file);
        } catch (e) {
            if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
            throw e;
        }
        return stat.isFile() || stat.isFIFO();
    },
    isDirectory: function isDirectory(dir) {
        try {
            var stat = fs.statSync(dir);
        } catch (e) {
            if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
            throw e;
        }
        return stat.isDirectory();
    },
    realpathSync: function realpathSync(file) {
        try {
            var 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 defaultReadPackageSync(readFileSync, pkgfile) {
        return JSON.parse(readFileSync(pkgfile));
    },
    moduleDirectory: 'node_modules',
    preserveSymlinks: false
}

install

With npm do:

npm install resolve

license

MIT

resolve's People

Contributors

arcanis avatar bouk avatar goto-bus-stop avatar j- avatar jaredhanson avatar jmm avatar joepie91 avatar justinbmeyer avatar keithamus avatar lgandecki avatar ljharb avatar mafintosh avatar manucorporat avatar matthewp avatar michaelficarra avatar nicolo-ribaudo avatar nirosugir avatar parshap avatar paulirish avatar pos777 avatar robert-chiniquy avatar searls avatar shinnn avatar simenb avatar stefanpenner avatar tcchau avatar thlorenz avatar tjenkinson avatar tootallnate avatar zkochan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

resolve's Issues

v1.1.0 breaks browserify API

I'm listening for package events in browserify and I'm using pkg.__dirname as documented.
With the latest release of this package, the __dirname points to all sorts of things. Sometimes the parent directory of the entry point, sometimes a .js file and in other cases it's correct.

Downgrading this module in my node_modules tree make it work fine again.

Any chance you could add a license?

I really need to use this kick-ass module but I work in a setting where people look for licenses etc.

Any chance you could add a license so that I could use it? MIT would be preferable.

Thanks in advance.
Krishnan

`extensions` not respected if `main` package file entry is found

There's is the extensions option to specify what extensions the file we want to resolve needs to have. This is not respected when the target is also the name of a module and that module has a main field in the package.json.

In my opinion the file specified in main should only be used if it satisfies the extensions filter.

Unable to resolve when node_modules is under a windows shared folder

Hi,

I'm unable to resolve certain modules when they are located under a windows shared folder. First, I'm using node-resolve 1.3.3 under windows 10 and node v6.9.1.

Here's the full trace:

02:35:56.273:  FATAL ERROR: Uncaught exception: Cannot find module 'deviceReporter' from '\\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\deviceReporter\configs' while trying to resolve require directive for deviceReporter in config at path \\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\deviceReporter\configs\gpii.deviceReporter.config.base.json while loading included configs for config at path //vboxsrv/vagrant/node_modules/universal/gpii/node_modules/deviceReporter/configs/gpii.deviceReporter.config.development.json while loading included configs for config at path //vboxsrv/vagrant/node_modules/universal/gpii/configs/gpii.config.development.all.local.json while loading included configs for config at path //vboxsrv/vagrant/node_modules/universal/tests/configs/gpii.tests.acceptance.localInstall.config.json while loading included configs for config at path \\vboxsrv\vagrant\node_modules\universal\tests\platform\windows\configs\gpii.tests.acceptance.windows.builtIn.config.json
Error: Cannot find module 'deviceReporter' from '\\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\deviceReporter\configs' while trying to resolve require directive for deviceReporter in config at path \\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\deviceReporter\configs\gpii.deviceReporter.config.base.json while loading included configs for config at path //vboxsrv/vagrant/node_modules/universal/gpii/node_modules/deviceReporter/configs/gpii.deviceReporter.config.development.json while loading included configs for config at path //vboxsrv/vagrant/node_modules/universal/gpii/configs/gpii.config.development.all.local.json while loading included configs for config at path //vboxsrv/vagrant/node_modules/universal/tests/configs/gpii.tests.acceptance.localInstall.config.json while loading included configs for config at path \\vboxsrv\vagrant\node_modules\universal\tests\platform\windows\configs\gpii.tests.acceptance.windows.builtIn.config.json
    at Function.module.exports [as sync] (\\vboxsrv\vagrant\node_modules\kettle\node_modules\resolve\lib\sync.js:40:15)
    at loadRequire (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:128:36)
    at Object.fluid.each (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:513:17)
    at Function.kettle.config.createDefaultsImpl (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:123:11)
    at loadConfigFromPath (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:81:44)
    at Object.fluid.each (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:513:17)
    at Function.kettle.config.loadSubConfigs (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:78:11)
    at Function.kettle.config.createDefaultsImpl (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:119:19)
    at loadConfigFromPath (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:81:44)
    at Object.fluid.each (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:513:17)
    at Function.kettle.config.loadSubConfigs (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:78:11)
    at Function.kettle.config.createDefaultsImpl (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:119:19)
    at loadConfigFromPath (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:81:44)
    at Object.fluid.each (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:513:17)
    at Function.kettle.config.loadSubConfigs (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:78:11)
    at Function.kettle.config.createDefaultsImpl (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:119:19)
    at loadConfigFromPath (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:81:44)
    at Object.fluid.each (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:513:17)
    at Function.kettle.config.loadSubConfigs (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:78:11)
    at Function.kettle.config.createDefaultsImpl (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:119:19)
    at Function.kettle.config.createDefaults (\\vboxsrv\vagrant\node_modules\kettle\lib\KettleConfigLoader.js:157:26)
    at Object.kettle.test.testDefToServerEnvironment (\\vboxsrv\vagrant\node_modules\kettle\lib\test\KettleTestUtils.js:250:65)
    at transformInternal (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:469:34)
    at fluid.transform (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:494:17)
    at Object.kettle.test.bootstrap (\\vboxsrv\vagrant\node_modules\kettle\lib\test\KettleTestUtils.js:276:33)
    at Object.kettle.test.bootstrapServer (\\vboxsrv\vagrant\node_modules\kettle\lib\test\KettleTestUtils.js:285:24)
    at Object.gpii.test.runTests (\\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\testing\src\Testing.js:454:24)
    at \\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\testing\src\Testing.js:490:19
    at Object.fluid.each (\\vboxsrv\vagrant\node_modules\infusion\src\framework\core\js\Fluid.js:513:17)
    at Object.gpii.test.runSuite (\\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\testing\src\Testing.js:487:11)
    at Object.gpii.test.runSuitesWithFiltering (\\vboxsrv\vagrant\node_modules\universal\gpii\node_modules\testing\src\Testing.js:517:15)
    at Object. (\\vboxsrv\vagrant\tests\AcceptanceTests.js:31:11)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

As you can see, since the code is under a shared folder, its path begins with //vboxsrv/vagrant because it follows the UNC name convention. After debugging resolve a bit, I found out that the call to path.join here is returning in the form of /vboxsrv/vagrant (note the single / at the beginning), hence the problem. If I just don't apply the prefix (in this particular case \\) the problem goes away. I guess that in this particular case the prefix must be empty too. Or maybe I'm just wrong. What do you think?

Thanks in advance,
Javi

Returns undefined for malformed JSON

$ npm install resolve
$ echo "{" > package.json
$ node -e "require('resolve')('package.json', {moduleDirectory: '.'}, (err, res, pkg) => console.log(err, res, pkg))"
null '/Users/rahat/Downloads/temp/package.json' undefined

It should probably return an error about the JSON syntax error.

Doesn't work in windows azure

This module seems to fail in windows azure, I'm still trying to work out why but I have the following stack trace:

Error: Cannot find module 'debounce'
    at \\100.84.154.36\volume-19-default\48f64dac649c24ece69b\24267363711442628887c9727944f370\site\wwwroot\node_modules\browserify-middleware\node_modules\browserify\node_modules\browser-resolve\node_modules\resolve\lib\async.js:44:17
    at process (\\100.84.154.36\volume-19-default\48f64dac649c24ece69b\24267363711442628887c9727944f370\site\wwwroot\node_modules\browserify-middleware\node_modules\browserify\node_modules\browser-resolve\node_modules\resolve\lib\async.js:110:43)
    at \\100.84.154.36\volume-19-default\48f64dac649c24ece69b\24267363711442628887c9727944f370\site\wwwroot\node_modules\browserify-middleware\node_modules\browserify\node_modules\browser-resolve\node_modules\resolve\lib\async.js:119:21
    at load (\\100.84.154.36\volume-19-default\48f64dac649c24ece69b\24267363711442628887c9727944f370\site\wwwroot\node_modules\browserify-middleware\node_modules\browserify\node_modules\browser-resolve\node_modules\resolve\lib\async.js:54:43)
    at \\100.84.154.36\volume-19-default\48f64dac649c24ece69b\24267363711442628887c9727944f370\site\wwwroot\node_modules\browserify-middleware\node_modules\browserify\node_modules\browser-resolve\node_modules\resolve\lib\async.js:60:22
    at \\100.84.154.36\volume-19-default\48f64dac649c24ece69b\24267363711442628887c9727944f370\site\wwwroot\node_modules\browserify-middleware\node_modules\browserify\node_modules\browser-resolve\node_modules\resolve\lib\async.js:16:47
    at Object.oncomplete (fs.js:107:15)

core included modules not correct on node 6.9.0

It seems the algo for core is not working as expected on node 6.9.0:

test.js:

const core = require('resolve/lib/core.js');
console.log('Current version %s', process.versions.node);
console.log('path: %s', core['path']);
console.log('v8: %s', core['v8']);
console.log('process: %s', core['process']);

Output:

node test.js 
Current version 6.9.0
path: true
v8: undefined
process: undefined

Use the real path for resolving dependencies

Node uses the real path of modules (except when executed with --preserve-symlinks) to resolve dependencies. That is why pnpm's symlinked node_modules work fine with Node applications.

However, resolve is a really popular and widely used package and it does not use the real path of modules to resolve dependencies. As a consequence, a lot of tooling fails with pnpm. See the most recent issue: pnpm/pnpm#857. And also many of these might be related: pnpm/pnpm#801

Would you accept a pull request to change the behavior of resolve to work the way Node does? It won't change anything for projects that use npm/Yarn because they don't leverage symlinks but it would be a huge help for the pnpm community!

resolving with pkg metadata breaks browserify

Here is the command I'm running from level-dump to get the following error:

~/dev/js/projects/level-dump (master %)
โž  browserify test/*.js > bundle.js

/usr/local/lib/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:91
                        var dir = path.resolve(x, pkg.main);
                                                     ^
TypeError: Cannot read property 'main' of undefined
    at module.exports.dir (/usr/local/lib/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:91:54)
    at load (/usr/local/lib/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:54:43)
    at module.exports.cb (/usr/local/lib/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:60:22)
    at module.exports.isFile (/usr/local/lib/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:16:47)
    at Object.oncomplete (fs.js:297:15)

To reproduce just clone that repo and repeat the above step.

Dependency with 'cloneWithProps'

Hi, recently I've upgraded my project from React 0.14 to 15, and as you might know, on this last version 'cloneWithProps' is deprecated and you must use 'cloneElement' instead. Well, browserify install 'module-deps' as a dependency, and this one installs 'browser-resolve', which installs 'resolve' and this one needs 'react-addons-clone-with-props'. Is there a way to fix this? I can't see where in 'lib/async.js' in the module is using 'cloneWithProps'. I'm banging my head as I have been searching around and nobody had the same problem...

This is the output of my gulp build:
Error: Cannot find module 'react/lib/cloneWithProps' from '/home/ppmiron/Development/Project/node_modules/react-addons-clone-with-props' at /home/ppmiron/Development/Project/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:46:17 at process (/home/ppmiron/Development/Project/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:173:43) at ondir (/home/ppmiron/Development/Project/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:188:17) at load (/home/ppmiron/Development/Project/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:69:43) at onex (/home/ppmiron/Development/Project/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:92:31) at /home/ppmiron/Development/Project/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:22:47 at FSReqWrap.oncomplete (fs.js:82:15)

Relative basedir on windows fails to resolve anything

The following will fail (windows 8.1):

var path = require('resolve').sync(
        'resolve/test/core.js',
        {
                basedir: 'lib\\foo'
        }
);
// Error: Cannot find module 'resolve/test/core.js' from 'lib\foo'

However, it works properly if I do the following instead:

var path = require('resolve').sync(
        'resolve/test/core.js',
        {
                basedir: require('path').resolve('lib\\foo')
        }
);
// D:\Users\joris_000\Projects\foo\node_modules\resolve\test\core.js

It looks like something is going wrong here: node-modules-paths.js:8

If I log the paths that are being created at line 26, I get the following output:

/D:\Users\joris_000\Documents\Projects\foo\lib\foo\node_modules
/D:\Users\joris_000\Documents\Projects\foo\lib\node_modules
/D:\Users\joris_000\Documents\Projects\foo\node_modules
/D:\Users\joris_000\Documents\Projects\node_modules
/D:\Users\joris_000\Documents\node_modules
/D:\Users\joris_000\node_modules
/D:\Users\node_modules
/D:node_modules

If I move line 18 before line 8, so that the end result is this:

module.exports = function (start, opts) {
    var modules = opts.moduleDirectory
        ? [].concat(opts.moduleDirectory)
        : ['node_modules']
    ;

    start = path.resolve(start);

    var prefix = '/';
    if (/^([A-Za-z]:)/.test(start)) {
        prefix = '';
    } else if (/^\\\\/.test(start)) {
        prefix = '\\\\';
    }
    var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\/+/;

    // ensure that `start` is an absolute path at this point,
    // resolving againt the process' current working directory
    var parts = start.split(splitRe);
...

It seems to be fixed, but I am not sure how this change affects other platforms

Error.code is undefined

Steps to repro

$ mkdir -p /tmp/resolve-bug
$ cd $_
$ echo '{}' > package.json
$ npm install resolve@latest
$ node
> require('resolve')('asd', function(error) { console.log(error.code, error.message) })

Expected behavior:

MODULE_NOT_FOUND 'Cannot find module \'asd\' from \'.\''

Current behavior:

undefined 'Cannot find module \'asd\' from \'.\''

I'm on [email protected] on macOS
I did search through existing issues to make sure this wasn't a duplicate

Expose more internal resolve logic

A lot of the functions in both lib/async.js and lib/sync.js would be useful to reuse. I want to write a quick resolve-glob module (using this and glob), but right now that'll result in me copying/duplicating 90% of the logic that already exists here. Would you be open to a PR to correct this?

sync should rethrow if stat throws (but not ENOENT)

https://github.com/substack/node-resolve/blob/1.1.6/lib/sync.js#L9-L11

It is possible for fs.statSync to fail do for reasons other then ENOENT. As such, we should re-throw or we end up with an un-related error do to the stat object being missing: https://github.com/substack/node-resolve/blob/1.1.6/lib/sync.js#L1

note this would also fix the a-symmetry with async โ€“ which correctly handles the error https://github.com/substack/node-resolve/blob/1.1.6/lib/async.js#L23

an example would be: fs.statSync('\\\\some-unc-path\\folder name\\missing file') will throw unfortunately throw an UnknownError :(

"Error: Cannot find module" output should include filename

When using browserify and there's a problem with the path to a module, I get error output like:

Error: Cannot find module 'module' from '/dir/subdir'

There may be any number of files in subdir that were trying to require the module. It would be really helpful for the error output to include the filename that contained the require() call instead of just the path to the dir it resides in.

Error in async mode and strange benchmark test

Hi!
For some reason I write my own require.resolve() implementation and use yours and some other for benchmarking.

So, today I saw async mode in node-resolve and add it to test suite. And its sometime works, and sometime not.

See yourself - add Meettya@04d85e5

npm install node-bench -g
npm install lodash

and run test from root dir (may uncomment assert in async to get error)
node-bench ./bench/async-resolve_vs_other.js

and even more - if node-bench right - in my tests sync mode faster than async - its strange.

doesn't seem to be working - global modules

In the node prompt I typed

require('resolve').sync('gulp')

Error: Cannot find module 'gulp' from '.'
    at Function.module.exports [as sync] (C:\Users\Administrator\AppData\Roaming\npm\node_modules\resolve\lib\sync.js:33:11)
    at repl:1:21
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)

But I am able to require gulp from node...This is a global module..

Broken in browserify

This commit broke node-resolve being able to be used with browserify. process.versions is an empty object when this code runs in the browser, and the node key does not exist.

Running npm start in this project can be used to reproduce the error.

node-resolve will incorrectly resolve modules from cwd on Windows

This is caused by the parsing regex in node-module-paths.js and some odd Windows behaviour. Here's a repro setup and trace:

At the start, cwd is E:\kettle, which contains a module infusion at E:\kettle\node_modules\infusion. It has made a call

resolve.sync("infusion", {basedir: "E:\"})

which should NOT resolve.

Unfortunately, https://github.com/substack/node-resolve/blob/master/lib/node-modules-paths.js#L22 has split the path "E:" to the two segments [ "E:", "" ]

This then gets processed by the main loop in node-module-paths https://github.com/substack/node-resolve/blob/master/lib/node-modules-paths.js#L27 to the following array: [ "E:node_modules", "E:\node_modules"]. YOU WOULD THINK that the two elements of this array harmlessly refer to the same path, but they do not. On Windows, there is the somewhat insane convention that a bare drive letter in fact refers to the CWD for that drive which in this case is E:\kettle. Therefore the first element of this array incorrectly resolves into "E:\kettle\node_modules\infusion" by the time it reaches the LoadAsDirectorySync algorithm.

It seems that there is already some special-casing for the win32 platform in node-module-paths.js , but sadly we need a bit more. Fixing the splitRe on this line https://github.com/substack/node-resolve/blob/master/lib/node-modules-paths.js#L20 to make sure that it does not split on :\ should be enough.

Note that since JavaScript regexes don't support zero-width lookbehind, my pull uses a clunky scheme for fusing the first two path segments back together again if we detect that the path begins with a drive letter.

Error on Node.js 6.0.0

I'm using browser-resolve, but think the problem may be in this package. On Node.js 6.0.0 it completely doesn't work. It says: "Path must be a string. Received undefined".

Support "browser" deep module references

I would like to support re-pathing "deep" directory references with the browser config. This was brought up here in node-browser-resolve. And it was suggested here that the changes partly belong in node-resolve.

To make this change, I will need to change node-resolve to make a better attempt to find the package.json and opts hook that supports repathing.

loadAsDirectory, given a path like x = "../node_modules/foo/bar" will look for package.json in "../node_modules/package.json".

If given a path without node_modules like: x = "/Users/justin/dev/project/foo/bar", it will look for package.json in each folder until it finds it.

If a "deep" module reference is being resolved, a package.json is found, and an opts.pathFilter is found, opts.pathFinder(pkg, x, relativeX) will be called where:

  • pkg - the package data
  • x - the moduleId attempted to be resolved
  • relativeX - the moduleId path relative to the package.json location.

If opts.pathFilter returns a value, the returned value will be joined from the package.json location and passed to loadAsFile. Otherwise, x will be used with loadAsFile.

Example:

loadAsDirectory("/Users/justin/dev/project/foo/bar") 
  opts.pathFilter(pkg, "/Users/justin/dev/project/foo/bar", "./foo/bar") //-> "./browser/foo/bar"
  loadAsFile("/Users/justin/dev/project/browser/foo/bar", pkg)

Thoughts on this, the changes, and the choice of the pathFilter name and arguments? Thanks!

/cc @defunctzombie

Add an option to #sync to not throw on resolution failure

Sometimes I don't particularly care when resolution fails (suppose that the whole reason I'm using the module is to speculate not only where but whether a given module name is resolvable). In my case, it'd be nice to be able to hand the sync method an option by which it wouldn't throw an error upon failure.

Thoughts, @substack?

resolve.sync doesn't respect NODE_PATH

There is an inconsistency in how resolve.sync and require.resolve resolve paths:

$ NODE_PATH=/opt/grunt-0.4.2/lib/node_modules node
> require.resolve('grunt')
'/opt/grunt-0.4.2/lib/node_modules/grunt/lib/grunt.js'
> require('resolve').sync('grunt')
Error: Cannot find module 'grunt' from '.'
    at Function.module.exports [as sync] (/home/shlevy/test/node_modules/resolve/lib/sync.js:32:11)
    at repl:1:21
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)
>

Hidden StackOverflow issue (resulting in bug + perf)

resolve.sync of a module with a package.json containing main: '.' will hang for quite some time, (up to 800ms on my machine) and then return return the correct value...

Steps to reproduce:

mkdir -p node_modules/evil/
echo '{"main": "."}' > node_modules/evil/package.json
touch node_modules/evil/index.js
require('resolve').sync('evil') //  => "path/to/node_modules/evil/index.js"  (but very slow)

If the try/catch is removed from https://github.com/substack/node-resolve/blob/master/lib/sync.js#L73 you instead get a fun stack overflow

> require('.').sync('evil')
RangeError: Maximum call stack size exceeded
    at new fs.Stats (fs.js:133:20)
    at Object.fs.statSync (fs.js:907:18)
    at isFile (/Users/spenner/src/substack/node-resolve/lib/sync.js:14:27)
    at loadAsFileSync (/Users/spenner/src/substack/node-resolve/lib/sync.js:45:13)
    at loadAsDirectorySync (/Users/spenner/src/substack/node-resolve/lib/sync.js:68:29)
    at loadAsDirectorySync (/Users/spenner/src/substack/node-resolve/lib/sync.js:70:29)
    at loadAsDirectorySync (/Users/spenner/src/substack/node-resolve/lib/sync.js:70:29)
    at loadAsDirectorySync (/Users/spenner/src/substack/node-resolve/lib/sync.js:70:29)
    at loadAsDirectorySync (/Users/spenner/src/substack/node-resolve/lib/sync.js:70:29)
    at loadAsDirectorySync (/Users/spenner/src/substack/node-resolve/lib/sync.js:70:29)

Really inefficient resolution

Suppose we are in /a/b/c/d.js and require some-thing and node_modules is in /a/node_modules, node-resolve handles this extremely efficiently

Current behavior:

Checks these in order to see which one exists

  • /a/b/c/node_modules/some-thing.js
  • /a/b/c/node_modules/some-thing/node_modules/package.json
  • /a/b/node_modules/some-thing.js
  • /a/b/node_modules/some-thing/node_modules/package.json
  • /a/b/c/node_modules/some-thing.js
  • /a/b/c/node_modules/some-thing/node_modules/package.json
  • /a/node_modules/some-thing.js
  • /a/node_modules/some-thing/node_modules/package.json

It gets even more inefficient as the number of possible extension grows, it does some many stats that for our module bundler bundling our app it can easily get to a hundred thousand unnecessary stats

The ideal behavior would be

  • /a/b/c/node_modules
  • /a/b/node_modules
  • /a/node_modules
  • /a/node_modules/some-thing.js
  • /a/node_modules/some-thing/node_modules/package.json

I'm on [email protected] at the time of writing

Possible loadAsFile inconsistencies

It seems that if resolving a path that matches the regexp
e.g. ./node_modules/jquery/jquery.min - then loadAsFile(String, Function) is called
however if the id takes format of "jquery/jquery.min", then loadAsFile(String, undefined, Function) is called

This results in opts.package being used only when the RegExp is matched. This has an upstream effect on browser-resolve and module-deps whereby if I use the first format, my transforms will apply inside of node_modules, but if I use the second, they don't... is this possibly a bug, or is there a reason behind it? Thanks!

Node modules path dirs resolver bug

Hey guys!

I've recently came across a problem when using jest that uses node-resolver to resolve the dependencies. The problem is detailed here jestjs/jest#2947

Anyway I've debug it throughout and came to the conclusion the problem was with node-resolver itself as you can see from the issue in jest. I've looked into the master branch here and tried replacing the changed node-modules-path file and the problem was fixed. From this commit actually 58b99a3

So anyway you guys can release this so this can be fixed? I just checked that the last release was before this fix.

Thanks!

This should be tested in 0.10-6.x

Currently, both versions this is tested on in Travis (0.6 and 0.8) are unsupported, even in maintenance mode. Could this be instead tested in 0.10, 0.12, 4, 5, and 6 (all the currently supported versions)?

@substack I believe this might unmask many of the errors people are experiencing with this project.

resolve silently eats unknown exceptions

There are a couple places where resolve eats exceptions. This is simply not acceptable. This wasted a good 30 minutes of my time, and it could have been much worse. Unknown exceptions always need to be propagated.

In sync.js, exceptions are eaten on the following lines:

12: catch (err) { if (err && err.code === 'ENOENT') return false }
64: catch (err) {}

in async.js:
81: catch (err) {}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.