Open JamieGoodson opened 3 years ago
I got no issue with both Node v17.0.1 and v17.1.0 and mock-fs v5.1.2.
What's TS v10.2.1?
What's TS v10.2.1?
TypeScript 🙂
Current typescript is v4. What's v10?
Got the same problem after updating... something.
I've tracked down the issue to getReadFileContextPrototype
in readfilecontext.js
.
It works with plain node, but it does not work with yarn PnP (3.1.1). When I run this code from the above mentioned file:
getReadFileContextPrototype = function() {
const fs = require('fs');
const fsBinding = process.binding('fs');
const originalOpen = fsBinding.open;
let proto;
fsBinding.open = (_path, _flags, _mode, req) => {
proto = Object.getPrototypeOf(req.context);
return originalOpen.apply(fsBinding, [_path, _flags, _mode, req]);
};
fs.readFile('/ignored.txt', () => {});
fsBinding.open = originalOpen;
return proto;
}
With just node
, it returns the prototype. With yarn node
, it returns undefined
. Happens with node 14 and 16.
Are other people with this issue also using yarn?
Seems like when using yarn, it only works with mock-fs@5.0.0 and node 14:
Using mock-fs@5.0.0 with node 16 gives a different error, but it seems to be the same underlying cause.
Are other people with this issue also using yarn?
I'm having it after migrating to Yarn 3 + PnP
I assume yarn pnp monkey-patched nodejs internals (something like what mock-fs does). The other tool does this practice is jest, which mock-fs also has difficulty to work with.
I found that the getReadFileContextPrototype will alwasy return null if you first call:
jest.mock('fs');
in your test before mock.
within this function:
exports.getReadFileContextPrototype = function () {
const fs = require('fs');
const fsBinding = process.binding('fs');
const originalOpen = fsBinding.open;
let proto;
fsBinding.open = (_path, _flags, _mode, req) => {
proto = Object.getPrototypeOf(req.context);
return originalOpen.apply(fsBinding, [_path, _flags, _mode, req]);
};;
fs.readFile('/ignored.txt', (err) => {});
fsBinding.open = originalOpen;
return proto;
};
When all of the fs functions are mocked, and the fsBinding.open never gets called, so proto stays undefined.
This is happening to me using jest + typescript + mock-fs on es6 module mode. When I was using commonjs without typescript, it ran with the jest.mock('fs')
just fine.
I've also found the following if anyone's interested: Using Typescript:
AggregateError: EBADF: bad file descriptor, fstat
at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read/context:52:21)
at FSReqCallback.callbackTrampoline (node:internal/async_hooks:130:17)
or a
Error: ENOENT: no such file or directory, open 'C:\Users\Tony\Dev\var\data\unit_test\test.json'
so I converted all of my readFileSync -> readFile and writeFileSync -> writeFile within my tests + code and they seemed to work.
I'm not sure why this is. I have my suspicion that there might be something funny when running everything with es6 modules + typescript. es6 module imports work asynchronously, where as commonjs require doesn't, so there might be something around that when loading the fsBinding.
or
Results in
Node:
v17.0.1
TS:v10.2.1
mock-fs:5.1.2