-
-
Notifications
You must be signed in to change notification settings - Fork 26.8k
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
Polyfill #170
Comments
Are any other major tools using/recommending this? |
Not that I'm aware of. Their usage stats seem fairly impressive (https://polyfill.io/v2/docs/usage). I'm not averse to us offering a different (e.g. static) js polyfill, I just think we should default to including a global polyfill of some sort. The least controversial thing might be to just provide a static polyfill (not sure which ones are popular these days). I think we should provide something though as soon as possible. |
I would normally include |
We could ship full core-js in development build, then build a custom core-js based on analysing code for which features are actually used in production. Doing that analysis in development would probably be way too slow since it would require analysing all of the dependencies. We could also look at building a couple of different bundles, one for browsers with full ES5 support and another for browsers that need ES5 polyfills, then feature detect on the client. |
Feedback about polyfill.io seems generally positive. |
Do we have a good solution to this? polyfillpolyfill/polyfill-service#561 |
@gaearon we're fixing that soon |
I will ship a fix for polyfillpolyfill/polyfill-service#561 |
What is the planned fix? Is it future proof? |
I wonder if a better fallback would be to hedge slightly and deliver at least the most commonly needed polyfills, rather than delivering no polyfills. |
I don’t understand the problem space that well, would the proposed fix also work for Twitter / Slack / LinkedIn / ...? |
The proposed fix is to adapt the existing UA aliasing so it's not just mapping between browser families but so it can alter the entire parsed UA. We could then do something like: 'facebook': function(ua) {
return {family: 'ios_saf', major: ua.os.major};
} This would easily extend to other in-app browsers. (Twitter at least looks like it's correctly detected as MobileSafari) |
We lean on ua-parser, because life's too short to write your own UA classification lib! However, sometimes its classifications are not useful for us, and we alias them. |
I think the lack of unhandled rejection reporting is unfortunately a blocker for us. This is a super common problem with React. People call Would you be interested in adopting a Promise polyfill that reports unhandled rejections by default? I believe |
How about including a default I like @mjackson's solution for this in his web-starter project, providing static minified versions and loading them only when needed: <script>window.Promise || document.write('\x3Cscript src="/es6-promise.min.js">\x3C/script>\x3Cscript>ES6Promise.polyfill()\x3C/script>')</script>
<script>window.fetch || document.write('\x3Cscript src="/fetch.min.js">\x3C/script>')</script> I think you can do something similar with Webpack's import and export loaders, but don't quote me on that. |
We had to remove polyfill.io due to it failing to identify ie11 correctly. |
OK, thanks for feedback. What @insin suggested in #170 (comment) looks super reasonable to me. Mostly because So I think we should go with that approach instead. |
@gertjvr could you raise that at Financial-Times/polyfill-service please? Seems like a fairly major issue. |
@quarterto will do its not polyfill.io issue actually its to do with useragent npm package but didn't dig to deep. |
The reason I’m inclined to not use polyfill.io right now is that most React users don’t care about ES6 features like |
The best way to do this IMO is to do a client-side feature test and a This is actually one of the primary reasons I need to server-render my template in web-starter. So I can do those polyfills. If server-rendering is off the table (note that I'm not talking about server-rendering your whole app-just the "chrome" and a bunch of Please note, however, that in order to use the |
Hmm, can you help me understand why server rendering is important here? Couldn’t we just put these conditional |
We can just put them in our index.html template. The downside is that it gets exposed to the user and becomes impossible for us to update because the template lives in the user's repository. A better solution I think might be to add something like I don't think "server rendering" is actually relevant here, so much as we just need some way to add the appropriate inline scripts to the page. |
Ah, all I meant by "server rendering" was that you need to be able to affect the HTML. It sounds like index.html will work beautifully. |
A gzipped, minified build with just Without gzipping, it's 138 kB v. 222 kB. Certainly there's room to optimize, but I don't think "adding 28 kB to the gzipped size" is sufficient for the easiest solution to be dismissed outright as "way too large". |
We’d also need |
Also, React gets a lot of bad rep for being “large”. We can say that 40kB gzipped is less than many images but that’s what people look at in comparisons, and I can guarantee that if we make it 70kB by default, somebody will use this in charts claiming React apps are huge (especially considering the “default” status of this tool). So we should be careful bundling extra stuff. But perhaps bundling |
71 kB gzipped, 228 kB without gzip if I add I think didactically, in this context, it's just better. One-line polyfill import (and one that ships with Babel, at that) v. something non-trivial to ship exactly the correct polyfills. The other thing the React ecosystem gets a bad rep for is tooling complexity, and doing bespoke, advanced stuff to pull in specific polyfills I think hurts more on the complexity front than it helps on the bundle size front. |
OK. Here’s my proposal. Let’s ship these polyfills:
We would bundle them for everybody via |
I don't actually know how to import core-js polyfills individually. 2 minutes of guessing gives me: import 'react';
import 'react-dom';
import 'core-js/es6/promise';
import 'core-js/es6/symbol';
import 'isomorphic-fetch'; This gives me 49 kB gzipped, 161 kB just minified. (These numbers are a bit weird since I'm using webpack 2... maybe... probably not too bad.) I don't know. I really like The other option is to use It will also reduce bundle size a bit by using external helpers from The main downside that I'm aware of is that the transform is paranoid to the point of also trying to polyfill e.g. |
They’re nice but from my experience with answering React issues beginners don’t really use them / know about them, and those who do know, know how to include a polyfill. On the other hand, |
I agree that adding 8 kB of polyfills to get a mostly working ES6 environment is a strict win. I think the You'd get the extra functionality if you needed it, and you'd only pay in bundle size for features that you actually use. The extra complexity is just a single additional Babel plugin. (Also, selfishly, if there were a |
Would you like to take a stab at implementing my proposal from #170 (comment)?
Agree, in the future. |
The issue with babel-runtime is that it doesn't polyfill things that are used by dependencies in node_modules. Increasingly (with the popularity of node v4/v5/v6 starting to overtake 0.10) people will start shipping modules to npm that depend on things like I'm keen for us to implement @gaearon's solution in the short term. In the longer term, we can make something clever enough to load only the required dependencies, but do so globally for all modules. |
@ForbesLindesay The current proposal isn't polyfilling @gaearon I'm not sure I'll have time to look at it right now. I don't even know for sure that I imported those polyfills correctly. I'd prefer someone who actually has worked with core-js directly do this. |
True. I'm trying to come up with a solution that does let us start using those features. In the short term, library author's may have to bundle polyfills for them, but we have an opportunity to change that by providing an efficient polyfill that's only provided if the code needs it. We can easily statically analyse code to detect whether or not it uses |
IIRC, using
Of course the benefit of the polyfill service is that you get the feature detection done server-side, so you don't need to run JavaScript to figure out whether you need to load other JavaScript. Our promise polyfill seems to serve most users' needs but it is not perfect, and we'd welcome a submission of a better one. |
We can get round document.write anyway because we control the entire stack. We could add code directly to the bundle to do the feature switching and Re promise polyfills, I would suggest the promise npm module. Once then/promise#129 is merged you'll be able to simply |
For now #235 covers |
This is shipped in 0.2.0 alpha, please feel free to provide feedback. Here's how: #190 |
Upgrade to typescript 2.5.3
mark |
Polyfilling via babel doesn't work very well in my experience since you don't normally run babel against node_modules. For apps (rather than libraries) I think it's generally best to just have global polyfills.
With this in mind, we could consider just adding a script to link to https://polyfill.io/v2/docs/ as the default polyfill. It provides a polyfill based on the user agent string so is a decent future proof default.
For non-polyfill babel-runtime components, we should do as @insin suggest in #51 (comment)
The text was updated successfully, but these errors were encountered: