You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a function that installs missing modules when an import fails, but the import statement seems to preserve the failure while the script is still running.
import('some-module').catch(// this catch will only be reached the first time the script is run because resolveMissingModule will successfully install the module()=>resolveMissingModule('some-module').then(// again, this will only be reached once, but it will fail, because the import seems to have cached the previous failure()=>import('some-module')))
The only information I found in regards to import caching was this documentation, which does not tell me where the “separate cache” used by import can be found.
On Fri, Apr 5, 2019, 12:01 PM Gus Caplan ***@***.***> wrote:
the import cache is purposely unexposed. adding a query has been the
generally accepted ecosystem practice to re-import something.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#49442>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAOUo5N5tioTq2s_t431OrihH_wH8Qagks5vd4FSgaJpZM4cfV4g>
.
FYI, I'm implementing ESM support in Mocha (mochajs/mocha#4038), and cannot currently implement "watch mode", whereby Mocha watches the test files, and reruns them when they change. So "watch mode" in Mocha, in the first iteration, will probably not support ESM, which is a bummer.
While we could use cache busting query parameters, that would mean that we are always increasing memory usage, and old and never-to-be-used versions of the file will continue staying in memory due to the cache holding on to them.
And I'm not sure a loader would help here, as the loader also has no access to the cache.
Reacted by jonerer, Matteo Collina, Ryan Atkinson, cayter, Katja Lutz, Marvin Hagemeister, Sid Vishnoi, atzcl, Andrew Bradley, Sébastien Règne and 29 more
An API for unloading modules certainly makes sense.
Usually with a direct registry API there is the tracing issue. An API that
handles dependency removal can be useful.
A simple API might be something like -
import { unload } from ‘module’;
unload(import.meta.url); // returns true
Where the unload function would remove that module including all its
dependencies from the registry. If in a cycle the whole cycle would be
removed.
A subsequent module load would refresh all the loads anew.
Other problems to ensure work out is what if modules in the tree are still
in-progress. I’d be tempted to say it should fail for that case and only
work when all modules have either errored or completed.
We still have memory leak concerns as v8 doesn’t lend itself easily to
module GC still. But Node.js can lead the way here as it should. It will be
an ongoing process to get there, but the API can come first.
The main questions then seem to be:
* are we ok exposing this as a module or should it be tied to loaders? If
tied to loaders how would userland code request this? Or don’t we want it
to - as in Mocha should run a new context with a loader?
* should it be a direct registry API (get/set) with tracing, or should it
be a deep API like the example above
* finally, ironing out the partially loaded tree edge cases
On Tue, Nov 26, 2019 at 00:09 Gil Tayar ***@***.***> wrote:
FYI, I'm implementing ESM support in Mocha (mochajs/mocha#4038
<mochajs/mocha#4038>), and cannot currently
implement "watch mode", whereby Mocha watches the test files, and reruns
them when they change. So "watch mode" in Mocha, in the first iteration,
will probably not support ESM, which is a bummer.
While we *could* use cache busting query parameters, that would mean that
we are always increasing memory usage, and old and never-to-be-used
versions of the file will continue staying in memory due to the cache
holding on to them.
And I'm not sure a loader would help here, as the loader also has no
access to the cache.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#49442?email_source=notifications&email_token=AAESFSTBSWVLXPTWDYZOHSDQVSVQRA5CNFSM4HD5LYQKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFEXNDI#issuecomment-558462605>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAESFSWTJXGB4J6WWNMOLRDQVSVQRANCNFSM4HD5LYQA>
.
Reacted by Jordan Harband, Aleksei Krasnoperov, Evan Plaice, Christopher Hiller, Anton Korzunov, Ruy Adorno, Ryan Atkinson, hackingoff, Tim Cabbage, Damien Maillard and 47 more
I'm really not a fan of the idea of our module cache being anything except insert-only. CJS cache modification is bad already, and CJS modules don't even form graphs.
Additionally, other runtimes (like browsers) will never expose this functionality, so some alternative system will have to be used for them regardless of what node does, in which case it seems like that system could just be used for node.
Reacted by Matteo Collina, stella, Artem Govorov, Dexter Miguel, Steven Adams, Tobias Berger, Gilbert, Josh Junon, MattXYZ, La7rodectus and 29 more
Reacted by Owen Buckley, Shalvah, Khoa Bean, yodalightsabr, Honored One, saud alnasser and Th3Ward3n
@bmeck - interesting. That would mean that the tests themselves run in Workers. While I am theoretically familiar with workers, I haven't yet had any experience with them: is any code that runs in the main process compatible with worker inside a worker? In other words, compatibility-wise, would all test code that works today in the "main process" work inside workers?
I wouldn't want Mocha to have a version (even a semver-major breaking one) where developers will need to tweak their code because now it's running inside a worker. I'm guessing that there's a vast amount of that code running inside Mocha, and any incompatibility would be a deal breaker.
Looking at the list, I can see process.chdir() is not available, which is probably a deal breaker in many tests (unit tests probably don't use process.chdir(), but Mocha is used for all sorts of tests), as is breaking some native add-ons (although I'm not sure how big of a problem this is in the real world).
I would hesitate to say this, as my only contribution to Mocha currently is this pull request, but I would guess that the owners would veto this. Or maybe allow this only if we add a --run-in-workers option. In any case, without looking too much at the code, this is probably a significant investment to implement for supporting ES Modules, as this is not a simple refactor, but rather an architectural change in how Mocha works.
If it wasn't apparent from the above, I believe I would still prefer a "module unloading" API, unless the working group is adamant and official about not having one, of course. Which would probably mean going the "subprocess"/"worker" route.
Hi, the ability to invalidate cache when using import (or in my case even require) seems to be very important to be able to use the new experimental mock.module functionality from the native Node test runner.
importassertfrom'node:assert';import{mock,test}from'node:test';// This works welltest('Mock shallow module',async()=>{for(leti=0;i<2;i++){constfsMock=mock.module('node:fs',{namedExports: {writeFileSync: mock.fn(()=>i)}});constfs=awaitimport('node:fs');assert.strictEqual(fs.writeFileSync(),i);fsMock.restore();}});// This failstest('Mock deep module',async()=>{for(leti=0;i<2;i++){constfsMock=mock.module('node:fs',{namedExports: {writeFileSync: mock.fn(()=>i)}});const{ getFs }=awaitimport('./fs-extended.mjs');constfs=getFs();assert.strictEqual(fs.writeFileSync(),i);fsMock.restore();}});
Result:
test at my.test.mjs:16:1
✖ Mock deep module (4.481709ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
0 !== 1
at TestContext.<anonymous> (file:///Users/filip.satek/git/cns-cli/my.test.mjs:23:16)
at async Test.run (node:internal/test_runner/test:931:9)
at async Test.processPendingSubtests (node:internal/test_runner/test:629:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 0,
expected: 1,
operator: 'strictEqual'
}
Even though I called fsMock.restore(), in the second iteration, the getFs call still gave me the node:fs module from the first iteration.
I hope this is related to this issue, otherwise please let me know and I will file a new issue for my use-case.
Edit: Tested on Node v22.9.0 using node --test --experimental-test-module-mocks my.test.js command.
Reacted by Satvik Sharma, Martin Staffa, Josh Balfour, v1rtl, Ahraz-Volvo, Olaf Kwant, Fil Maj and Owen Buckley
I'm also running into issues with this with the native module mocking, where I've setup the mock only in one test & already imported the module under test at the top.
import{describe,it}from"node:test";importMyClassfrom"./tested-module.js";functionsetup(){// ...returnnewMyClass(...);}describe("myModule",()=>{it("should run test1",()=>{/* ... */});it("should run test2",(t)=>{t.mock.module("node:fs/promises",{defaultExport: {writeFile: t.mock.fn(),}});// This is mocked correctly because I haven't imported the original moduleconstmockedFs=(awaitimport("node:fs/promises")).default;// This still calls the real fs methods because I'd already imported it at the top.constMyMockedClass=(awaitimport("./tested-module.js")).default;});})
I'm experiencing the same issue: Mocks from older tests seem to be reused in subsequent ones. Doing await import('./repro.mjs?a='+randomUUID()) doesn't help either.
I created a library using module.registerHooks: https://github.com/sxzz/import-without-cache. It allows you to load modules and their submodules without caching, which I hope it will be helpful. Please note that there are some known limitations.
This issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
Activity
devsnek commentedon Apr 5, 2019
the import cache is purposely unexposed. adding a query has been the generally accepted ecosystem practice to re-import something.
however, a failure to import something will not fill the cache.
this trivial program works fine for me (assuming
nope.mjsdoes not exist):jonathantneal commentedon Apr 5, 2019
@devsnek, hmm, might this be limited to imports that use node_modules? This similarly trivial program fails for me the first time, but not the second.
bmeck commentedon Apr 5, 2019
devsnek commentedon Apr 5, 2019
if its just happening with node_modules it could be #26926
MylesBorins commentedon Aug 29, 2019
can this be closd?
hybrist commentedon Aug 29, 2019
I think a use case like this would hopefully be implemented as a loader. Do we already track this as a use case in that context?
bmeck commentedon Aug 30, 2019
@jkrems we have old documents with that as a feature, but no success criteria examples.
giltayar commentedon Nov 26, 2019
FYI, I'm implementing ESM support in Mocha (mochajs/mocha#4038), and cannot currently implement "watch mode", whereby Mocha watches the test files, and reruns them when they change. So "watch mode" in Mocha, in the first iteration, will probably not support ESM, which is a bummer.
While we could use cache busting query parameters, that would mean that we are always increasing memory usage, and old and never-to-be-used versions of the file will continue staying in memory due to the cache holding on to them.
And I'm not sure a loader would help here, as the loader also has no access to the cache.
guybedford commentedon Nov 26, 2019
devsnek commentedon Nov 26, 2019
I'm really not a fan of the idea of our module cache being anything except insert-only. CJS cache modification is bad already, and CJS modules don't even form graphs.
Additionally, other runtimes (like browsers) will never expose this functionality, so some alternative system will have to be used for them regardless of what node does, in which case it seems like that system could just be used for node.
bmeck commentedon Nov 26, 2019
@giltayar have you looked into using Workers or other solutions to have a module cache that you can destroy (such as by killing the Worker)?
giltayar commentedon Nov 28, 2019
@bmeck - interesting. That would mean that the tests themselves run in Workers. While I am theoretically familiar with workers, I haven't yet had any experience with them: is any code that runs in the main process compatible with worker inside a worker? In other words, compatibility-wise, would all test code that works today in the "main process" work inside workers?
I wouldn't want Mocha to have a version (even a semver-major breaking one) where developers will need to tweak their code because now it's running inside a worker. I'm guessing that there's a vast amount of that code running inside Mocha, and any incompatibility would be a deal breaker.
devsnek commentedon Nov 28, 2019
there are differences between workers and the main thread, mostly surrounding the functions on
process, likeprocess.exit()in a worker doesn't end the process, just the thread. There's a good list here: https://nodejs.org/api/worker_threads.html#worker_threads_class_workergiltayar commentedon Nov 28, 2019
Looking at the list, I can see
process.chdir()is not available, which is probably a deal breaker in many tests (unit tests probably don't useprocess.chdir(), but Mocha is used for all sorts of tests), as is breaking some native add-ons (although I'm not sure how big of a problem this is in the real world).I would hesitate to say this, as my only contribution to Mocha currently is this pull request, but I would guess that the owners would veto this. Or maybe allow this only if we add a
--run-in-workersoption. In any case, without looking too much at the code, this is probably a significant investment to implement for supporting ES Modules, as this is not a simple refactor, but rather an architectural change in how Mocha works.giltayar commentedon Nov 28, 2019
If it wasn't apparent from the above, I believe I would still prefer a "module unloading" API, unless the working group is adamant and official about not having one, of course. Which would probably mean going the "subprocess"/"worker" route.
135 remaining items
simlu commentedon Jul 17, 2024
Should probably close this as "wont do"?
lzxb commentedon Aug 14, 2024
My example
Use it
RomainLanz commentedon Aug 14, 2024
If you are interested, we created
Hot Hookto hot reload node imports during development.https://adonisjs.com/blog/hmr-in-adonisjs
https://docs.adonisjs.com/guides/concepts/hot-module-replacement
https://github.com/julien-R44/hot-hook
Filipoliko commentedon Oct 4, 2024
Hi, the ability to invalidate cache when using
import(or in my case evenrequire) seems to be very important to be able to use the new experimentalmock.modulefunctionality from the native Node test runner.https://nodejs.org/api/test.html#mockmodulespecifier-options
Here is a use-case, where you can run into a trouble.
fs-extended.mjs
my.test.mjs
Result:
Even though I called
fsMock.restore(), in the second iteration, thegetFscall still gave me thenode:fsmodule from the first iteration.I hope this is related to this issue, otherwise please let me know and I will file a new issue for my use-case.
Edit: Tested on Node v22.9.0 using
node --test --experimental-test-module-mocks my.test.jscommand.ramblingenzyme commentedon Jan 28, 2025
I'm also running into issues with this with the native module mocking, where I've setup the mock only in one test & already imported the module under test at the top.
tested-module.js
my-test.test.js
joshbalfour commentedon Mar 18, 2025
I'm experiencing the same issue: Mocks from older tests seem to be reused in subsequent ones. Doing
await import('./repro.mjs?a='+randomUUID())doesn't help either.Here's a simple reproduction:
repro.mjs
repro.test.mjs
thw0rted commentedon Aug 1, 2025
@Filipoliko it looks like your comment may be related to #59163 , it should be possible to reset module mocking but it doesn't seem to actually work.
sxzz commentedon Nov 29, 2025
I created a library using
module.registerHooks: https://github.com/sxzz/import-without-cache. It allows you to load modules and their submodules without caching, which I hope it will be helpful. Please note that there are some known limitations.thescientist13 commentedon Mar 1, 2026
Just a heads up there is a PR up for this now - #61767 ! 🙌
github-actions commentedon Aug 9, 2026
This issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
filmaj commentedon Aug 9, 2026
Please do not make this issue as stale! Would love to see this issue resolved in node 🙏