Closed cibernox closed 6 years ago
The fetch API could be conditionally polyfilled using the new targets feature in ember-cli 2.13. Once minified and gzipped it's just ~2KB
thats smaller then jQuery ;)
I think it's been proposed at various times to use either ember-ajax (https://github.com/emberjs/data/issues/4175) or ember-network as the network library for Ember Data (though ember-network may be replaced by ember-fetch, plus it's scope is quite limited, so ember-ajax may be the better candidate here).
The benefit being that authentication, custom headers, etc. can be setup once and used both for XHRs originating from Ember Data, for XHRs in other addons and for application-specific XHRs.
As a way of replacing $.ajax
I'd suggest making either of the two addons above run without jQuery, and then use them as a network addon for Ember Data. Thoughts?
Also related: https://github.com/emberjs/data/pull/4406 https://github.com/emberjs/data/issues/4404
I'm not against the idea of removing jQuery, on the contrary I'm very supportive. Just wanted to mention some thoughts on how $.ajax
can be removed.
The benefit being that authentication, custom headers, etc. can be setup once and used both for XHRs originating from Ember Data, from other addons and for other XHRs.
As a way of replacing $.ajax I'd suggest making either of the two addons above run without jQuey would be a good way forward, and then use them as a network addon for Ember Data. Thoughts?
As one of the maintainers of ember-ajax, I'd like to say that we're amenable, and interested in, such work. It's a goal of ours to be the library upon which Ember Data builds for its network requests.
/cc @alexlafroscia
@sandstrom I believe that there is some interest in merge ember-network
and ember-fetch
, since they have the same goals. I believe they should be the same addon (and ember-fetch
has the best name IMO)
If we could make ember-ajax
work with fetch instead of jQuery then seems like it could be posible to merge all three and have a beautifully unified networking story, and ember-data could build on top of that.
I'm all into the idea.
Literally ember-network is copy pasta of ember-Fetch and ember-Fetch predates ember-network and is maintained. So the discussion is between ember-Ajax and ember-Fetch.
I do believe we want to get to real fetch someday. Is there a way we can either unify or make ember-Ajax and ember-fetch be pluggable?
@stefanpenner Can you check with Tom if we can start by deprecating either ember-fetch
or ember-network
in favour of the other? That would be a useful first step.
I can once he returns from vacation
It's a goal of ours to be the library upon which Ember Data builds for its network requests.
This has always been the a plan, but there was never a huge reason to finally make it happen. Maybe this is it.
I always saw the benefit of ember-ajax
being that it could provide just the $.ajax
implementation once Ember no longer shipped with jQuery by default, so I'm willing to do the work so that the addon pulls that in if needed.
If we could make ember-ajax work with fetch instead of jQuery then seems like it could be posible to merge all three and have a beautifully unified networking story, and ember-data could build on top of that.
I've kicked this idea around a lot and I, personally, don't think it's a good idea. While there is certainly a benefit to having a unified networking story, there are a few problems IMO:
$.ajax
, and thus ember-ajax
, creates a cancel-able request. fetch
does not.fetch
semantics for rejection around 4** responses is different than what $.ajax
does (jQuery has always considered that a failure and reject, but fetch
would resolve the Promise)I've always hoped that the Ember community would land on ember-ajax
+ ember-(network|fetch)
(I have no idea which is the "winning" solution at this point) as the go-to tools, based on whether the developer wants to use the "new" fetch
API or the $.ajax
API that they're used to. However, that does leave a standing question of what Ember Data could/should build on top of.
Just a heads up, github's fetch
polyfill does not support IE9.
@btecu IE9 does work if you have a promise polyfill, and we already ship RSVP with ember. We can make it work.
@alexlafroscia These differences are good points! What do you think about these two possible solutions:
Cancel
There is work in progress to add cancelation to fetch
(details).
A fairly simple solution is to build cancelation into whichever xhr-service we end up using for Ember Data (but that cancelation wouldn't really cancel the request, just ignore the result when it comes back; i.e. it's a cancel from the perspective of the API consumer, but not on the wire).
4xx responses
The xhr-service could still reject on 4xx
(I think it makes sense to reject on 4xx
and 5xx
), even though the underlying fetch library resolved.
@alexlafroscia I think it would be possible for an addon to be based on fetch and still provide an $.ajax
-compatible API. The main differences from the top of my head:
fetch
returns a response and the user has to call .json()
(or others) on it to get the actual data.fetch
only rejects under very exceptional circumstances, like real network errors. 4XX and 5XX are not rejections.fetch
allows for streaming responses (not sure if the polyfill does, but I reckon that it doesn't)fetch
doesn't allow real cancellation yet (spec in progress), XHR/ajax does.fetch
doesn't allow progress events on uploads, I not sure if $.ajax
does. I know that raw XHR allows that.data
-> body
)Other than cancellation, that I don't know if it's possible with ember-ajax
, seems that we can replicate all that on top of fetch in a small enough amount of code to make fetch: service()
and ajax: service()
be possible with a single addon.
Tech is not foreign to trends and marketing, so I think we should make fetch be the default in the ecosystem. I think that technical reasons aside, people feel like they want use fetch
because it's modern, even if it's just a matter or perception and it will make little to none difference for them. Still, perception matters.
The intent of ember-network
was to aggregate isomorphic network implementations into one spot, including jQuery, XMLHttpRequest and others. In practice najax has been "good enough" and now the momentum is behind fetch, so I have no objection to moving the community off ember-network. That said, given that there is broad ecosystem support for isomorphic packages (via the browser
package.json field), I recommend we adopt that instead of doing something Ember-specific.
@tomdale could you elaborate what you mean by that? I'm not familiar with the browser
field on package.json so I don't see the role it would play.
I believe that @tomdale is actually referring to modules
entry point which is what we allow and use in glimmer applications (browser
is a somewhat bizarre spec and we do not currently plan to support browser
out of the box).
Some "light" reading:
@rwjblue If i'm reading this right, Tom is suggesting to create a node library that exposes one polyfill for the browser and another for node, so we can just import fetch from 'package-name';
, and depending on if the app is in node or browser, it will get the right polyfill.
However this is just part of what I'd expect the addon to provide. I'd expect the addon to provide
fetch
service to encapsulate common logic to all fetch requests, typically authentication, like ember-ajax
does.We might create a standard non-ember specific package, but for the last three points we might need to create an ember-addon that relies on that package.
@rwjblue No, that's not exactly what I'm suggesting. The modules
field signifies that the target file is authored with ES6 modules, it doesn't indicate which environment it is designed to be run in. The browser
field is used for cases like we're hitting here, where you have one implementation that uses Node APIs and another implementation that uses browser APIs.
The whole thing is incoherent because it has evolved organically. It may be on us to try to propose amendments to module
/browser
etc that better capture the permutations. But as much as possible, I'd like to align our roadmap with the broader JS ecosystem; using fetch
universally between the browser and Node is something many people have, so we should try to join forces to tackle the problem.
wondering if this got picked up in any ember data sub team meetings.
@webark Not as far as I know, but I finally got around to deprecating ember-network
this weekend and ember-fetch
is FastBoot compatible. It seems like the important thing to do is to migrate Ember Data to use fetch
semantics via ember-fetch
. Once that's working, how we get fetch
into Ember Data is just an implementation detail.
There is a lot of interest in getting npm packages consumable in a first-class way. Once that's in, we can probably start to think about even being able to move off ember-fetch
and have ED rely on a non-Ember-specific fetch
implementation (which ember-fetch
is a wrapper around anyway).
Any updates on this? I've been working on removing jQuery from my apps and addons and I think the only major thing holding me back, at this point, is ember-data.
@rwwagner90 I managed to make ED work without jquery, using https://github.com/ember-cli/ember-fetch#use-with-ember-data
@rwwagner90 i've done the same..
Closing in favor of the quest in #5320. We're on our way :)
This might deserve an RFC, but for now I want to start the discussion as a mere issue.
I've been trying to make jQuery be optional in Ember apps and so far is going ok.
ember-native-dom-event-dispatcher
makes Ember itself be jQuery-less.ember-native-dom-helpers
provides arternative test helpers that allow to test apps without the jQuery-based helpers provided by Ember. For the most of it, you can replaceember-ajax
withember-fetch
with a relatively low effort.The main blocker for apps is that many addons rely on jQuery and that might block the effort. If just the top 20 of the most popular addons working without jQuery, the rest of the ecosystem would follow.
Of the top 20, ember-data is by far the biggest and more used, and one of the few where removing jQuery is actually a hard task, but that is what I'm proposing here.
Replace
$.ajax
withfetch
The good news is that I tried and it's not that hard.
By no means this snippet is the full solution, it only works for
GET
requests and doesn't honor headers and such, but after some digging I have good and bad news, but mostly good:jQuery.ajax
usage is fully contained in the private_ajaxRequest
method.jqXHR
object into other methods ...jqXHR
are all private and usingfetch
'sResponse
object would actually simplify the code a bit.The
fetch
API could be conditionally polyfilled using the new targets feature in ember-cli 2.13. Once minified and gzipped it's just ~2KB, so even if included it's footprint is rather small.Benefits
slim
build of jQuery, which saves ~20% of the size but doesn't include some features likeajax
and animations.fetch
theJSON.parse
happens out of the main thread, which will help with big payloads. That without accounting with the overhead$.ajax
adds.Downsides
$.ajax
. We'd have some code to mangle those option into something we can pass to fetch.$.ajaxSettings/ajaxSetup/ajaxPrefilter
to setup auth headers and stuff like that instead of using ember-data methods for it. This is not ember-data's fault but we should try to find a way to deprecate this if possible./cc @stefanpenner @runspired @rwjblue @bmac