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

Proposal: global.window = global #1043

Closed
isaacs opened this issue Mar 3, 2015 · 34 comments
Closed

Proposal: global.window = global #1043

isaacs opened this issue Mar 3, 2015 · 34 comments
Labels
discuss Issues opened for discussions and feedbacks.

Comments

@isaacs
Copy link
Contributor

isaacs commented Mar 3, 2015

One of the biggest and weirdest stumbling blocks I'm seeing as people try to use npm and CommonJS for browser code is the difference in spelling of global vs window.

I'd like to propose that we just go ahead and create a global called window that is a reference to node's global object.

Yes, yes, "window" is a silly name. It was silly in the browser, and it's even sillier outside of it. But it's a fixture in the language, extremely low-risk, and will reduce a lot of friction onboarding browser JavaScript people.

@mscdex
Copy link
Contributor

mscdex commented Mar 3, 2015

-1 It seems like a bad idea to let people pollute the global namespace by default like that on the server side, especially if there is a dependency that pulls in such browser-side javascript module and the user is totally unaware that globals are being messed with. IMHO it's better to fix the javascript in question to detect node and set module.exports instead.

@cjihrig
Copy link
Contributor

cjihrig commented Mar 3, 2015

I'm -1. Seems like encouraging a bad habit.

@Fishrock123
Copy link
Member

-1

It's not like this is browser-land where there isn't yet a module system in place.

@chrisdickinson
Copy link
Contributor

extremely low-risk

Adding window stands a chance of breaking code that sniffs that variable for environment hints. I can't say how much code – I know anecdotally past me has definitely done it – but it does worry me a bit.

@tellnes
Copy link
Contributor

tellnes commented Mar 3, 2015

-1

The ReferenceError you get saying window is not defined does indirectly also says to the user "you are not in the browser now".

@seishun
Copy link
Contributor

seishun commented Mar 3, 2015

-1

Ugly, potentially breaking and doesn't actually solve anything.

@medikoo
Copy link

medikoo commented Mar 3, 2015

-1 Terrible idea

@moll
Copy link

moll commented Mar 3, 2015

There are probably more problems with importing code that depends on window than just the existence of window. Like not actually being a Window instance.

Perhaps a simple mention of something like JSDOM is sufficient for people looking to run browser code in IO.js.

@isaacs
Copy link
Contributor Author

isaacs commented Mar 4, 2015

So, this is clearly a bit unpopular so far! Nevertheless, some of the objections are substantive, so I will explain my reasoning.

@mscdex You say "it's better to fix the javascript in question to detect node and set module.exports instead." And I don't disagree. But that is orthogonal to the problem. You can still modify the code to detect node and set module.exports, and there are other ways to detect the browser. But this would make much of that work optional, strictly increasing the utility gained from the corpus of JavaScript to date.

@cjihrig What bad habit it would it be encouraging? People already can set things as globals in node. (Not to mention that every module is a global.)

@Fishrock123 "It's not like this is browser-land where there isn't yet a module system in place." I don't see the relevance.

@chrisdickinson Breaking existing node modules is a good point. I should try to see about investigating public npm packages for that behavior.

@tellnes There are already lots of ways we directly tell users that. See also my response to @chrisdickinson. If this is the primary blocker, it can be quantified and investigated quite easily.

@moll While yes, code that does window.open() will never work in node, there's an awful lot of JavaScript that just uses window as a hook for global.

@jbergstroem
Copy link
Member

If this lands in tree it'd probably be around forever. For that reason alone I feel time – and counter-arguments like above – needs to stand between opinion and commits.

@medikoo
Copy link

medikoo commented Mar 4, 2015

@cjihrig What bad habit it would it be encouraging? People already can set things as globals in node. (Not to mention that every module is a global.)

