-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
ESM loading loads duplicate, starting with node 16.14.0 when using --experimental-specifier-resolution=node
#42116
Comments
In your
|
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
@DerekNonGeneric I replaced the hostname of the machine with xx's as I saw no reason to advertise that ;) I'll try to create a minimal reproduction today. |
I created a reproduction for the The duplicated loading is way harder to reproduce, as it involves loading a 3rth party. |
OK so the steps are:
I'm afraid this is the expected result, see https://nodejs.org/api/esm.html#mandatory-file-extensions. When using ESM, you must use file extension in imports, and/or use I think the duplicated loading is the most interesting problem, that's too bad it's also the most difficult to reproduce. Could you try with Node.js 17.0.1 and Node.js 17.1.0 please? We've made some changes between those two versions that were backported only recently to v16.14.0, I'm curious if that could be related. |
This comment was marked as off-topic.
This comment was marked as off-topic.
@aduh95 I know it is expected behavior, that is why I'm using the CLI flag, to begin with.
I just did. |
I did this, and it shows exactly the same behavior. works in 0.1 and breaks in 1.0. may I ask about those changes? It might well be something I'm doing. as I'm walking the edge on what can be done. Knowing what those changes are, might lead me to a workaround, or even to a fix. |
Thanks, that's very helpful :)
So, you can try the road of loader hooks (https://nodejs.org/api/esm.html#hooks) – while it's still experimental, since you are using
I think you lost me there, why would that change? The CLI flag you are using only change how Node.js interprets the string you pass to the import statement, AFAIK it doesn't (or at least shouldn't) change how Node.js parses the files (that's only based on the file extension when you don't use loader hooks).
There was a resolver spec hardening, whose changes are described in #40510 (comment) which could be related. |
This comment was marked as resolved.
This comment was marked as resolved.
Hmm, I'm not familiar enough with the node source code to have a verdict, but the PR you linked might have a clue. {
[internalFS.realpathCacheKey]: realpathCache
} Where I don't see how this is cached in the updated code. added: |
I've tried to test this hypothesis, but that doesn't seem to be the case. Here's the script I used to reproduce in case you want to iterate on it: mkdir repro
cd repro
mkdir -p node_modules/third_party
echo 'import {a} from "./index-symbolic-link";a.val="mutated value";console.log("should be logged only once");' > node_modules/third_party/submodule.mjs
echo 'import("./submodule.mjs"); export const a = {val:"original value"};' > node_modules/third_party/index.mjs
ln -s ./index.mjs node_modules/third_party/index-symbolic-link.mjs
echo '{"exports":"./index.mjs"}' > node_modules/third_party/package.json
echo 'import {a} from "third_party";import {a as b} from "./node_modules/third_party";setTimeout(() => console.log(a,b), 300);' > index.mjs
node --experimental-specifier-resolution=node index.mjs
cd ..
rm -r repro |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Small update. I can reproduce the issue without a hitch in our mono-repo. However, I have been working on an isolated reproduction, and have not yet been able to do that. The errors I'm getting are only possible when I get the same ESM module twice. |
@SanderElias do you think your problem may be related to #42195? Any chance you would be able to compile node from #42197 to check if that solves your problem? |
cc @nodejs/modules @nodejs/loaders FYI |
That really looks like the same problem. I'm using symlinks too. However, I couldn't reproduce with only a symlink, so there must be something more.
If I had the time available I would love to, but my current schedule doesn't allow me to. (I have to take in account that I'm pretty rusty in this area) |
@GeoffreyBooth When I decided to go with
If/When I would be able to add a loader without having to resort to cmd-line options, this would be much easier to adapt. |
@SanderElias You can also use one of the nightly builds (the most recent one at the time of writing can be found at https://nodejs.org/download/nightly/v18.0.0-nightly202203074158d62dec/ and does contain the fix), so you don't have to set up a whole dev env :) If you were able to download that version and report if if the issue is still there, that'd be awesome (and if the issue is gone, feel free to close this one). |
@aduh95 Sory for the (involuntary cv19) delay. |
The nightly is built from the |
@aduh95 Thanks for the support, and I'm glad this will be fixed in the next releases! Also, thanks for the head-up, and I'm well aware of this "risk". Personally, it really saddens me, that the use of ESM is still considered 'a risk' or experimental in 2022. |
Yes, me too! You'd think that there would be companies interested in making Node.js ESM implementation extensible via a stable API, but it looks like there are no takers but the few volunteers who are doing the actual work on their free time for the most part... |
Version
v16.14.0
Platform
Linux xxXxx 5.13.0-30-generic #33-Ubuntu SMP Fri Feb 4 17:03:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
No response
What steps will reproduce the bug?
I'm the main author of Scully.
In our
@next
version we switched completely to ESM modules. I have an internal register of plugins.Up to version 16.4.0, our code works as expected.
After that, I'm erroring out on plugins that are not 'found'. This seems to happen because I get a new copy of the plugin registry.
That would only be possible as somehow the module loading imports the same thing twice.
It does not happen when I don't use the
--experimental-specifier-resolution=node
option.However, as I have to load a piece of code dynamically, I do need that option. I have no control over the code I need to load, and it is importing without specifying the extension.
So, if I leave off the option, and I try to load the dynamic code I'm getting a load of
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
errors.A workaround could be if I can somehow tell NodeJs that the dynamic code is ESM, and is available with the
.js
extension.There is already a package.json in the dynamic folder that has
{type: "module"}
So, I'm unsure what exactly triggered this change in behavior between node 16.13.2 and 16.14.0(and later, the latest 17 has the same issue), But I would love a way so I can work around this.
Its going to be time-consuming to create an simple replication out of this, so I hope I can get some guidance here.
How often does it reproduce? Is there a required condition?
every time I run the program with >16.14.0
What is the expected behavior?
For my programs to work as before.
What do you see instead?
The error my program shows is there because we handle error conditions, and doesn't add anything to this issue.
Before 16.14:
After:
Additional information
No response
The text was updated successfully, but these errors were encountered: