Closed silverwind closed 9 years ago
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...
@mikeal:
The assumption we were under when we agreed to take the change was that the only breaking change in clone() behavior
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 changefeature, this would log 'http://ok.com/path/name?q=3'
, after this changefeature it will log 'http:///path/name?q=3'
. That is, the order users change the properties in matters and can induce breaking behavior.
@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 url.parse()
be used as if they were regular old object literals quite extensively. As @chrisdickinson points out, this changes the assumptions that might exist for some developers (including myself). I'm +1 on reverting this back until 3.0.0
so there is no scrambling to get things fixed before dropping the official 2.0.0
the fact that you can pass the object in to http.request()
even encourages you to think of it as a plain object
quick question: if someone wanted this perf gain in their app today couldn't they just import it from npm and set url.parse
to this version in the npm module? they could even use the --require
flag to make sure it happens before any other modules get loaded and parse some urls.
@rvagg exactly, my mind was trained to think of it as such.
@mikeal That would run into similar issues as --use-strict
, but would be viable for folks to try it out ahead of time. It'd be roughly equivalent to a feature flag, I think.
@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 url
interface. I'm happy to discuss our reasoning, but ultimately @isaacs made the call, and I agreed, that this set of changes is sufficiently problematic to require a lot more discussion and careful planning to land.
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