-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
url: deleting properties has no effect #1591
Comments
there is no real utility in deleting like this, |
Yeah, |
Deleting the properties will not work anymore in io.js 2.0 as the properties are now getters/setters and deleting them will delete the getters/setters themselves from the instance. Nulling the properties has the same effect, while also bringing a performance gain over delete. Related: nodejs/node#1591
Deleting uri properties will not work anymore in io.js 2.0.0 as the properties are now getters/setters and deleting them will delete the getters/setters themselves from the instance. Nulling the properties has the same effect, while also bringing a performance gain over delete. Related: nodejs/node#1591
I'm pretty sure |
I don't think this can be fixed without a fundamental change in the module (and likely a big perf loss). My first idea was to set |
@silverwind it will throw an error in strict mode (at least the case you linked to, it wont for things on the prototype unfortunately) |
@monsanto thanks, I incidentally just read about that. Won't help as these properties are all on the prototype. |
How slow would it be to add the getters on the instance itself for a few releases to help people migrate? Declare the functions themselves outside of the constructor so we don't get into bad closures-and-hidden-classes territory, of course. Of course it wouldn't help for people who don't use strict mode... |
property definition is absurdly slow even if you have static functions |
Hmm I think |
Nope, |
It's a breaking release, it's ok to break delete. Just do what browsers do (normal, configurable props on the prototype). |
What's the use-case for deleting a prop? Removing that data? That is a terrible way of doing it to begin with. |
@Fishrock123 Yep, removing the data. Using |
@iojs/tc I'd like to hear from other TC members on this, we're about to ship code that will silently break usage like I don't believe this to be a simple matter of "assign to We have to have some respect for cowpaths that already exist and I'm anticipating no small amount of pain coming from this change. |
it's not "assign to falsey" but assigning to |
The issue with the configurable getters/setters is that once you delete them, reassignment will make the property a plain property, possibly causing undefined behaviour. I've been looking at using @petkaantonov Do you have an estimate how the perf would be when using plain properties again? These could theoretically be observed to avoid unecessary assignment (jsperf here). |
@silverwind the properties are on the prototype, therefore Edit: see http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.7 |
I'll try again to make the point that this behaviour is exactly the behaviour of every DOM object ever, and should not be surprising to any JS developer. |
I'm fretting about this a bit. Code has been written that relies on Given this, my preference is to ship the new URL code behind a feature flag for the duration of v2.0.0, which should be relatively short, given the impending V8 upgrade. If we can't get the code behind a feature flag in time for the v2.0.0 release, we should drop this from the release and get it into |
Deferring to 3.0.0 won't make it any better as we have no meaningful way to reach users, except through the changelog. I'd say put it in the list of breaking changes and be done with it. URL-based auth can't be that widespread anymore. |
I agree with @silverwind. We're going to have to bite the bullet sooner or later if we want to ship this feature. I'm not sure if a feature flag would help or if it should default to on or off. |
Any stats or data on that? |
@silverwind we can detect the I honestly think that making users just change |
We can detect a delete with We should just set it to null when observing deletes. We should not require user intervention or break npm. |
|
I feel like there is a lot of crosstalk here. Using |
npm/npm#8163 does not pass npm's full test suite, even on Unfortunately, this is not a trivial update for npm, and it's going to take some time to get this fixed and to make sure that whatever the full solution does doesn't break npm under older versions of Node. |
@domenic because we'd have at least a full release cycle using the rest of this new code and testing it in the wild before asking users to change behavior in order to improve the performance. |
Notably, Object.observe is asynchronous, so beyond the perf concerns, I don't think it'd actually fix the problem. I think at this point we should back out the change and introduce it behind a flag on the v2.x line, making it a candidate for v3 or v4. I agree with @domenic that we shouldn't block the v2.0.0 release for this to land with a feature flag. |
I think it would be better to back it out then. We'll want to re-evaluate if this is worth landing being that there is no way to fix this behavior without using proxies and we still don't know when those will land and what perf impact they'll have when they do. The assumption we were under when we agreed to take the change was that the only breaking change in |
The performance is not based on accesssors (except eager .format() call for .href), everything was made an accessor for consistency, for enabling browser similarity (which seems to be a goal of url module although it's currently nothing like that) and for better sanity, e.g. props can be validated and are reflected in other propd. Also url is not a dictionary or an associative array but an object instance of Url... |
I probably did a bad job of explaining the other breaking change I was worried about, but here it is, for posterity: parsed = url.parse('http://google.com/path/name?q=3')
parsed.hostname = 'ok.com'
parsed.host = null
console.log(url.format(parsed)) Before this |
@mikeal I think you mean before we decided to make everything an accessor (like in browsers). In browsers host is just a hostname and port, it doesnt make sense to set hostname and host at the same time. You either set port and hostname separately or you set them together from one string using the host setter. |
I have seen the objects returned from |
the fact that you can pass the object in to |
quick question: if someone wanted this perf gain in their app today couldn't they just import it from npm and set |
@rvagg exactly, my mind was trained to think of it as such. |
@mikeal That would run into similar issues as |
@chrisdickinson ya, that's what I figured. that might be a better path to getting the ecosystem to update than taking more code in to core that is behind a flag we may never take out from behind the flag. |
the npm module is completely different than this all accessors version |
Good call on the revert. What remains to be researched is why my proposed npm patch fails npm's tests, but otherwise this is resolved. Thanks everyone. |
This will probably find its way back to the TC at some point, but as I explain in npm/npm#8163, @isaacs and I don't think the right thing to do is to change npm to match the new |
Interesting...I suppose on the one hand, for any API, as an API user, I shouldn't expect delete to "work" because a property could be on a prototype. On the other hand, I wouldn't expect the shape of the object to change from Node version to version. Urlgeddon! ;-) BTW nice work @petkaantonov. Do you know if there are techempower benchmarks showing the improvements? |
Looks like deleting properties no longer has an effect because the properties are getters/setters. Encountered in https://github.com/npm/npm/blob/master/lib/config/nerf-dart.js
The question is, do we want to/can support this with getters/setters at all, or are we fine with it breaking? If we want to break it, we propable need to patch npm to use
uri.prop = null
oruri.prop = ''
instead ofdelete uri.prop
.1.8.1
2.0.0
cc: @petkaantonov @domenic @rvagg @othiym23
The text was updated successfully, but these errors were encountered: