-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
require can't find module by name if it's a symlink anymore #1212
Comments
cc @nodejs/modules |
How are you running node? There's a --preserve-symlinks option that may be relevant. |
@ljharb Through webpack. My code is part of a small module that returns a Promise resolving to a webpack configuration. Now that you mentioned that. I did update |
I would be willing to bet that webpack 4 changed its default symlink behavior; but if something happens when using webpack, it's definitely a webpack issue and not a node one :-) |
Thanks for the idea! I tried it out in a small script* and it properly resolves symlinks. Seems to be issue with Webpack and will follow up there. Additionally, I also couldn't figure out why require.resolve.paths() was undefined. But the function works fine outside of Webpack. * Test script: /* eslint-disable no-console */
const path = require('path');
function resolvePathTo(pathTo) {
let result = process.cwd();
try {
console.log('Resolving', `${pathTo}${path.sep}package`);
result = path.dirname(require.resolve(`${pathTo}${path.sep}package`));
} catch (error) {
if (error.code !== 'MODULE_NOT_FOUND') {
throw error;
}
}
return result;
}
console.log('resolves to cwd', resolvePathTo('anything'));
console.log('resolves directory-module', resolvePathTo('directory-module'));
console.log('resolves symlink-module', resolvePathTo('symlink-module'));
console.log('resolves original-module', resolvePathTo('original-module'));
console.log(require.resolve.paths('symlink-module')); Directory structure (each containing a stefan@Work-Stefan /srv/projects/tests/symlinks $ ll node_modules/
total 16K
drwxr-xr-x 4 stefan stefan 4.0K Apr 14 19:30 ./
drwxr-xr-x 3 stefan stefan 4.0K Apr 14 19:21 ../
drwxr-xr-x 2 stefan stefan 4.0K Apr 14 19:20 directory-module/
drwxr-xr-x 2 stefan stefan 4.0K Apr 14 19:21 original-module/
lrwxrwxrwx 1 stefan stefan 15 Apr 14 19:21 symlink-module -> original-module/
stefan@Work-Stefan /srv/projects/tests/symlinks $ |
After further testing I found the 'error'. Not in webpack or node but on my misunderstanding of how node/require walks up/through directories. Anyway, two small modules to illustrate why it doesn't and shouldn't have ever worked: [...]/module-a/index.js: /* eslint-disable no-console */
const moduleB = require('module-b');
console.log(module.paths);
try {
console.log('resolved', require.resolve('module-b'));
} catch (e) {
console.log('failed resolve module-b');
}
console.log(moduleB()); [...]/module-b/index.js: /* eslint-disable no-console */
module.exports = () => {
console.log(module.paths);
try {
// module.paths = module.paths.concat(module.parent.paths);
console.log('resolved', require.resolve('module-b'));
} catch (e) {
console.log('failed resolve module-b');
}
return 'module-b result';
} Symlink is: Here's the output of running stefan@Work-Stefan /srv/projects/issues/resolve-within-symlink/module-a $ node index.js
module-a
[ '/srv/projects/issues/resolve-within-symlink/module-a/node_modules',
'/srv/projects/issues/resolve-within-symlink/node_modules',
'/srv/projects/issues/node_modules',
'/srv/projects/node_modules',
'/srv/node_modules',
'/node_modules' ]
resolved /srv/projects/issues/resolve-within-symlink/module-b/index.js
module-b
[ '/srv/projects/issues/resolve-within-symlink/module-b/node_modules',
'/srv/projects/issues/resolve-within-symlink/node_modules',
'/srv/projects/issues/node_modules',
'/srv/projects/node_modules',
'/srv/node_modules',
'/node_modules' ]
failed resolve module-b
module-b result The issue is that So now I understand why it doesn't work and my best guess to why it worked before is that at the time each of my projects had their node_modules directory as a symlink to the same "master node_modules". So naturally my "module-b" could resolve itself in there. Anyway, wasted a few hours on this but at least I learned something. PS: To whomever it may concern: Thanks for creating node! |
I have method that worked fine a couple month ago:
It'd basically return current working directory path (the module calling the method) by default or the directory path to a module with the name from the methods parameter, if it is installed somewhere in the paths
require.resolve
looks in.Unfortunately the code doesn't work anymore for looking up a module that is a symlink (i.e. setup with
npm link
). It works fine if the module is an actual directory and not a symlink though.Example directory setup:
stefan@Work-Stefan /srv/projects/tests/songworks/module $ ls -la node_modules/@songworks/ total 52K drwxr-xr-x 4 stefan stefan 4.0K Apr 14 05:38 ./ drwxr-xr-x 848 stefan stefan 36K Apr 14 05:25 ../ drwxr-xr-x 3 stefan stefan 4.0K Apr 14 03:23 testsuite/ drwxr-xr-x 3 stefan stefan 4.0K Apr 14 03:23 util/ lrwxrwxrwx 1 stefan stefan 31 Apr 14 05:38 module -> /srv/projects/songworks/module/
require.resolve
can resolve the module@songworks/testsuite
, but not@songworks/module
(anymore).I can still make the method work if I give
require.resolve
an absolute path to the module symlink, with f.e.path.resolve('node_modules', pathTo, 'package')
. But that kinda defeats the purpose of usingrequire.resolve
to begin with.Also, the code worked fine in at least node
8.9.3
, as that's the version I last worked on this project with.Any idea what I'm doing wrong or why it doesn't work with symlinked modules anymore? What can I do to figure this out?
Thanks in advance!
The text was updated successfully, but these errors were encountered: