davidmyersdev / vite-plugin-node-polyfills

A Vite plugin to polyfill Node's Core Modules for browser environments.
MIT License
263 stars 17 forks source link

Uncaught TypeError: null has no properties on fs #18

Closed prpanto closed 1 year ago

prpanto commented 1 year ago

Just import the fs module and the error appear on the console log.

zz-link commented 1 year ago

waiting for it

davidmyersdev commented 1 year ago

It looks like the underlying implementation in node-stdlib-browser uses null as the polyfill for fs. I assume this is because the implementation is fairly large and could be somewhat complicated depending on your use case.

@prpanto @zz-link what would the desired implementation look like for you? Are you attempting to use this to polyfill fs for the browser? If so, what should the underlying implementation actually do in that environment? At the very least, some more information around your use case would help me determine next steps.

Erudition commented 1 year ago

In my case, the error is with orbitDb, which actually checks for fs and sets it to null if it's not available, using other methods as a fallback. Alas, this plugin defines fs, so it passes the check but then tries to call non-existent properties on it.

So for me, a way to exclude fs from the polyfill should be good enough. (Seeing this on Vite, only in production build (rollup))

Erudition commented 1 year ago

ah, it seems fs is just a mock, with fs = null. Weird, then, that one of the packages I'm polyfilling for fails on this line:

https://github.com/orbitdb/orbit-db-storage-adapter/blob/de44df31324d69a27de506d868cb0a1daeaa65b1/src/index.js#L43

with Uncaught (in promise) TypeError: Cannot read properties of null (reading 'mkdirSync').

Shouldn't null being falsy mean that mkdirSync is never called? I'm new to JS.

davidmyersdev commented 1 year ago

@Erudition it looks like you are importing fs with import * as fs from 'fs' rather than import fs from 'fs'. I believe that coerces the import into an actual module, although it's odd that you are seeing that error message instead of something like Uncaught TypeError: fs.mkdirSync is not a function.

Erudition commented 1 year ago

@Erudition it looks like you are importing fs with import * as fs from 'fs' rather than import fs from 'fs'.

It's not mine, it's in the package linked. However it works fine in vite dev, and everywhere other than vite build...

it's odd that you are seeing that error message instead of something like Uncaught TypeError: fs.mkdirSync is not a function.

Well, as before, fs is definitely null, so .mkdirSync would look like a property access of null. The expression fs.mkdirSync is tested for truthiness first, so that would be where it errors - it's not yet used as a function.

Thanks to pnpm patch I was able to get it working by removing the line...

davidmyersdev commented 1 year ago

Well, as before, fs is definitely null, so .mkdirSync would look like a property access of null. The expression fs.mkdirSync is tested for truthiness first, so that would be where it errors - it's not yet used as a function.

This is not entirely accurate given the nature of import * statements. In aggregate named imports such as those, you are no longer importing the default export. Instead, it aggregates all named exports into a standalone module.

That said, version v0.8.1 has been released and adds support for excluding specific modules via the new exclude configuration option.

dcorb commented 1 year ago

I had the same error, and I solved it like this:

Uncaught TypeError: Cannot read properties of null (reading 'realpathSync') I'm migrating from CRA to Vite, so I don't have the project yet in a "working" state in Vite.

The error came from https://github.com/evenchange4/graphql.macro (in this file is using fs.realpathSync.

Finally I understood that graphql-macro needs babel-plugin-macros installed (I had it installed, but that's not enough for Vite).

So I found this package suitable for vite and configured it as the README says: https://github.com/itsMapleLeaf/vite-plugin-babel-macros This solved my issue.

Note: For others, maybe this is useful, polyfill some methods of fs https://github.com/StarLederer/vite-plugin-fs

davidmyersdev commented 1 year ago

@dcorb this makes me wonder if I should expose an API for allowing custom polyfill overrides. 🤔