Qual é a diferença entre um calço e um polyfill?

406

Ambos parecem ser usados ​​nos círculos de desenvolvimento da web, veja, por exemplo , Polyfills entre navegadores HTML5 , que diz:

Então, aqui estamos coletando todos os calços, fallbacks e polyfills ...

Ou, há o projeto es5-shim .

No meu projeto atual, estamos usando vários deles e quero colocá-los todos no mesmo diretório. Então, como devo chamar esse diretório --- shimsou polyfills?

Domenic
fonte
6
reabra: Suponho que "o que devo chamar de diretório" possa ser baseado em opiniões, mas realmente não é fornecido o contexto maior da questão - nem é o aspecto mais importante dessa questão. Todas as respostas aqui parecem concordar e há um uso significativo de fatos, referências e conhecimentos específicos.
Nobar

Respostas:

386
  • Um shim é qualquer pedaço de código que executa a interceptação de uma chamada de API e fornece uma camada de abstração. Não é necessariamente restrito a um aplicativo Web ou HTML5 / CSS3.

  • Um polyfill é um tipo de calço que atualiza os navegadores herdados com os modernos recursos HTML5 / CSS3, geralmente usando Javascript ou Flash.

Respondendo à sua pergunta específica, ligue para o diretório shimsse desejar manter o diretório genérico.

Arsalan Ahmed
fonte
234

Calço

Se você estiver familiarizado com o padrão do adaptador, saberá o que é um calço. Shims intercepta chamadas de API e cria uma camada abstrata entre o chamador e o destino. Normalmente, os calços são usados ​​para compatibilidade com versões anteriores. Por exemplo, o pacote es5-shim npm permitirá que você escreva a sintaxe do ECMAScript 5 (ES5) e não se importa se o navegador está executando o ES5 ou não. Tome Date.now como um exemplo. Esta é uma nova função no ES5, onde a sintaxe no ES3 seria nova Date (). GetTime () . Se você usar o es5-shim, poderá escrever Date.now e, se o navegador em que estiver executando suportar o ES5, ele será executado. No entanto, se o navegador estiver executando o mecanismo ES3, o es5-shim interceptará a chamada para Date.nowe apenas retorne new Date (). getTime () . Essa interceptação é chamada shimming. O código-fonte relevante de es5-shim é semelhante a este:

if (!Date.now) {
    Date.now = function now() {
        return new Date().getTime();
    };
}

Polyfill

Polyfilling é realmente apenas uma versão especializada de shimming. O Polyfill é sobre a implementação de recursos ausentes em uma API, enquanto que um calço não seria necessariamente tanto sobre a implementação de recursos ausentes quanto sobre a correção de recursos. Eu sei que isso parece muito vago, mas onde os calços são usados ​​como um termo mais amplo, o polyfill é usado para descrever os calços que fornecem compactação retroativa para navegadores mais antigos. Portanto, enquanto os calços são usados ​​para encobrir pecados antigos, os polyfills são usados ​​para trazer aprimoramentos futuros de volta no tempo. Como exemplo, não há suporte para sessionStorage no IE7, mas o polyfill no pacote sessionstorage npm adicionará esse recurso no IE7 (e mais antigo) usando técnicas como armazenamento de dados na propriedade name da janela ou cookies.

Kjetil Klaussen
fonte
107
Portanto, enquanto os calços são usados ​​para encobrir pecados antigos, os polyfills são usados ​​para trazer aprimoramentos futuros de volta no tempo. Isso resume tudo para mim. Obrigado por uma explicação clara.
JohnnyQ
Esta resposta é útil, obrigado. Mas parece-me que os dois termos geralmente não são usados ​​precisamente na web, incluindo o es5-shim. Eu acho que es5-shim é uma mistura de calços e polyfills pela sua definição.
Matt Browne
WOW -> Portanto, enquanto os calços são usados ​​para encobrir pecados antigos, os polyfills são usados ​​para trazer melhorias futuras de volta no tempo. <- Muito obrigado!
Zeppelin
3
O exemplo de data parece um Polyfill para mim. Por que eu acho que é um Polyfill? Porque Date.now é uma chamada nativa. Um Polyfill adicionará esse recurso com a mesma API perfeita ao navegador. Um calço vem com uma nova API como: MyShim.Date.now(); Corrija-me se estiver errado.
TatzyXY
99

Pelo que entendi:

Um polyfill é um código que detecta se uma determinada API "esperada" está ausente e a implementa manualmente. Por exemplo

if (!Function.prototype.bind) { Function.prototype.bind = ...; }

Um shim é um código que intercepta chamadas de API existentes e implementa um comportamento diferente. A idéia aqui é normalizar determinadas APIs em diferentes ambientes. Portanto, se dois navegadores implementarem a mesma API de maneira diferente, você poderá interceptar as chamadas da API em um desses navegadores e alinhar seu comportamento com o outro navegador. Ou, se um navegador tiver um bug em uma de suas APIs, você poderá interceptar novamente as chamadas para essa API e contornar o bug.

Šime Vidas
fonte
66

Citando Axel Rauschmayer em seu livro Speaking JavaScript :

  • Um shim é uma biblioteca que traz uma nova API para um ambiente mais antigo, usando apenas os meios desse ambiente.
  • Um polyfill é um calço para uma API do navegador. Ele normalmente verifica se um navegador suporta uma API. Caso contrário, o polyfill instala sua própria implementação. Isso permite que você use a API nos dois casos. O termo polyfill vem de um produto de melhoramento da casa; de acordo com Remy Sharp :

    Polyfilla é um produto do Reino Unido conhecido como Spackling Paste nos EUA. Com isso em mente: pense nos navegadores como uma parede com rachaduras. Esses [polyfills] ajudam a suavizar as rachaduras e nos dão uma boa parede lisa de navegadores para trabalhar.

Bergi
fonte
9

Calço. Um shim é uma biblioteca que traz uma nova API para um ambiente mais antigo, usando apenas os meios desse ambiente.

Polyfill. Em outubro de 2010, Remy Sharp publicou um blog sobre o termo "polyfill" [via Rick Waldron]:

Um polyfill é um pedaço de código (ou plug-in) que fornece a tecnologia que você, desenvolvedor, espera que o navegador forneça de forma nativa. Achatar o cenário da API, se desejar.

Sagitário
fonte
8

Um artigo fantástico escrito sobre isso, há alguns anos atrás, que explica isso bem:

O que é um Polyfill?

No artigo, os (2) são simplesmente contrastados como tais:

Shim: um pedaço de código que você pode adicionar (ou seja JavaScript) que consertaria algumas funcionalidades, mas geralmente teria sua própria API .

Polyfill: algo que você pode inserir (ou seja JavaScript) e, silenciosamente, funcionaria para imitar as APIs de navegador existentes que, de outra forma, não são suportadas.

atconway
fonte
11
Acho que essa é uma representação enganosa do uso comum e do que Remy Sharp realmente diz no post do blog ao qual você se vinculou. Shim é mais frequentemente usado como sinônimo de polyfill hoje em dia (ver particularmente o ES5-calço e ES6-calço ) e Remy é particular sobre dizendo que para ele a palavra 'calço' aludiu a uma API personalizada (por comparação com shim.gif). Ele não está ditando que as palavras sejam usadas dessa maneira e, ao dizer "para mim" , reconhece tacitamente que seu uso não é universal.
Mark Amery