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

safely use global #4

Closed
ibreathebsb opened this issue Jul 31, 2019 · 18 comments
Closed

safely use global #4

ibreathebsb opened this issue Jul 31, 2019 · 18 comments

Comments

@ibreathebsb
Copy link

ibreathebsb commented Jul 31, 2019

in the source code

var origSymbol = global.Symbol;

i think this one better

var origSymbol = global && global.Symbol;
@ljharb
Copy link
Member

ljharb commented Jul 31, 2019

Why? It’s a node module. global can’t ever not exist.

@oles
Copy link

oles commented Sep 3, 2019

Uh-oh.

import 'array.prototype.find'

results in: ReferenceError: global is not defined
traced to: var origSymbol = global.Symbol;

$ npm ls has-symbols
└─┬ [email protected]
  └─┬ [email protected]
    └─┬ [email protected]
      └─┬ [email protected]
        └── [email protected]

@ljharb is it better to handle the issue here or in https://github.com/es-shims/Array.prototype.find?

@ibreathebsb

This comment has been minimized.

@ljharb
Copy link
Member

ljharb commented Sep 3, 2019

@oles global is always defined in node; are you using a bundler that doesn’t define it?

@oles
Copy link

oles commented Sep 3, 2019

Should have noted that this happened in Firefox, where the usecase is polyfilling Array.prototype.find (and .flat). Sorry for missing this vital information, @ljharb!

@oles
Copy link

oles commented Sep 3, 2019

I'm using webpack, let me check my config tomorrow!

@ljharb
Copy link
Member

ljharb commented Sep 3, 2019

Webpack absolutely understands global by default or it wouldn’t be able to bundle most of npm.

@oles
Copy link

oles commented Sep 4, 2019

Aha. I've set node: false in my config. Removing that solves this!

Though this might not be the case in the future?
https://github.com/webpack/changelog-v5/blob/master/README.md#automatic-nodejs-polyfills-removed

Thanks for the help, @ljharb!

@ljharb
Copy link
Member

ljharb commented Sep 4, 2019

I doubt the global polyfill, which is a single line (global = window), will be excluded there, but certainly if webpack changes its approach then that may impose difficulty on its users.

@boris-petrov
Copy link

@ljharb - I also hit the same problem in a browser environment. Bundler is webpack with node: false. Stacktrace:

index.js:3 Uncaught (in promise) ReferenceError: global is not defined
    at Object../node_modules/has-symbols/index.js
    at Object../node_modules/es-abstract/GetIntrinsic.js
    at Object../node_modules/es-abstract/es5.js
    at Object../node_modules/string.prototype.trim/implementation.js
    at Object../node_modules/string.prototype.trim/index.js
    at Object../node_modules/parse-headers/parse-headers.js
    at Object../node_modules/xhr/index.js
    at Module../node_modules/video.js/dist/video.es.js

That is, I'm using video.js which is a browser package and it transitively includes has-symbols, which blows up because global is not defined.

Why don't you just make has-symbols browser-friendly? :)

@ljharb
Copy link
Member

ljharb commented Oct 3, 2019

@boris-petrov it is browser-friendly; node: false is what's not browser-friendly.

I could certainly use https://www.npmjs.com/package/globalthis instead of relying on global being present, but that would be unfriendly to users in a CSP environment, and would also inflate the bundle size further.

@boris-petrov
Copy link

@ljharb - I don't want to argue too much because polyfilling global is a single line of code but if you open the console in your browser right now and type global in it you'll get a global is not defined error. :) So adding node: false doesn't make it browser-unfriendly, it makes it "correct". I agree that it would inflate the bundle size but... that's the way JavaScript works unfortunately.

Again, feel free to ignore my comment as it is not a big deal, but I believe that right now the behavior is not correct.

Thank you for the time!

@ljharb
Copy link
Member

ljharb commented Oct 8, 2019

You’re totally right that global doesn’t work in a browser - but by default, any npm package that uses global (and there are a great many) is transpiled to use window by every bundler. Using node: false is disabling that default and thus deviating from community convention.

require doesn’t work in the browser either, but i don’t see you complaining about the use of require - this is a node module, and “browser friendly” for all node modules means “transpiles the way browserify does by default”.

@boris-petrov
Copy link

OK, fair enough! Thanks again!

@Knagis
Copy link

Knagis commented Dec 27, 2019

https://docs.npmjs.com/files/package.json#browser

You can specify a separate implementation for node and browser environments - this way your package would work out of the box for both and neither includes code that is not needed.

As pointed out in a comment above, webpack 5 no longer transpiles global to window by default so you might see duplicates of this issue popping up more often once they get out of beta.

@ljharb
Copy link
Member

ljharb commented Dec 27, 2019

Webpack 5 isn’t out yet, and i still hope to convince them to restore the proper behavior of transpiling global to window.

You’re right that i could duplicate the entire file just to change global to window, but since every bundler window the beginning of node has done that, it seems like a strange redundancy to force on the entire ecosystem.

@bhushanlaware
Copy link

still getting this issue, can't we use globalThis instead global?

@ljharb
Copy link
Member

ljharb commented Jan 4, 2022

@bhushanlaware no, can’t we use non-broken bundlers instead of broken ones?

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

6 participants