Skip to content
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

TypeError on import or require #344

Open
JamieGoodson opened this issue Nov 26, 2021 · 10 comments
Open

TypeError on import or require #344

JamieGoodson opened this issue Nov 26, 2021 · 10 comments

Comments

@JamieGoodson
Copy link

JamieGoodson commented Nov 26, 2021

import mock from 'mock-fs';
...

or

const mock = require('mock-fs');
...

Results in

TypeError: Cannot read properties of undefined (reading 'read')

Node: v17.0.1
TS: v10.2.1
mock-fs: 5.1.2

@3cp
Copy link
Collaborator

3cp commented Nov 27, 2021

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?

@JamieGoodson
Copy link
Author

What's TS v10.2.1?

TypeScript 🙂

@3cp
Copy link
Collaborator

3cp commented Nov 30, 2021

Current typescript is v4. What's v10?

@blutorange
Copy link

blutorange commented Jan 6, 2022

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?

@blutorange
Copy link

blutorange commented Jan 6, 2022

Seems like when using yarn, it only works with mock-fs@5.0.0 and node 14:

  • WORKS: mock-fs@5.0.0 / node 14.17.5 / yarn 3.1.1
  • NOT WORKING mock-fs@5.1.0 / node 14.17.5 / yarn 3.1.1
  • NOT WORKING mock-fs@5.0.0 / node v16.13.0 / yarn 3.1.1
  • NOT WORKING mock-fs@5.1.2 / node v16.13.0 / yarn 3.1.1

Using mock-fs@5.0.0 with node 16 gives a different error, but it seems to be the same underlying cause.

@webstackdev
Copy link

Are other people with this issue also using yarn?

I'm having it after migrating to Yarn 3 + PnP

@3cp
Copy link
Collaborator

3cp commented Jul 30, 2022

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.

@tschirmer
Copy link

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.

https://stackoverflow.com/questions/70447223/const-mock-requiremock-fs-gives-typeerror-cannot-read-properties-of-und/77604547#77604547

@tschirmer
Copy link

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.

@tschirmer
Copy link

tschirmer commented Dec 6, 2023

I've also found the following if anyone's interested:
Using Typescript:

  • readFileSync / writeFileSync returns an aggregate error:
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'
  • however, readFile / writeFile doesn't

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants