Open BadIdeaException opened 3 months ago
This sounds really promising, @BadIdeaException. I really appreciate you taking the time to investigate this. I'll try to make time in the coming days to see what it would be like to use your approach.
I'm happy to hear that. Also will be happy to help more if I can.
@tschaub Any news on this yet? I have been playing around with it a little in a local copy (I haven't forked, just cloned and went wild), and I have been able to throw this together in a way that both keeps the existing compatibility with CommonJS and does its new trick with ESM. New Gist here. Just add the files into mock-fs/lib/
(well, package.json
in the project root, obviously). The tryit
files I had also put in my project root, for lack of a better place.
For convenience, I then symlinked this into node_modules
, to emulate mock-fs having been npm install
ed. (ln -s ./ node_modules/mock-fs
.) Then
node tryit.cjs
// null [ '.gitignore' ]
and
node --import mock-fs/bootstrap tryit.mjs
// null [ '.gitignore' ]
Ergo, works in both ways.
"main"
field in package.json
and the addition of "exports"
. This is how the magic of diverting ESM imports to the new system happens.fs
are available. In fact, most of them aren't. (I tried readFileSync
first, but nope; and the signature of readdir
does not conform to the original). I suspect this has to do with the magic of how your re-binding code works in the original index.js
, but to be honest, that part of your code is not very clear to me. I was under the impression you had (mostly) re-implemented the methods of node:fs
in Binding
, but this seems to not be the case? Am I overlooking something here? This seems to me to be the biggest remaining obstacle.module.register
only became available with Node 18, although hook.mjs
looks like it should be compatible to being used as a loader. ( I haven't tried this, though.).js
) and ESM (.mjs
) in this way, but short of rewriting everything in ESM I can't see a way around it. The import hook mechanism seems to rely on ESM (which I guess sort of makes sense), and I haven't found a way around this.index.js
as the CJS version, then wrote a rough-shod ESM one next to it (although it does use the same implementation of Binding
and FileSystem
). My instinct is that the existing code should be fairly easy to refactor in such a way that the two share code for their common functionality, though.Would love to hear your thoughts.
As seen in #383:
and had started wondering if Loaders (now called Customization Hooks) might be a way to control access to the fs module without needing access to
process.binding
.I've taken the liberty of throwing together a quick gist for this as a proof of concept. It provides a mechanism to switch access between real and fake file system by calling
fakefs()
andfakefs.restore()
, resp. For this, it intercepts import resolution requests tofs
ornode:fs
and redirects them to a dedicated module, which in turn exports aProxy
that basically acts as a switch between the real and the fake file system at will.The only caveat with this approach that I can see is that the hooks would need to be registered right at the beginning, but this should easily be doable by specifying an import flag. Mocha even supports doing this as part of the configuration file.
I would love if this project could be kept alive. The only alternative I have found is memfs, and I dislike that I have to manually mock the
fs
import in the system under test literally every time.