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

caught ReferenceError: global is not defined #2

Closed
bjornharvold opened this issue Nov 8, 2019 · 5 comments
Closed

caught ReferenceError: global is not defined #2

bjornharvold opened this issue Nov 8, 2019 · 5 comments

Comments

@bjornharvold
Copy link

Great library!

For some reason, today ng-qrcode failed with a big fat error.

Uncaught ReferenceError: global is not defined
    at Object.../../node_modules/node-libs-browser/node_modules/buffer/index.js (index.js:43)
    at __webpack_require__ (bootstrap:79)
    at Object.../../node_modules/qrcode/lib/core/reed-solomon-encoder.js (reed-solomon-encoder.js:3)
    at __webpack_require__ (bootstrap:79)
    at Object.../../node_modules/qrcode/lib/core/qrcode.js (qrcode.js:10)
    at __webpack_require__ (bootstrap:79)
    at Object.../../node_modules/qrcode/lib/browser.js (browser.js:4)
    at __webpack_require__ (bootstrap:79)
    at Module.../../node_modules/ng-qrcode/fesm2015/ng-qrcode.js (ng-qrcode.js:1)

I did some Googling and found:
global is not available as of Angular 6.

Library authors should not depend on this property. See this post: angular/angular-cli#9827 (comment)

As a workaround for now, I am putting this is my polyfills.ts
(window as any).global = window;

@mnahkies
Copy link
Owner

Thanks for the report. I've generally found myself making a similar polyfill in most angular projects for one reason or another, but agree with the reasoning behind the comment you linked.

Based on the stack trace it's coming from a deeply nested dependency, so there may not be a lot I can do, but I'll investigate and at the least add a note to the readme if it's not practical to patch the underlying dependency.

I wouldn't feel comfortable adding such a polyfill to the library itself, as that feels a bit presumptuous to do in a library

@bjornharvold
Copy link
Author

Thanks @mnahkies. I saw that too. Just thought I'd reach out in any case.

@mnahkies
Copy link
Owner

mnahkies commented Dec 9, 2019

I've had a more detailed investigation into this, and it's actually quite a tricky situation.

The issue

Looking at the https://github.com/feross/buffer repository, you'll notice that the bug is present in the 4.x branch, but not master - it's fixed on buffer@5.x.

I made a new project, and then did:

$ npm ls buffer
top level project
├─┬ @angular-devkit/build-angular@0.900.0-rc.5
│ └─┬ webpack@4.41.2
│   └─┬ node-libs-browser@2.2.1
│     └── buffer@4.9.2
└─┬ ng-qrcode@3.0.1
  └─┬ qrcode@1.4.4
    └── buffer@5.4.3

So you can see, that the qrcode module actually directly depends on the correct dependency, but unfortunately a different version gets brought in by webpack through node-libs-browser. Upgrading node-libs-browser isn't an option as it is deprecated and no longer used in webpack@5

For whatever reason webpack chooses to bundle up the old v4 version instead of the v5 version that our dependency actually wants.

Ideally the angular team would update angular to use webpack@5 which would remove the node-libs-browser dependency and solve our immediate issue.

However this seems a bit of a band aid solution, as the current way that the angular/webpack bundling is working seems to completely preclude the ability to have two libraries in the dependency tree that depend on incompatible library versions co-exist correctly.

I don't know enough about webpack configuration to know if this is a problem that can be solved through tweaks there, but bottom line is that angular 9 still depends on webpack 4 and so this specific problem won't be going away by itself in a hurry.

Possibly related webpack issue: webpack/webpack#9739

Workarounds

I can see two different workarounds, each with pro's/con's. I'll go ahead and document these on the readme and then close this issue.

Define global in index.html

Edit your applications index html to have a script section in the <head> like this:

<script>window.global = window</script>

This is something that I personally end up doing with most angular projects, but your mileage may vary.

Note: as @bjornharvold originally noted you could also put this in polyfills.ts as

(window as any).global = window;

However I'd be slightly wary as I'm unsure if polyfills.ts gets executed when rendering using SSR / Angular Universal on NodeJS for example, and I don't have a project to hand that I can test this with unfortunately.

caveat this means that qrcode will still be obtaining an outdated version of buffer compared to what it is expecting. I haven't seen this cause any issues so far though.

Force node-libs-browser to use buffer@^5.4.3

Methods:

From what I can tell this also fixes the problem, and is technically more correct as it means that the version of buffer expected by qrcode will be provided.

@mnahkies
Copy link
Owner

Closing as per above comment.

Note that with some further observation I've found that it doesn't affect every project, seems to be a bit of luck involved as to how the node modules directory structure ends up looking - deleting package-lock.json / node_modules and then running npm install may resolve for some projects.

@bdirito
Copy link

bdirito commented Feb 20, 2020

Note that webpack@5 is still in beta (as of 2020 02 20)

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

3 participants