-
-
Notifications
You must be signed in to change notification settings - Fork 80
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
use browser fetch if exists #63
Conversation
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.
https://github.com/github/fetch/blob/master/fetch.js#L8
Need these check otherwise these features can't be supported by github/fetch.
This project explicitly forces the polyfil in all cases. This is because the polyfill is not complete, and switching between modes automatically is dangerous. I would be open to a config setting to allow this as an opt-in. |
@stefanpenner Just added the option which could be set in 'ember-cli-build.js' as
It defaults to true. |
#45 is also somewhat related. |
assets/browser-fetch.js.t
Outdated
'Symbol', | ||
'iterator', | ||
'ArrayBuffer' | ||
]; |
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 if we are to add all of these we should also add fastboot
polyfills in order to ensure parity.
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.
Why are we adding FormData
, FileReader
, Blob
to self? They are also not added to Fastboot fetch.
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.
ef14409
to
492f9a4
Compare
To ensure parity with Fastboot polyfills, supported properties(FormData, FileReader, Blob, etc) should only be used internally in github/fetch but not exported. |
We explicitly don't do this right now, only because we don't want folks accidentally relying on non polyfilled features in development, and becoming surprised in production. There is likely a strategy, were we detect these violations or minimize potential fallout. I would love for us to do so, so we can benefit from native fetch when possible. @xg-wang thoughts? |
@stefanpenner The Github polyfill for Make it more clear, the roadmap I would like for
We need to discuss the potential disparity between fastboot fetch and browser fetch, and where should changes be made. My assumption is that we can tolerate the disparity a little bit more since we didn't expect fastboot/browser behavior to be exactly same in else aspects. @rwjblue I'm not sure about #45. We don't need to avoid import when targets have |
@xg-wang this sounds mostly reasonable. I really do want us to use fetch by default. One key area that will need to still be dealt with is that IE11 (a supported platform) does not have fetch. So for users that fall back to the polyfil ( It's never fun to realize that some important aspect of your app is non-functional once you test in IE11. |
@stefanpenner as far as I can tell, the main missing feature from polyfil is streams. I have not investigated it yet, but is it really unreasonable to polyfil by using progress events on XHR? |
@stefanpenner - Github polyfill
I will figure out the supplement set and see if we can do a warning message for those. For native @tchak - Polyfillable or not, I think it's reasonable to let https://github.com/github/fetch decide. |
@tchak / @xg-wang thoughts on simply wrapping native fetch, in something that hides stream stuff by default? In a way that errors with a helpful message (and opt-opt instructions). Basically just catching the cases where the polyfill will fall short. ^^ would be for if we can't reasonably polyfil the remaining features. |
We have these choices:
My thought:
My opinion:
|
The problem with leaving streams out is that it is the only way with I feel that if we want for |
We also have, in development/test only use polyfil, and in prod use real.
For users who want to use streams, we can allow a "alwaysUseNativeFetch" style option, which opts out of the above safety. Thoughts? |
I would love to here how well this works (tell me the downsides), and the impact of it. |
492f9a4
to
42691b8
Compare
I updated this patch so we can have some real code stuff to talk about. |
42691b8
to
ae7be04
Compare
index.js
Outdated
@@ -75,15 +75,16 @@ module.exports = { | |||
} while (current.parent.parent && (current = current.parent)); | |||
} | |||
|
|||
this.buildConfig = target.options['ember-fetch'] || {forcePolyfill: true}; | |||
this.buildConfig = target.options['ember-fetch'] || { preferNative: false }; |
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.
Rename the option here as I personally feel it more comfortable for me.
This should also be force overwritten if in testing, will add this in next commit.
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.
This sounds good. To help forks deal with the upgrade, could we detect if they use forcePolyfill
property, and throw a useful error message?
Once released, this will also be a major bump.
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 will squash the commits once I have a more meaningful implementation, right now it's more of a brainstorm
While not technically related, one problem with using native fetch right now is that pretender and ember-cli-mirage won't work. It's not per-set a problem of this library, but will bite people if we go ahead and do this. Someone needs to make pretender work with fetch. |
@cibernox making pretender work with native fetch sounds good. I believe @xg-wang's proposal is to run the polyfill fetch during dev/tests, but native in production. This would allow pretender (used in dev) to "just work". We should obviously follow up with a fetch solution for Pretender (pretenderjs/pretender#60). This shouldn't take much time, and I believe @xg-wang will be working on fetch + pretender compat next. @cibernox thoughts? (answered this comment with @xg-wang sitting next to me) |
07fee4e
to
16f68ce
Compare
For this change, open the dummy app and see console to confirm it's working:
Warn users like this:
|
tests/dummy/config/environment.js
Outdated
@@ -45,6 +45,9 @@ module.exports = function(environment) { | |||
|
|||
if (environment === 'production') { | |||
// here you can enable a production-specific feature | |||
ENV['ember-fetch'] = { | |||
preferNative: true |
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.
config/environment.js is for runtime configuration. But this is being used for build time configuration.
In general build time configuration should come from the ember-cli-build.js
file. For example:
new EmberApp(trees, {
'ember-fetch': { preferNative: true }
})
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.
The intention was to let the user control the behavior under different environment, once pretender lands the fetch support ember-fetch no longer needs to consider different environment config. I'm going to move it back to the build config.
@stefanpenner
index.js
Outdated
browserTree = map(browserTree, (content) => `if (typeof FastBoot === 'undefined') { ${content} }`); | ||
var preferNative = this.fetchConfig.preferNative; | ||
browserTree = map(browserTree, (content) => `if (typeof FastBoot === 'undefined') { | ||
var preferNative = ${preferNative}; |
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.
also, should we call this preferNative
or forceNative
, which is more appropriate?
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.
There will always be a fetch
available, forceNative
sounds like "if native is not available, do nothing".
So I was comparing preferNative
and forcePolyfill
and it turns out preferNative
is more intuitive.
@@ -16,20 +16,23 @@ | |||
"build": "ember build", | |||
"lint:js": "eslint ./*.js addon addon-test-support app config lib server test-support tests", | |||
"start": "ember server", | |||
"test": "ember try:each" | |||
"test": "npm run test:node && ember try:each", | |||
"test:node": "mocha" |
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.
test:node
might be confusing, since we are testing browser behavior in node env
package.json
Outdated
"ember-cli-babel": "^6.8.2", | ||
"node-fetch": "^2.0.0-alpha.9", | ||
"yetch": "^0.0.1" | ||
"whatwg-fetch": "https://github.com/github/fetch" |
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.
TODO, change this when new version released
}); | ||
const fetchReturn = this.JSONAPIAdapter._ajaxRequest({}); | ||
// if in pretender with native fetch testing, pretender will polyfill native fetch | ||
assert.ok(fetchReturn instanceof Promise || fetchReturn instanceof window.Promise); |
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.
Highlight
This is the only change in this file other than formatting and including tests in module. We have RSVP.Promise but pretender will have the Promise provided specified in ember-cli-pretender
Review needed @tchak @stefanpenner @rwjblue, should we mention stream and other fetch polyfill caveats? |
If set to false, native `fetch` access will be enabled.
test on dummy app and 'yarn link'ed app
fetch should be called in the context of window
Use `Object.defineProperty` instead of property caching so future modification to window.<xxx> will also take effect. e.g. pretender swaps `window.fetch` will not work if ember-fetch cached the native fetch already. misc: fix misuse of Mergetrees, fix and reformat adapter test
6592741
to
57fb401
Compare
Rebased on master. Investigating why fail Scenario ember-default and 2.12. |
For fixing "Error: Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in a run" in CI.
- node test remove ember-fetch.map - README mention github/fetch rather than Netflix/yetch - const/let over var
This PR is ready, need some review. @rwjblue @stefanpenner @tchak |
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.
small tweaks, and then we are good.
index.js
Outdated
var expandedAbortcontrollerPath = expand(abortcontrollerPath, 'abortcontroller-polyfill-only.js'); | ||
|
||
var polyfillTree = concat(new MergeTrees([find(expandedFetchPath), find(expandedAbortcontrollerPath)]), { | ||
const fetchTree = path.dirname(require.resolve('@xg-wang/whatwg-fetch')); |
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.
lets leave a comment above this line, briefly explaining why it is a fork and when we hope to get back onto the mainline.
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.
Maybe we can actually have an issue on the fork with this info, and have the comment here cross link that?
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.
Open 2 issues where the fork is being used, I will open another one under ember-fetch and cross link them.
test/prefer-native-test.js
Outdated
describe(`Build browser assets with preferNative = ${flag}`, function() { | ||
let output, subject, addon; | ||
|
||
beforeEach(async function() { |
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.
we can drop async
here, as it doesn't appear we have an await in the function
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.
good catch
yarn registry seems not stable these days CI passed on mine repo |
released as v5.1.0 🎉🎉🎉🎉🎉🎉 |
GitHub/fetch expects a
window
that contains a fetch, Headers, Response... as the passed inself
so it can skip the unnecessary polyfill. But in ember-fetch the passed inself
is actually the exported object, which is{}
at first.