hildjj / node-cbor

Encode and decode CBOR documents, with both easy mode, streaming mode, and SAX-style evented mode.
MIT License
356 stars 73 forks source link

ReferenceError: Can't find variable: TextDecoder #167

Closed Knaackee closed 1 year ago

Knaackee commented 2 years ago

Hello, thanks for your work!

I try to use this library in a react-native (expo) app and got a problem getting it working.

I read here https://github.com/hildjj/node-cbor/issues/162 that it should work if i use the Simple TextDecoder polyfill but i am still getting ReferenceError: Can't find variable: TextDecoder.

Any ideas?

const TextDecoder = require("@cto.af/textdecoder");
// ReferenceError: Can't find variable: TextDecoder
const cbor = require("cbor");
hildjj commented 2 years ago

Try following the directions here. It's not enough to require @cto.af/textdecoder, you have to get it hooked into the correct global variable where it's supposed to be.

Knaackee commented 2 years ago

Thanks for the quick reply!

I followed the instructions (added the package and modified the metro.config.js).

Now I am getting another Error:

TypeError: Super expression must either be null or a function

require("cbor-rn-prereqs");
// TypeError: Super expression must either be null or a function
const cbor = require("cbor");

Thanks again for your help!

hildjj commented 2 years ago

Can you give me the full backtrace please? Feel free to trim out path names that are local to your environment.

Knaackee commented 2 years ago

Sure, here are the errors I am getting. I don't see anything related to node-cbor 🤔

TypeError: Super expression must either be null or a function

Stack trace:
  D:\MyProject\node_modules\react-native\Libraries\LogBox\LogBox.js:149:8 in registerError
  D:\MyProject\node_modules\react-native\Libraries\LogBox\LogBox.js:60:8 in errorImpl
  D:\MyProject\node_modules\react-native\Libraries\LogBox\LogBox.js:34:4 in console.error
  node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
  D:\MyProject\node_modules\react-native\Libraries\Core\ExceptionsManager.js:104:6 in reportException
  D:\MyProject\node_modules\react-native\Libraries\Core\ExceptionsManager.js:172:19 in handleException
  D:\MyProject\node_modules\react-native\Libraries\Core\setUpErrorHandling.js:24:6 in handleError
  D:\MyProject\node_modules\@react-native\polyfills\error-guard.js:49:36 in ErrorUtils.reportFatalError
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:204:6 in guardedLoadModule
  http://192.168.188.93:19000/__generated__%5CAppEntry.bundle?platform=android&dev=true&hot=false&minify=false:244727:3 in global code
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.

Stack trace:
  D:\MyProject\node_modules\react-native\Libraries\LogBox\LogBox.js:149:8 in registerError
  D:\MyProject\node_modules\react-native\Libraries\LogBox\LogBox.js:60:8 in errorImpl
  D:\MyProject\node_modules\react-native\Libraries\LogBox\LogBox.js:34:4 in console.error
  node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
  D:\MyProject\node_modules\react-native\Libraries\Core\ExceptionsManager.js:104:6 in reportException
  D:\MyProject\node_modules\react-native\Libraries\Core\ExceptionsManager.js:172:19 in handleException
  D:\MyProject\node_modules\react-native\Libraries\Core\setUpErrorHandling.js:24:6 in handleError
  D:\MyProject\node_modules\@react-native\polyfills\error-guard.js:49:36 in ErrorUtils.reportFatalError
  D:\MyProject\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:367:8 in __guard
  D:\MyProject\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:112:4 in callFunctionReturnFlushedQueue
  [native code]:null in callFunctionReturnFlushedQueue

I did a try catch block around the require like:

try {
  require("cbor");
} catch (err) {
  console.log(err);
}

and getting.

Super expression must either be null or a function

