0.3.0 • Published 8 years ago

@brad-jones/dynamic-polyfill-sync v0.3.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 years ago

dynamic-polyfill-sync

CircleCI TypeScript Conventional Commits semantic-release
Build Status

TLDR: A synchronous version of dynamic-polyfill.

This package provides an IE8+ solution that will run feature detection across required polyfills, in the event the browser does actully require a polyfill only then will this use a "synchronous" XMLHttpRequest to the https://polyfill.io service.

Usage

Download and install with Npm/Yarn:

npm install @brad-jones/dynamic-polyfill-sync --save

OR

yarn add @brad-jones/dynamic-polyfill-sync

Then in your library entry point (usually index.js):

import polyfill from '@brad-jones/dynamic-polyfill-sync';
polyfill(['Promise', 'Symbol', 'Object.assign', 'etc...']);

export * from './FooModule';
export * from './BarModule';

Providing a custom polyfill.io url

polyfill(['fills...'], 'https://cdn.custom-polyfill-service.com/v2');

Why?

As a library developer, I want to develop using modern JavaScript standards but I also want my library to be as compatible as it can be, so like we all do these days I use a transpiler, usually TypeScript.

However thats only half the story my library also needs to have polyfills installed when running in older javascript engines. In the past I would have included these polyfills with my build.

The problem with this is that firstly a modern browser that doesn't require the polyfills pays the performance hit of having to load them. And secondly if I have multiple library packages that I want to use they will all duplicate some of the polyfills.

Read more:

Yeah and so...

Well I then came across this project: dynamic-polyfill. And I thought it had solved all my problems. And yes if I was building an "APP" it would solve all my polyfilling needs. But I am building a "Library".

I played around with wrapping my code in a dynamic-polyfill callback, which worked for sure but it created issues around bundling and just didn't feel nice to use in a project that was consuming the library.

Now I could tell my library users that they are responsibile for providing the polyfills but then my package doesn't have a "just works" option, which I believe is vitally important for intially learning and evaluating a new library.

Synchronous... really this doen't sound great

Yeah ok I get it Synchronous XHR requests are not best practise due to blocking the main UI thread of the browser or even the entire browser in some cases.

I believe asking the browser to load it's polyfills synchronously is one of those acceptable edge cases. The javascript isn't going to work without the polyfills anyway.

Due to the fact that we perform feature detection, a modern broswer will never perform the blocking synchronous request.

And so now my library code will "just work".

Multiple libraries

If you loaded multiple scripts that used this package to load their polyfills, the first library might load most of the polyfills and the second might only need to load a few extra ones, again because we are doing feature detection. So yes multiple requests might end up being made to https://polyfill.io but not for the same content.

Know Issues

Actually after heaps of testing (via SauceLabs / BrowserStack), it appears that IE8 & 9 will load a CORS resource so long as it is over HTTPS, using the normal old XMLHttpRequest.

I actually had it all working in IE8 with XDomainRequest but it would not work in IE9. I then dropped the use of XDomainRequest altogether and it worked in both IE8 & 9.

Honestly I still don't get it as it appears to contradict all the documnetation. Until someone comes along and says it doesn't work I am not going to look at it any further.

IE8 & 9 do not offer a standards compliant CORS implementation of XMLHttpRequest. Instead we use XDomainRequest which works but there are a few restrictions.

  1. Requests must be targeted to the same scheme as the hosting page. This restriction means that if your AJAX page is at http://example.com, then your target URL must also begin with HTTP. Similarly, if your AJAX page is at https://example.com, then your target URL must also begin with HTTPS.

Read more: https://goo.gl/GPY87s