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 replace ember-ajax with ember-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.
$.ajax with fetchThe 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 using fetch's Response 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.
slim build of jQuery, which saves ~20% of the size but doesn't include some features like ajax and animations.fetch the JSON.parse happens out of the main thread, which will help with big payloads. That without accounting with the overhead $.ajax adds.$.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
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 :)
Most helpful comment
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