Stack trace:
  D:\MyProject\node_modules\@babel\runtime\helpers\inherits.js:5:10 in _inherits
  http://192.168.188.93:19000/__generated__%5CAppEntry.bundle?platform=android&dev=true&hot=false&minify=false:241013:13 in <unknown>
  D:\MyProject\node_modules\ieee754\index.js:53:6 in exports.write
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:349:11 in loadModuleImplementation
  http://192.168.188.93:19000/__generated__%5CAppEntry.bundle?platform=android&dev=true&hot=false&minify=false:238934:28 in <unknown>
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:349:11 in loadModuleImplementation
  http://192.168.188.93:19000/__generated__%5CAppEntry.bundle?platform=android&dev=true&hot=false&minify=false:238359:25 in <unknown>
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:349:11 in loadModuleImplementation
  D:\MyProject\node_modules\big-integer\BigInteger.js:1019:9 in prototype.shiftLeft
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:349:11 in loadModuleImplementation
  App.tsx:54:9 in <global>
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:349:11 in loadModuleImplementation
  __generated__\AppEntry.js:7:0 in <global>
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:349:11 in loadModuleImplementation
  D:\MyProject\node_modules\metro-runtime\src\polyfills\require.js:201:44 in guardedLoadModule
  http://192.168.188.93:19000/__generated__%5CAppEntry.bundle?platform=android&dev=true&hot=false&minify=false:244731:3 in global code
hildjj commented 2 years ago

I assume that when you remove the require('cbor') line, the error goes away?

Knaackee commented 2 years ago

That's correct. :) But I want to use it. :)

hildjj commented 2 years ago

OK, I just did this on my local box, and everything worked:

// somewhere down below in the view {cbor.encode(254).toString('hex')}   {cbor.decode('18ff')}


* `npx react-native run-ios`

What I saw in the iOS emulator, in the right spot: `18fe 255`
hildjj commented 2 years ago

https://stackoverflow.com/questions/30116430/reactjs-giving-error-uncaught-typeerror-super-expression-must-either-be-null-or and https://medium.com/@anuhosad/react-errors-super-expression-must-either-be-null-or-a-function-4aac6e5173ad have some other things to check.

Knaackee commented 2 years ago

Thanks a lot. I already read the posts. I am still getting:

Requiring module "..\..\..\node_modules\cbor\lib\cbor.js", which threw an exception: TypeError: Super expression must either be null or a function

The only difference I see is that I am using an expo typescript app.

hildjj commented 2 years ago

Try this, which just worked for me in an expo/TypeScript project:

const p = require('cbor-rn-prereqs');
p.patchGlobal(globalThis);
const cbor = require('cbor');

I think the difference is that globalThis and global are somehow different in your world.

hildjj commented 2 years ago

I haven't been able to cause the TypeError you're getting, and now it seems like this works (although I'd swear it didn't the first time I tried it):

require('cbor-rn-prereqs');
const cbor = require('cbor');

Why don't you email me at the address in the package.json file, and we'll see if we can either set up a time to do a screen share, or get me access to your project.

Knaackee commented 2 years ago

Thanks a lot but patchGlobal doesn't resolve the problem.

I am trying some things and report back.

Sure, if I have still no success, I post a public repo link.

Knaackee commented 2 years ago

Ok, I found the problem.

require resolves to the wrong "stream" package although i got

resolver: {
    extraNodeModules: {
      stream: require.resolve('stream-browserify'),
    },
 }

in my metro.config.js.

I replaced require("stream") with require("stream-browserify") in the cbor and nofilter package and it now works. Any idea why extraNodeModules is not working? I use expo-yarn-workspaces which does a lot of customiziation inside metro.config.js.

Do you know something that could prevent extraNodeModules from working?

hildjj commented 2 years ago

At this point, I think we're pretty clear it's an issue with metro/react-native, in which I have almost no expertise, sorry. However, let me suggest some avenues of exploration:

hildjj commented 2 years ago

Can you send the full contents of your metro.config.js file as well, please? I assume you're calling createMetroConfiguration then adding to whatever came back from that before exporting it?

Knaackee commented 2 years ago

Sorry for not getting back to you sooner.

  1. Yes, I see a stream package in my node_modules.
  2. Yes, I can make changes.
  3. I use expo-yarn-workspaces to configure metro.config.js. Pretty basic.

Thanks for your help!

hildjj commented 2 years ago

Contents of metro.config.js?

smitalm commented 2 years ago

In my case, this was problem with documentation. While documentation states, that node 10+ versions are supported, node v10 does not have TextDecoder class (which was added in later versions).

hildjj commented 2 years ago

I see I missed at least one document reference to the move to Node 12 in the last major release. WillFix, sorry.

Also see #169, where I chased this down for a different flavor of NativeScript. The conclusion there is that NativeScript added a broken TextDecoder implementation.

hildjj commented 1 year ago

I fixed the doc issue (note that we're up to requiring Node 14 now). I think this is as solved as it's going to get until NativeScript fixes their TextDecoder bug.