-
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
Crash of ESM loader #48240
Comments
Could you provide steps to reproduce? Ideally without involving any npm package or downloading code from the internet, but anything would be appreciated. EDIT: I'm able to reproduce using |
Thank you! Looks like I understand what the problem is: I write the tool to load a couple loaders, and it's Now I have another thing I cannot understand. I'm working on library to mock ESM imports, and it is used as loader and works good in node v16 and node v18. I use global variables to access map and set of modules to re-import and cannot understand how to deal with node v20 loaders, since they use workers. Ideally I want to keep mocking for a test file: test('cat: should call readFile', async (t) => {
const readFile = stub();
mockImport('fs/promises', {
readFile,
});
const cat = await reImport('./cat.js');
await cat();
stopAll();
t.calledWith(readFile, ['./README.md', 'utf8']);
t.end();
}); And this |
Global variables won't work, you'll need to use |
Maybe this can help as an example? https://github.com/giltayar/esm-loaders-talk/tree/main/07-clear-cache/off-thread It's a loader that implements "cleaning the cache" and has commuication between (this is sample code and has no error handling and such) |
Could you please clarify can I pass function using |
Not to discourage ingenuity, but have you considered testdouble? Mocking ESM is exactly what it does (very well). |
I mean communication using Also as I understand I cannot save
Never herd about it. I used |
@coderaiser you can't send functions via the port. Only serializable stuff can be sent. |
@giltayar in this case mocking functions of ESM modules starting from node v20 will be absolutely impossible? Since I need a way to create function inside test, and then loaded module should call this function. |
Both the test file and the loaded module are evaluated in the main thread. The function doesn't need to pass through the loader thread. |
@targos here is how
How should I rewrite this logic to have ability to mock implementations of a modules? I don't want to tell that mocking is best practice, but sometimes you don't want to run real implementation which do something to network connections, or works with file system, and cannot to re-write all your codebase. |
@giltayar what we would need is to have a mocking implementation in our test suite, having it outside the test suite is not as useful as it could break at anytime without us noticing. |
FWIW I've been working on this for our test runner's mocking API. |
Thank you guys, looks like I understand the thing about using Anyways I don't need to pass mocking details to Here is how it looks like. |
PR-URL: nodejs#48249 Fixes: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
@cjihrig could you please share what API test runner will have? |
PR-URL: nodejs#48247 Refs: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs#48249 Fixes: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
@coderaiser you can see my work in progress here: https://github.com/cjihrig/node/commits/mock. Sorry, there are no docs yet. |
The amount of hacks needed these days to maintain a testing framework is just mind boggling. Test framework design is very much an afterthought in node unfortunately... So, for the next unfortunate person stumbling onto this thread, here is another example of... some really dark magic =) |
This is simply not true. I had a conversation literally yesterday where we specifically discussed support and implications for this. Also, multiple members of our team are themselves maintainers of testing frameworks 😉 |
@JakobJingleheimer Man, I'd love to join in on these conversations! Especially the inability to free memory / cache in ESM feels like huge regression coming from CJS and has caused me so many headaches. But maybe I just have to make some fundamental design changes coming from CJS 😬 |
Our team meets every other Tuesday at 20:00 CET. I'm away for the next one (01 Aug); I'm not sure if that one will happen. An issue is automatically generated in the node/loaders repo for each meeting, where we coordinate. Please jump in—we'd be happy to have you 🙂 You mentioned a memory issue—feel free to toss that onto the discussion topics! A quick glimpse at that issue says the person is looking for access to ESM's ModuleMap. I would guess direct access is something we would likely not expose, but we may provide some kind of readonly clone/snapshot if there was need of it. If that is indeed what you need, let us know. |
If you’re referring to ESM’s lack of an equivalent to |
Thank you for your replies here, much appreciated! @JakobJingleheimer I've subscribed to the repo and will keep an eye out for the next meeting! What we are really looking for is an easy way to hot reload in esm, without causing memory leaks. @GeoffreyBooth Yeah, it's an unfortunate situation. I spend way too much time already trying various workarounds and the current one seems to be the best. I've written down what we are currently doing here |
Ah, right, yes
It's been discussed a few times, and AFAIK, this is not possible without access to V8's module graph. You can get something decent together with |
Do you have an exanple of that? Or is that basically what we are already doing here? |
Generally yes for globalPreload / postMessage. This article does a good job of covering this topic: https://dev.to/giltayar/mock-all-you-want-supporting-es-modules-in-the-testdouble-js-mocking-library-3gh1. He's updated testdouble to use MessageChannel, so you could glean from that. The p.s. Sorry for the delay—I was out of town. |
PR-URL: nodejs#48247 Refs: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs#48249 Fixes: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs#48247 Refs: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs#48249 Fixes: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs#48247 Refs: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs#48249 Fixes: nodejs#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs/node#48247 Backport-PR-URL: nodejs/node#50669 Refs: nodejs/node#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs/node#48249 Backport-PR-URL: nodejs/node#50669 Fixes: nodejs/node#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs/node#48247 Backport-PR-URL: nodejs/node#50669 Refs: nodejs/node#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Jacob Smith <jacob@frende.me>
PR-URL: nodejs/node#48249 Backport-PR-URL: nodejs/node#50669 Fixes: nodejs/node#48240 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
Version
v20.20
Platform
mac os
Subsystem
No response
What steps will reproduce the bug?
I'm working on tool that collects coverage https://github.com/coderaiser/escover
It runs provided script and adds loaders using
NODE_OPTIONS
. Node v20.2 is crashed, node v18, node v16 works good.How often does it reproduce? Is there a required condition?
No response
What is the expected behavior? Why is that the expected behavior?
No response
What do you see instead?
Additional information
No response
The text was updated successfully, but these errors were encountered: