Re: Prollyfills and the global namespace / multi-fills

On Thursday, July 4, 2013 at 2:58 AM, Marcos Caceres wrote:
>  
> On Wednesday, July 3, 2013 at 10:21 PM, Tobie Langel wrote:
> > On Wednesday, July 3, 2013 at 9:46 PM, François REMY wrote:
> > > > Ok, I can see where there could be potential clashes for
> > > > unmaintained code. But I think this would be rare.
> > >  
> > > It's not rare at all. Most websites are unmaintained, and they hold the web  
> > > platform back. Ask any implementor for stories where unmaintained websites  
> > > slowed down the unprefixing or the introduction of new APIs because of  
> > > conflicts, you'll see for yourself.
> >  
> > We had serious issues back in the days with PrototypeJS for document.getElementsByClassName, Function.prototype.bind, Array.prototype.reduce, Array.prototype.indexOf, Array.prototype.toJSON, String.prototype.toJSON, document.querySelectorAll, etc.
> >  
> > This is absolutely going to happen.
> Was the problem that you were not able to tell if all those method's .toString() function returned "function valueOf() { [native code] }"? Or that those had been hijacked even though the browser did support the real deal?

For the context, a lot of the above-mentioned methods originated in (or were popularized by) PrototypeJS and were then standardized and implemented natively. So this seems very close to the desirable outcome of prollyfills (seriously prollyfills!? <-- not getting tired of that one any time soon).

In some cases, we had guards setup (e.g. if (!document.getElementsByClassName) …) in others we did not. Either cases came with their load of grief. A couple of examples:

1) document.getElementsByClassName:

I don't remember the details of who came up with this one exactly, but Prototype included a version of it early on. The prollyfilled version (heh!) returned an instance of the Array object. The native one a LiveList.

Because there was a guard setup to default to the native object, and because devs were relying on the set of array enum provided by Prototype, a lot of the code in applications went something like this:

    document.getElementsByClassName('foo').each(function(element) { … });

Of course, that started breaking as browsers started shipping a native implementation.

2) Array.prototype.indexOf:

Our implementation relied on the == operator. TC-39's (which came years later) on ===.

Again grief and hard to debug issues whichever way we'd handle the situation. Behind a guard: code that had been working start to fail as browsers implement the TC-39 version. Without a guard, code that works when Prototype isn't around suddenly starts to fail when you add the library or vise versa.

3) Array.prototype.toJSON and String.prototype.toJSON:

See previous posts on the topic[1].

4) document.querySelectorAll:

The main issue here was that the native method had a bunch of bugs on different browsers which required a lot of special casing. Would have been prevented had implementors run our test suites before shipping their implementations.

To summarize, specs are going to seriously change between what is prollyfilled ([insert snarky comment here]) and what gets shipped, and that's going to cause plenty of grief down the road. To mitigate this solid test suites using testharness.js would help along with a system to easily identify native code from prolyfills.

Best,

--tobie
---
[1]: https://gist.github.com/kitcambridge/2605201 or https://groups.google.com/forum/#!msg/prototype-core/E-SAVvV_V9Q/oeKLrn2MUHYJ

 

Received on Thursday, 4 July 2013 09:32:03 UTC