Leonidas-from-XIV / node-xml2js

XML to JavaScript object converter.
MIT License
4.88k stars 602 forks source link

Angular 8: ReferenceError: global is not defined at node_modules/has-symbols/index.js #538

Closed chrisoppedal closed 4 years ago

chrisoppedal commented 4 years ago

Here's my implementation:

import { parseString } from 'xml2js'; ... parseString(xmlStrResponse, (err, result) => { console.dir(result); });

It seems like parseString is getting properly imported because I see errors when the parameters aren't right. However I get this error no matter what I send to parseString:

Uncaught ReferenceError: global is not defined at Object../node_modules/has-symbols/index.js (index.js:3) at webpack_require__ (bootstrap:79) at Object../node_modules/es-abstract/es2016.js (es2016.js:3) at webpack_require (bootstrap:79) at Object../node_modules/es-abstract/es7.js (es7.js:3) at __webpack_require (bootstrap:79) at Object../node_modules/object.getownpropertydescriptors/implementation.js (implementation.js:3) at webpack_require__ (bootstrap:79) at Object../node_modules/object.getownpropertydescriptors/index.js (index.js:5) at webpack_require__ (bootstrap:79)

Leonidas-from-XIV commented 4 years ago

Looks like an issue with webpack to me.

tgangso commented 4 years ago

Strugling with the same issue, any workaround?

chrisoppedal commented 4 years ago

I haven't gotten around to look at it. I'm using the latest version of Angular CLI, I'm going to try an older version to see if that gets webpack to work.

tgangso commented 4 years ago

Converting a project from ionic 3 (angular 5) to ionic 4 (angular 8). Worked fine before, but not anymore, this is the only library i got an issue with.

Should be easy for the author to replicate and see what needs to be done? Just create a new angular project and add the npm package, use it in the app component, then npm start will give you the error.

etbresso commented 4 years ago

I find that and it's work for me : https://stackoverflow.com/questions/54201934/referenceerror-global-is-not-defined-with-stream-and-angular-7-1

Leonidas-from-XIV commented 4 years ago

As mentioned above, it is not an xml2js issue but rather a problem with Angular or Webpack.

tgangso commented 4 years ago

Maybe not the main priority of this project, the workaround seems to work ok for now.

Did however also note this comment about the workaround: "global does not exist in a browser. A library that supports web browsers should not be using Node.js specific functionality."

https://github.com/angular/angular-cli/issues/8160#issuecomment-511012706

Still think this is something you should look into on your end.

chrisoppedal commented 4 years ago

Adding this line to polyfills.ts fixed the issue:

(window as any).global = window;

elezar42 commented 4 years ago

This was introduced with the recent change to use util.promisify. That package has a dependency on the has-symbols package, which relies on Node.js specific functionality.

@Leonidas-from-XIV, you're right that this is because of how Angular configures Webpack. It explicitly sets Webpack to not include shims for Node specific functionality, as mentioned in https://github.com/angular/angular-cli/issues/9827#issuecomment-369578814) But by using util.promisify, you're keeping xml2js from being able to work with Angular out of the box.

Maybe you don't really care if it works with Angular, but that's obviously a very widely used framework, so I think it would be great if you could find a way to allow xml2js to work, without the dependency on packages that rely on Node.js specific functionality.

tgangso commented 4 years ago

Do you have more info on what issues the workaround can cause?

elezar42 commented 4 years ago

Actually, I didn't really pay attention to what the workaround posted was. In the past, the workarounds I've seen have been trying to get ALL of the global vars that Node declares in, some of which have values that shouldn't be static, but don't get updated outside of a Node environment. Only adding the "global" var as listed here I think would be fine. I took the line about it causing problems out of my previous comment.

tgangso commented 4 years ago

@elezar42 ok great, would like to know if there where any issues before going to production. Still agree with your post, would be great if there was some easy way to avoid using promisify and be fully compatible.

Leonidas-from-XIV commented 4 years ago

@elezar42 Thanks for the investigation. I still go by the fact that this is node-xml2js and the fact that it runs in the browser is mostly accidental, since I don't have any kind of test suite of any kind that it works in the browser.

The promisify case is a mix of "damned if you do, damned if you don't" (cc @knoxcard): promise functionality was a commonly asked feature for many years and finally implemented, but it broke something else. Now I'm at an impasse, since I can't really remove the feature itself. I see two ways this can go forward:

  1. Use an older version of xml2js that didn't use util.promisify (or its shim for older node versions). There's hardly any changes since so by using an older version you're not missing out on much.
  2. Submit a PR for implementing util.promisify that is compatible with both Node and Angular.
tgangso commented 4 years ago

What version would be the latest that is not using promisify?

Leonidas-from-XIV commented 4 years ago

What version would be the latest that is not using promisify?

0.4.20.

tgangso commented 4 years ago

Thanks, I can confirm 0.4.20 works with no workaround. Maybe a note in the readme about angular compatibility can be added?