如何构建Web组件自定义元素以同时使用这两个规范


9

我需要建立一个应该需要工作与两个规格,组件custom elements spec v0它得到了过时custom elements spec v1,最新的稳定版本。

如果我使用custom elements v0规范构建组件,则由于某些应用正在使用polymer 2和使用上述规范,因此它们将面临问题,而polymer 1custom elements v1规范不兼容的应用将面临同样的问题。

我无法控制更改Polyfill的应用程序,某些应用程序必须使用支持旧规范的Polyfill,而某些应用程序使用新的Polyfill。

我正在寻找一个可靠的解决方案,以结合这两个规范以在所有应用程序中运行我的自定义元素,而不管polyfills版本如何。我可以在组件中添加任何polyfill或代码段,以便它们可以在任何地方运行,但我还没有找到支持我的两个规范的库或polyfill。

我打算编写一个适配器,该适配器可以结合下面提到的用于绑定回调的映射之类的两个规范,对此的意见将不胜感激。

connectedCallback(){
    this.attachedCallback();
}

我尝试使用stenciljs,但它只能与最新版本的自定义元素规范一起使用。我还没有找到任何方法来对其进行调整以使其与早期规范兼容。

请针对上述情况提出一些可行的替代方案和可行的解决方案。

Answers:


1

基本上,您的组件具有一些依赖关系,这些依赖关系可以直接或间接在polyfill中定义。如果我们将这些依赖关系视为依赖关系图的节点,则存在图不同的问题。两个图中都可能存在一个节点,但是它们的行为有所不同(相同的旧实现和更新实现function),并且图中存在的某些节点在另一个图中可能会丢失。当然,您可以自己放置一些polyfill或类似的东西,但是随后您需要维护polyfill,这可能没有什么用。

在我看来,更好的办法是实现一个function

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

我不确定如何实现此功能function,但是如果存在可以function产生正确版本的a或功能之间存在明显差异,则可以相应地实现上面的功能。然后,运行以下代码:

if (getWebComponentsVersion() === "v1") {
    //code for v1
} else {
    //code for v0
}

感谢您的回答,在这种情况下,我需要维护两个版本的组件代码,这在添加功能时会很麻烦,从长远来看,修复问题将变得很忙。
Konga Raju

@KongaRaju确实是一个缺点,但是如果您设法缩小特定于版本的问题空间并扩大可应用于两个版本的代码区域,那么您可能会发现此问题比乍看起来的麻烦程度要小。
Lajos Arpad

-1

我怀疑你知道Custom Elements v0 is deprecated at M70, and will be removed in M80, by February, 2020.

您可以做的是访问Can I use网站并检查浏览器支持版本,以了解哪个浏览器应加载哪个自定义元素版本...

然后,如果您不想使用外部库,请实施以下内容以检查浏览器和版本,并为所需的浏览器相应地加载正确的自定义元素(更多信息请参见此处)。

如果可以使用外部库,请尝试使用Bowser来检测版本,平台等。

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.
}


首先,谢谢您的回答。真正的问题在于,一旦检测到浏览器版本,便要构建组件?添加检查检测浏览器版本的检查将是一个额外的步骤。
Konga Raju

似乎我在假设上走得很远-上面的想法是构建2个独立的组件并加载到适当的浏览器中。
Mac_W
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.