rdfjs / N3.js

Lightning fast, spec-compatible, streaming RDF for JavaScript
http://rdf.js.org/N3.js/
Other
676 stars 127 forks source link

[Support or Bug] Uncaught TypeError: process.nextTick is not a function #386

Closed white-gecko closed 3 weeks ago

white-gecko commented 3 weeks ago

When I use the n3 StreamParser in a vue application with vite in the browser I get the error:

Uncaught TypeError: process.nextTick is not a function

I think this must be a quite common setup, so I wonder wham am I doing wrong?

I have put my mwe in a repository: https://github.com/white-gecko/2024-06-10-n3-issue-mwe

If you want to have more information please ask.

Thank you very much.

jeswr commented 3 weeks ago

Looking at your error log, the error seems to be occurring in the readable-stream dependency in https://github.com/nodejs/readable-stream/blob/main/lib/internal/streams/readable.js - would you be able to create a minimal repro making use of that package directly without N3.js and open an issue upstream.

RubenVerborgh commented 3 weeks ago

Suspected compilation pipeline misconfiguration; the process.nextTick bit is Node.js code that should never end up in the browser.

bergos commented 3 weeks ago

I'm guilty of adding the process Node.js polyfill to the readable-stream package. It was required because most bundlers removed the feature to inject the polyfills automatically.

I've used readable-stream with different bundlers, including vite, without any problems. But I haven't used it in the context of a Vue application. Maybe it's overwritten by Vue. I also noticed that you load the Node.js polyfills. n3 doesn't require it. If you added it for streamify-string, then you can get rid of it with Readable.from([dataString]).

white-gecko commented 3 weeks ago

Thank you for this information.

If I do

import { Readable } from 'stream' 
…
Readable.from(dataString).pipe(streamParser)

I get: Uncaught Error: Readable.from is not available in the browser.

Also when I remove the polyfills vite-plugin-node-polyfills, and nodePolyfills() I get:

Uncaught TypeError: Buffer2 is undefined
    js index.js:12
    __require chunk-ZS7NZCD4.js:8
    js string_decoder.js:26
    __require chunk-ZS7NZCD4.js:8
    js readable.js:68
    __require chunk-ZS7NZCD4.js:8
    js duplex.js:36
    __require chunk-ZS7NZCD4.js:8
    js pipeline.js:14
    __require chunk-ZS7NZCD4.js:8
    js compose.js:3
    __require chunk-ZS7NZCD4.js:8
    js operators.js:12
    __require chunk-ZS7NZCD4.js:8
    js stream.js:32
    __require chunk-ZS7NZCD4.js:8
    js browser.js:3
    __require chunk-ZS7NZCD4.js:8
    <anonymous> N3Store.js:2
index.js:12:4

As you see, I'm really no JavaScript expert … :-(

bergos commented 3 weeks ago

I guess the polyfills are older. That's why there is no Readable.from() method. You must add readable-stream as a dependency in the latest version and use it in the import statement. Modern bundlers don't give you any packages out-of-the-box. All imports should point to your source or packages that are part of your dependencies.

When using Readable.from(), don't forget that it must be called with an array/iterable. Just wrap the string as a single element into an array like this: [dataString].

white-gecko commented 3 weeks ago

@bergos Thank you for your help. Still I don't get it running.

When I replace streamify-string by readable-string cf. https://github.com/white-gecko/2024-06-10-n3-issue-mwe/pull/1/files I get the nextTick error.

Uncaught TypeError: process.nextTick is not a function
    resume readable.js:903
    resume readable.js:895
    on readable.js:821
    pipe readable.js:702
    tryStore App.vue:24
    mounted App.vue:18
    VueJS 8
    <anonymous> main.js:4
readable.js:903:12

When I also remove the polyfills cf. https://github.com/white-gecko/2024-06-10-n3-issue-mwe/pull/2/files, the n3 store can't get the Buffer

Uncaught TypeError: Buffer is undefined
    js index.js:12
    __require chunk-ZS7NZCD4.js:8
    js string_decoder.js:26
    __require chunk-ZS7NZCD4.js:8
    js readable.js:68
    __require chunk-ZS7NZCD4.js:8
    js duplex.js:36
    __require chunk-ZS7NZCD4.js:8
    js pipeline.js:14
    __require chunk-ZS7NZCD4.js:8
    js compose.js:3
    __require chunk-ZS7NZCD4.js:8
    js operators.js:12
    __require chunk-ZS7NZCD4.js:8
    js stream.js:32
    __require chunk-ZS7NZCD4.js:8
    js browser.js:3
    __require chunk-ZS7NZCD4.js:8
    <anonymous> N3Store.js:2
index.js:12:4

edit

In another context it is missing Buffer2, when I remove the polyfill:

Uncaught TypeError: Buffer2 is undefined
    js index.js:12
    __require chunk-ZS7NZCD4.js:8
    js string_decoder.js:26
    __require chunk-ZS7NZCD4.js:8
    js readable.js:68
    __require chunk-ZS7NZCD4.js:8
    js duplex.js:36
    __require chunk-ZS7NZCD4.js:8
    js pipeline.js:14
    __require chunk-ZS7NZCD4.js:8
    js compose.js:3
    __require chunk-ZS7NZCD4.js:8
    js operators.js:12
    __require chunk-ZS7NZCD4.js:8
    js stream.js:32
    __require chunk-ZS7NZCD4.js:8
    js browser.js:3
    __require chunk-ZS7NZCD4.js:8
    <anonymous> N3Store.js:2
index.js:12:4
white-gecko commented 3 weeks ago

Ok, I get it, I should only import the buffer polyfill. https://github.com/white-gecko/2024-06-10-n3-issue-mwe/pull/3/files

Thank you @jeswr , @RubenVerborgh , and @bergos for you support!