nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.83k stars 29.72k forks source link

ERR_MODULE_NOT_FOUND recommends what I asked it to import #33714

Open heavyk opened 4 years ago

heavyk commented 4 years ago

What steps will reproduce the bug?

mkdir -p node_modules/@broken_imports
echo 'export const lala = 3' > node_modules/@broken_imports/lala.js
echo "import { lala } from '@broken_imports/lala.js'" > test_imports.js
node test_imports.js

ok, now, we'll make it a es module package. it'll still say the same error.

echo '{"name": "test-pkg", "type": "module"}' > node_modules/@broken_imports/package.json
node test_imports.js

How often does it reproduce? Is there a required condition?

always happens for me. should output:

internal/modules/run_main.js:54
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@broken_imports/lala.js' imported from /Users/kenny/test/test_imports.js
Did you mean to import @broken_imports/lala.js?
    at packageResolve (internal/modules/esm/resolve.js:620:9)
    at moduleResolve (internal/modules/esm/resolve.js:659:14)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:752:11)
    at Loader.resolve (internal/modules/esm/loader.js:97:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:50:40)
    at link (internal/modules/esm/module_job.js:49:36)

What is the expected behavior?

I expected it to import. the docs say: https://nodejs.org/api/esm.html#esm_no_node_path

No NODE_PATH#
NODE_PATH is not part of resolving import specifiers. Please use symlinks if this behavior is desired.

tried with symlinks too, and couldn't get it to work.

guybedford commented 4 years ago

The ES module resolver doesn't support loading "files" in node_modules that aren't within valid package names.

We could certainly improve the error message in this case though.

heavyk commented 4 years ago

ok, I updated my original post to add a package.json (so it's a "valid" package).

is there a quick and dirty way (for right now to hack it) so that I can symlink a bunch of files (they all import other files using the @package name identifier) so that they can be imported? if not, I can just make a rollup build to convert them to cjs, so no big deal.

lundibundi commented 4 years ago

As I see it, the problem with this is that @ at the beginning of the package name is interpreted as referring to scoped/namespaced package (i.e. https://docs.npmjs.com/about-scopes) and the code is, therefore, searching for full package name (which will always be in the form of @scopename/package or @scopename/package/file.js) but since you want to directly read the file from a folder named @package that doesn't work and it interprets the file as a part of package name.

I don't think there is an easy way to make it work without changing to proper package imports.

RedYetiDev commented 4 months ago

Is this still occuring? AFAICT the recommended import errror isn't showing (but just a standard error):

mkdir -p node_modules/@broken_imports
echo 'export const lala = 3' > node_modules/@broken_imports/lala.mjs
echo "import { lala } from '@broken_imports/lala.mjs'" > test_imports.mjs
node test_imports.mjs
echo '{"name": "test-pkg", "type": "module"}' > node_modules/@broken_imports/package.json
node test_imports.mjs