resolve icon indicating copy to clipboard operation
resolve copied to clipboard

Result differs from Node's require.resolve when using `basedir` option with symlinks

Open j-christoffersen opened this issue 2 years ago • 9 comments

Hi, Ive noticed an issue that arises when using this package alongside npm link or yarn link - when resolving from a linked dependency's directory as basedir, this package will resolve to a module in the linked packages node_modules. This is in contrast to Node's require.resolve, which will resolve to the root level node_modules (same as if the package wasn't linked).

For example, if resolve-example depends on a package test-pkg, test-pkg itself depends on lodash, and I link resolve-example to test-pkg using yarn link, here's what I see after running the following

const resolve = require('resolve/sync')
let opts = { basedir: '/Users/jacksonchristoffersen/resolve-example/node_modules/test-pkg', preserveSymlinks: true }

console.log(require.resolve('lodash', opts))
// /Users/jacksonchristoffersen/resolve-example/node_modules/lodash/lodash.js

console.log(resolve('lodash', opts))
// /Users/jacksonchristoffersen/resolve-example/node_modules/test-pkg/node_modules/lodash/lodash.js

opts = { basedir: '/Users/jacksonchristoffersen/resolve-example/node_modules/test-pkg', preserveSymlinks: false }

console.log(require.resolve('lodash', opts))
// /Users/jacksonchristoffersen/resolve-example/node_modules/lodash/lodash.js

console.log(resolve('lodash', opts))
// /Users/jacksonchristoffersen/test-pkg/node_modules/lodash/lodash.js

I'd expect these results to match for each value of opts

j-christoffersen avatar Jan 27 '23 02:01 j-christoffersen

Yes, that's because of the preserveSymlinks option - node's own behavior changed here, and resolve v1 defaults to the older node behavior. You can try the v2 prerelease, or you can set the option yourself.

ljharb avatar Jan 27 '23 05:01 ljharb

Thanks for the response! I take it this means that, for this example, resolve v1 should never resolve to the same path as Node's resolve, regardless of what value is provided for preserveSymlinks?

j-christoffersen avatar Jan 27 '23 19:01 j-christoffersen

That doesn't sound right - resolve v1, by default, will match node < 6's resolve behavior. If you set preserveSymlinks to false, it should match modern node's resolution behavior (except for "exports", which isn't yet supported).

resolve v2's prerelease will match modern node (modulo "exports") unless you set preserveSymlinks to true, which will then match node < 6.

(the flag was added in node 6.3, i'm not actually sure when node's default was changed - probably node 7 or 8?)

ljharb avatar Jan 27 '23 20:01 ljharb

I'm actually not seeing a difference between running this with Node 16 (what I ran on originally) and Node v6... If I run the code above I get the following regardless of if I'm using Node v16 or v6

/Users/jacksonchristoffersen/resolve-example/node_modules/lodash/lodash.js
/Users/jacksonchristoffersen/resolve-example/node_modules/test-pkg/node_modules/lodash/lodash.js
/Users/jacksonchristoffersen/resolve-example/node_modules/lodash/lodash.js
/Users/jacksonchristoffersen/test-pkg/node_modules/lodash/lodash.js

j-christoffersen avatar Jan 27 '23 21:01 j-christoffersen

It could be older than that :-) try node 4 or 5?

Either way I'm more than happy to add these as test cases, whether it's a bug or not.

ljharb avatar Jan 27 '23 21:01 ljharb

I'm getting the same result using v4 and even v2 actually

j-christoffersen avatar Jan 27 '23 21:01 j-christoffersen

hm, weird. it could be even older - 0.12 or 0.10 - without the test case locally i have to ask you to keep trying :-D

ljharb avatar Jan 27 '23 21:01 ljharb

Same result with 0.12, 0.10, and even 0.8 (which is the lowest I can install without nvm giving me errors)

j-christoffersen avatar Jan 27 '23 21:01 j-christoffersen

wow, then i have no idea. want to send a PR with tests that match your expectations, and i'll see what i can do?

ljharb avatar Jan 27 '23 21:01 ljharb