But they don't do that. CJS format as used in iojs, totally deprecates using globals. It may even be better if there's no global exposed at all (as it's hard to find justifiable use case for it).

Bringing window in, will just open pandora's box of issues, for those not familiar with iojs. Those familiar will never try to use window (global either), but those who are not, will expect window to implement tens of things they used to have in browser.

iojs is different world, and it should not pretend it isn't, it'll be just confusing. It's much better if those not educated crash at first step.

@yosuke-furukawa
Copy link
Member

I guess ES6 module is the true key for removing friction for browser and server.

If io.js team will support ES6 module, I am -1 on this. we had better to choose more suitable way. And io.js should not add the workaround like global.window.

If io.js team will not support it, I am +1 on this. global.window will save Many JavaScript developers that would like to create libraries works on browser and server.

@Globegitter
Copy link

I am with @yosuke-furukawa here. The differences io.js and browser coding should be as minimal as possible and I think supporting ES6 modules should be the aim and would be preferred, but if that is not planned, 👍 for this proposal.

@drkibitz
Copy link

drkibitz commented Mar 4, 2015

-1 on global.window,
but I would like to propose global.self = global
https://developer.mozilla.org/en-US/docs/Web/API/Window/self

It's a very modest proposal as self still represents a WindowProxy without postMessage, but just thought I would throw it out there.

@mathiasbynens
Copy link
Contributor

It's a very modest proposal as self still represents a WindowProxy without postMessage

@drkibitz That doesn’t make sense. In browsers, self === window and self.postMessage === window.postMessage.

@drkibitz
Copy link

drkibitz commented Mar 4, 2015

@mathiasbynens that's why I mentioned that in my comment if it were implemented as global.self = global, no postMessage. Sorry probably badly worded. The difference is minor IMO, but just throwing it out because it is yet another global to take note of.

@Fishrock123 Fishrock123 added the discuss Issues opened for discussions and feedbacks. label Mar 6, 2015
@jkrems
Copy link
Contributor

jkrems commented Mar 9, 2015

-1 on this. I saw too much code that attaches itself as a global if window exists. Which seems like an awkward potential regression ("introduces global leaks somewhere in your dependency tree - have fun searching for it!").

@bnoordhuis
Copy link
Member

It seems the responses are overwhelmingly negative. Moving to close.

@yosuke-furukawa Apropos ES6 modules, nothing has been hashed out yet but the plan is to support them eventually. There is still a lot of work to be done in V8 before io.js can start looking into it, though.

@popomore
Copy link
Contributor

We can make a suggestion for legacy usage that use a window module instead.

const window = require('window');

It's a pollyfill for window object that make compatible between iojs and
browser.

On 2015年3月10日 周二 at 下午6:44 Ben Noordhuis notifications@github.com wrote:

It seems the responses are overwhelmingly negative. Moving to close.

@yosuke-furukawa https://github.com/yosuke-furukawa Apropos ES6
modules, nothing has been hashed out yet but the plan is to support them
eventually. There is still a lot of work to be done in V8 before io.js can
start looking into it, though.


Reply to this email directly or view it on GitHub
#1043 (comment).

@yosuke-furukawa
Copy link
Member

@bnoordhuis
Sounds good. I had better to watch some NG issues. :D nodejs/NG#9

@3rd-Eden
Copy link
Contributor

There is no actual window on the server. This makes absolutely no sense not to mention all the confusion that it's going to cause that it's actually available but there is no window.document to manipulate.. -1

@bevacqua
Copy link

-1

We shouldn't embrace the bad parts of client-side JavaScript just to encourage jQuery plugin developers to publish more modules on npm

@evantahler
Copy link

-1 in core, +1 in user land.

It seems that this could become a well-documented (and thus google-able) solution for folks to do before they require anything... then all is well!

@indexzero
Copy link

-1 👎 have to echo @chrisdickinson's argument here. I'm also guilty of doing some window sniffing and I worry about all the weird places capability detection would break.

On a related note: bringing some data to this argument by static analysis of npm modules would be a really fun side project 💯

@lukeapage
Copy link

-1 this needs to be solved by ecmascript. There should be a way to get the global object, then we can polyfill that in the browser and add it ti node.

Think about web workers - window is not the global in that context.

@jwerle
Copy link

jwerle commented Mar 12, 2015

@isaacs I'm -1 for many obvious reasons, but as an idea, perhaps changing code here could "fix" references to window. The window object can become scoped to the module. This won't pollute the global namespace and still provide a window object where window == global.

  NativeModule.wrapper = [
    '(function (exports, require, module, __filename, __dirname, window) { ',
    '\n});'
  ];

  NativeModule.prototype.compile = function() {
    var source = NativeModule.getSource(this.id);
    source = NativeModule.wrap(source);

    var fn = runInThisContext(source, { filename: this.filename });
    fn(this.exports, NativeModule.require, this, this.filename, global);

    this.loaded = true;
  };

@CrabDude
Copy link

-1

  1. From a technical perspective, it might undermine code that assumes window === browser and create difficult to debug bugs.
  2. From a psychological perspective, it misses an opportunity to encourage a rethinking to those new to node that you are not in the browser.
  3. From a project perspective, it signals that social pressures (or social motivations) can trump technical motivations. This may not seem like a big deal, but it's a very bad precedent.
  4. From a community perspective, the consensus is not to put this in, so putting it in at this point sends a very negative signal to community input.
  5. From a personal perspective, I expect lower entropy from lower stack code, and this adds entropy at the lowest point in the stack (from a userland perspective).

ATM, there are literally no +1s in this thread (except a conditional +1 or 2). I'm not sure I've ever seen such consensus on a technical solution in an open source project before. I can't help but smile in agreement. Seems like a pretty strong signal.

I'm in agreement with @bnoordhuis in favor of closing the issue.

@zeke
Copy link
Contributor

zeke commented Mar 12, 2015

re: window sniffing, browserify builds have a process.browser boolean.

@cjihrig cjihrig closed this as completed Mar 12, 2015
@drkibitz
Copy link

Browserify encourages the use of global, automatically sniffing,
wrapping, and passing the correct global ref that is either self or window.

On Thursday, March 12, 2015, Zeke Sikelianos notifications@github.com
wrote:

re: window sniffing, browserify builds have a process.browser boolean.


Reply to this email directly or view it on GitHub
#1043 (comment).

@isaacs
Copy link
Contributor Author

isaacs commented Mar 12, 2015

Points taken.

Just so we're clear, yes of course I know that there are countless ways to work around this in userland code. I am not brand new to JavaScript. I've designed and written a few modules, and a few module systems, including this one. I do know how it works, but thank you all very much for all the educational pointers about node's module system, just in case I had forgotten.

The point is that this would make a lot of currently-existing legacy code work without intervention in userland, so suggesting userland fixes isn't really relevant. I know it's not much intervention.

@MattiSG
Copy link

MattiSG commented Mar 12, 2015

Well… actually, +1 🎉 💃

@sam-github
Copy link
Contributor

Maybe non-client node developers are a minority, maybe not, but I have to say that browserisms in the node API stick out like a sore thumb (process.nextTick, global setTimeout... wtf?), and adding to that list doesn't excite me.

That said, I do like minimizing pain... I just don't see "oh, node code works differently" as pain... obviously its different.

and wouldn't doing

if(global) window = global;

anywhere in user code make node be like the browser? Its even idempotent, you can do it over and over.

@tracker1
Copy link

@isaacs I would suggest that if window is defined as a reference to global that global.self be expressly locked out... so that window.self === window can always be checked for when running in a browser. I tend to check for typeof window !== 'undefined' && window.self === window for if I'm in a browser.

Building isomorphic apps means that you explicitly want to go one direction or another depending on if you are in a browser or not... by defining a global window, that tends to break down that detection a bit.

I've also written JS for other platforms outside of node and browser... I'd prefer to keep that consideration in mind.

@WebReflection
Copy link
Member

oh ... irony ... it's ending up even more badly when I've asked to stop this madness and bring global directly in ES

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discuss Issues opened for discussions and feedbacks.
Projects
None yet
Development

No branches or pull requests