Como criar elementos personalizados de componentes da web para trabalhar com ambas as especificações

9

Preciso criar um componente que precise trabalhar com ambas as especificações, custom elements spec v0que foram descontinuadas e a custom elements spec v1versão estável mais recente.

Se eu criar componentes com custom elements v0especificações, alguns aplicativos enfrentarão problemas, pois estão usando polymer 2e acima, e o mesmo problema com polymer 1aplicativos que não funcionarão com custom elements v1especificações.

Não tenho controle sobre aplicativos para alterar polyfills , alguns aplicativos precisam usar polyfills com suporte a especificações antigas e outros usam novos polyfills.

Estou procurando uma solução sólida para combinar as duas especificações para executar meus elementos personalizados em todos os aplicativos, independentemente da versão do polyfills. Posso adicionar qualquer pedaço de polyfill ou snippet aos meus componentes para que eles possam ser executados em qualquer lugar. Não encontrei nenhuma biblioteca ou polyfill que ofereça suporte a ambas as especificações em minha pesquisa.

Estou planejando escrever um adaptador que possa combinar ambas as especificações, como o mapeamento mencionado abaixo para retorno de chamada em anexo, as entradas nesse pensamento serão muito apreciadas.

connectedCallback(){
    this.attachedCallback();
}

Tentei usar stenciljs, mas ele pode funcionar apenas com a versão mais recente das especificações de elementos personalizados. Não encontrei nenhuma maneira de ajustá-lo para fazê-lo funcionar com as especificações anteriores.

Por favor, sugira algumas alternativas viáveis ​​e soluções viáveis ​​para a situação acima mencionada.

Konga Raju
fonte

Respostas:

1

Basicamente, seu componente possui algumas dependências definidas nos polyfills, direta ou indiretamente. Se considerarmos essas dependências como nós de um gráfico de dependência, teremos o problema de os gráficos serem diferentes. É possível que um nó exista nos dois gráficos, mas se comportando diferente (implementação mais antiga e mais recente do mesmo function) e também é possível que alguns nós presentes em um gráfico estejam ausentes em outro. É claro que você pode inserir alguns polyfills de sua preferência ou algo parecido, mas precisará manter os polyfills, o que pode ser menos que útil.

Uma abordagem melhor na minha opinião é implementar um function, como

function getWebComponentsVersion() {
    //Return v1 if it's v1 and v0 if it's v0
}

Não tenho certeza de como implementar isso function, mas se houver um functionque produz a versão correta ou algumas diferenças evidentes entre as funcionalidades, você poderá implementar a função acima de acordo. E, em seguida, execute este código:

if (getWebComponentsVersion() === "v1") {
    //code for v1
} else {
    //code for v0
}
Lajos Arpad
fonte
obrigado pela sua resposta, neste caso, preciso manter duas versões do código do componente, o que seria uma dor ao adicionar recursos e, a longo prazo, corrigir problemas se tornaria um processo agitado.
Konga Raju
@KongaRaju é realmente uma desvantagem, mas se você conseguir diminuir o espaço do problema específico da versão e ampliar a área de código que pode ser aplicada às duas versões, poderá encontrar esse problema menos perturbador do que você imagina à primeira vista.
Lajos Arpad
-1

Eu suspeito que você esteja ciente disso Custom Elements v0 is deprecated at M70, and will be removed in M80, by February, 2020..

O que você pode fazer é acessar o Can I usesite e verificar as versões de suporte do navegador para ver qual navegador deve carregar qual versão de elementos personalizados ...

Depois, implemente o abaixo para verificar o navegador e a versão e carregar o elemento personalizado correto para o navegador desejado de acordo ( mais aqui ), se você não quiser usar bibliotecas externas.

Se você concorda com o uso de bibliotecas externas, tente o Bowser para detectar versão, plataforma etc.

navigator.browserSpecs = (function(){
    var ua = navigator.userAgent, tem, 
        M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
    if(/trident/i.test(M[1])){
        tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
        return {name:'IE',version:(tem[1] || '')};
    }
    if(M[1]=== 'Chrome'){
        tem = ua.match(/\b(OPR|Edge)\/(\d+)/);
        if(tem != null) return {name:tem[1].replace('OPR', 'Opera'),version:tem[2]};
    }
    M = M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
    if((tem = ua.match(/version\/(\d+)/i))!= null)
        M.splice(1, 1, tem[1]);
    return {name:M[0], version:M[1]};
})();

console.log(navigator.browserSpecs); //Object { name: "Firefox", version: "42" }

if (navigator.browserSpecs.name == 'Chrome') {
    // Do something for Chrome.
    if (navigator.browserSpecs.version > 76) {
        // Do something for Chrome versions greater than 76 like load v1.
    }
}
else {
    // Do something for all other browsers.
}

Mac_W
fonte
Antes de tudo, obrigado pela sua resposta. O verdadeiro problema está na construção de um componente depois que você detecta a versão do navegador? Adicionar uma verificação para detectar a versão do navegador seria uma etapa extra.
Konga Raju
Parece que fui longe demais em suposições - minha idéia acima foi criar 2 componentes separados e carregar nos navegadores apropriados.
Mac_W 22/10/19