ericblade / quagga2

An advanced barcode-scanner written in Javascript and TypeScript - Continuation from https://github.com/serratus/quaggajs
MIT License
758 stars 85 forks source link

NodeJS incompatibility: ReferenceError Image is not defined #150

Closed ivanvaccari closed 4 years ago

ivanvaccari commented 4 years ago

Hi. I'm trying to run the nodejs sample (https://github.com/ericblade/quagga2#using-node) but it's not working.

The reason is a dependency from the Image object which is defined only on browsers:

https://github.com/ericblade/quagga2/blob/0e792d9917a29690f2d143ed828ac94afd4d1c06/src/input/image_loader.js#L58

This line is actually making the whole script to fail.

Node version is 12.12.0

There's some suggestion about this?

ericblade commented 4 years ago

It shouldn't be entering that area of the code at all, I would think -- I'll check it out in a little bit (sometime tonight), and see if we've broken something related to that test, that has gone unnoticed.

ivanvaccari commented 4 years ago

It shouldn't be relevant but i'll add some info: image type is png, it's a whole page image coming from a pdf to png conversion made with pdf.js. Also, because that library return a nodejs buffer, the relative file is stored using npm tmp and deleted after the example scan.

ericblade commented 4 years ago

i didn't get a chance to look at that last night, but i will try to get at it very soon. i do not like having some major thing completely broken.

ericblade commented 4 years ago

I am confirming right now that that example is broken. I don't understand how, right off, but will look into it.

ericblade commented 4 years ago

I think I'm going to have to do some bisecting to figure out exactly where/how this broke, so I can see what the cause is and try to undo it. I'm also absolutely mystified here now, because I thought for sure that the test suite tested basic functionality (decodeSingle) in node, as well as in browser, and either it doesn't, or the test suite is doing something i'm not expecting/unaware of.

Alternatively, it might be worth just trying to strip out the custom code and make use of https://loaders.gl/modules/images/docs/api-reference/image-loader

As is, I see no reason why it shouldn't hit the Image() constructor, and I also see no reason why node should have an Image() constructor. It doesn't make sense. So either i've deleted some sort of polyfill, or I've removed a branch somewhere, unaware. At least, those are the two possibilities that I've thought of anyway.

ericblade commented 4 years ago

.... i've been digging for quite a while, and I cannot figure out any way in recent history that the lib could've ever worked. it definitely did, though, at one point. I'm definitely going to have to bisect on it, but I don't even know where to call 'good' .. any thoughts on what last release was working?

ivanvaccari commented 4 years ago

Hi. To be honest this is the first time i need to use a backend based scanner, so I can't suggest you on one release who ever worked.

ivanvaccari commented 4 years ago

Tried one stupid trick: iterated over all the published npm versions and noticed that things start to broke at @0.0.11 See https://gist.github.com/grisson2/7597482f17a53fe3ab0d6f35689e6755

On 0.0.11 (search for "+ @ericblade/quagga2@0.0.11") the node example broke with "ReferenceError: window is not defined", then all the subsequential versions fails for different reasons.

Note that at the moment (0.0.18), the node example is not working as-is: var Quagga = require('@ericblade/quagga2').default; makes Quagga undefined since default is undefined. Using var Quagga = require('@ericblade/quagga2'); works despite then crash with "ReferenceError: Image is not defined"

ericblade commented 4 years ago

Not a stupid trick, that's what 'git bisect' would do, basically. Thanks for finding a 'good' starting point, there's definitely been some issues since the webpack upgrade, but at least knowing that previous to that it was working, i can try to see code-wise how it was handled before then -- as far as I can tell, the only Node compatible "Image" construct thing is node-canvas .. and that is not browser compatible.. so i don't think that is what was done before.

anyway, i'll see if i can figure out what magic made it work back then, and get it back :)

ericblade commented 4 years ago

fwiw, i'm not sitting on this, just with the nation having the issues it's having right now, it's actually pulling me farther from being able to sit down and write code..

i just went backwards at 0.0.11, and that didn't seem to work either, nor 0.0.10, but 0.0.8 does seem to. i'm about to run it in debug and see if that gives some insight as to how it worked before all the changes.

ericblade commented 4 years ago

well, i've found the source of the problem (har har) .. there were a couple of files back in the old releases, in lib/ called input_stream and frame_grabber. Apparently, in the older webpack configuration, those files were somehow swapped into the code, instead of the ones in src/ when it was packaged for node.

It was not obvious to me how these files were connected, and it didn't seem to break anything by removing them, so they got removed, in favor of the newer looking files in src/ . I'd presumed that they were older versions. Turns out they are different versions for different environments.

If someone wants to resurrect these two files, and connect the code into the existing src/input_stream and src/frame_grabber via feature detection, rather than via cryptic webpack configurations, that'd be really great.

This also shows that the automated testing has even less coverage than I thought it did, and it's already proving that it's not very good coverage anyway.

I wish I'd completely revamped the test system before getting into any changes. Can't go back, though, so ever onward, eh

If no one else volunteers, I can probably do it sometime over the next few days.

ericblade commented 4 years ago

worthy of pointing out that i ended up discovering this by running debugger on identical test code on two different monitors side by side, one with 0.0.8 and one with the current master branch. Once they diverged in a non-trivial fashion, I was very confused, as the code looked really unfamiliar. I checked the filepaths, and they were in different directories, but with the same filename. Suddenly, the light bulb in my head went on.

ericblade commented 4 years ago

@grisson2 i think i've got this fixed, if you could update to 0.0.19, and let me know if you have any further issues, that'd be aweosme. might need to update the readme a bit still, but as far as i can tell, it's back to functional.

the following script works

const Quagga = require('@ericblade/quagga2');

Quagga.decodeSingle({
    decoder: {
        readers: [ 'code_128_reader' ],
    },
    locate: true,
    src: './test/fixtures/code_128/image-001.jpg',
}, function(result) {
    if (result.codeResult) {
        console.log('result', result.codeResult.code);
    } else {
        console.log('result not detected');
    }
});

browser tests also work.