-
Notifications
You must be signed in to change notification settings - Fork 27.4k
refactor(jshint): don't assume browser-only globals #14345
Conversation
I also updated JSHint. |
@petebacondarwin I see JSHint failures in the docs gulp task. Which JSHint config is used to lint |
@mgol I guess it is just the top level |
If you want we could copy a docs specific |
Where are globals like
|
WRT |
@gkalpak - in that case we need dgeni to create and provide such a file for every example that contains e2e tests. |
Why is that ? Can't we just put the required globals in a parent directory's |
OK, so I forgot that the e2e tests all go in their own folder.
So we should copy a baseline |
We can extend a common one, no need to copy all the settings. :) |
Would it be possible to use |
@lgalfaso It would but I'm pretty sure it'd break a lot of tests as people are mocking Also, we're currently providing globals We might consider all that for 1.6 but I wanted to land something in 1.5.x and it seems too risky to me. WDYT? |
Fair point, let's keep window On Friday, April 1, 2016, Michał Gołębiowski notifications@github.com
|
@mgol, now that you mention it, couldn't we just change |
@gkalpak I've already talked with @petebacondarwin about that. :) I plan to apply this change. |
So, I've been wondering about this change. Since I'm removing Line 5 in b54634d
.jshintrc for all source files that would declare these assumed browser globals? Or maybe we should just prefix all browser globals with window. and not do all that? Thoughts?
|
Don't we have that situation right now? |
The |
OTH, as @lgalfaso mentioned, ideally we'd use |
@mgol I think that your suggestion based on moving to using |
@petebacondarwin on it! |
PR updated. |
All tests have passed this time. |
Sweet! |
@@ -88,7 +109,7 @@ gulp.task('assets', ['bower'], function() { | |||
}); | |||
|
|||
|
|||
gulp.task('doc-gen', ['bower'], function() { | |||
gulp.task('doc-gen', ['bower'], function(cb) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need the callback here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right; I forgot to remove it after backtracking from a previous idea. :)
@@ -3,4 +3,4 @@ | |||
* (c) 2010-2016 Google, Inc. http://angularjs.org | |||
* License: MIT | |||
*/ | |||
(function(window, document, undefined) { | |||
(function(window) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that having undefined
as a parameter, which is not assigned, is actually a clever way to ensure that we have the "real" undefined
inside the closure. So I am for leaving this as a parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would it guard against, though? We've used to have the same parameter in jQuery but we removed it; if someone created a variable undefined
that is not equal to undefined
, basically everything would be broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IOW, shadowning undefined
with sth else is more or less equivalent to shadowing any other builtin like Object
, Array
, Object.prototype
methods etc. There are lots of ways in which someone can create a broken environment in which Angular breaks. I don't think it buys us much to defend just against shadowing undefined
and it's impossible to guard against everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var old_undefined = undefined;
undefined = {};
function moo(undefined) {
console.log(undefined === old_undefined);
}
moo();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know what it does. :) What I'm saying is that it doesn't really buy us much; there are thousands other APIs that, if messed with, will break Angular and we don't protect against such changes. Moreover, I think it's more likely that someone will break Object.prototype
for us than that they'll shadow undefined
. I feel this undefined
parameter is only providing a false sense of security.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It saves us from using void 0
everywhere, no?
I agree it doesn't save us from the other stuff, but we do have various bits of defensive code in place in the case that people do override parts of the Object.prototype
.
What is the benefit in removing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It saves us from using
void 0
everywhere, no?
I'd just rely on the undefined
from the outer scope. Note that it's not even possible in ES5 to overwrite undefined
, it's immutable even in sloppy mode (the only difference is that in strict mode trying to overwrite undefined
throws while in sloppy mode it's just a noop). The only way this could backfire is if Angular was loaded not via a regular script tag but wrapped in a separate closure which shadowed undefined
. But that requires modifying the source and if someone does that we've already lost the battle.
I agree it doesn't save us from the other stuff, but we do have various bits of defensive code in place in the case that people do override parts of the Object.prototype.
Since the global undefined
is immutable if Angular is loaded normally so that its undefined
points to the global one no one is able to modify that; shadowing is also impossible after the fact.
What is the benefit in removing it?
There is no huge benefit, perhaps a tiny size decrease. If you feel strongly about it, I'll restore it. :) I just think it doesn't really solve any problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, you convinced me :-)
OK, LGTM - please merge |
👍 Regarding the using |
That's why I didn't want to land it for 1.5. As for 1.6, we can still discuss. |
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Feature: We're no longer assuming browser globals in
src/**/*.js
which will prevent issues like #13442 from happening in the future.What is the current behavior? (You can also link to an open issue here)
Currently browser globals are assumed. This sometimes breaks tools like jsdom that make them available under
window
but not as globals; see e.g. #13442.What is the new behavior (if this is a feature change)?
For the browser these changes shouldn't matter. In other environments browser globals are now taken from the
window
variable instead of the global.Does this PR introduce a breaking change?
No.
Please check if the PR fulfills these requirements
Tests for the changes have been added (for bug fixes / features)Docs have been added / updated (for bug fixes / features)Other information:
Fixes #13442