2017-04-15 53 views
2

我在運行到ES5時遇到了一個簡單的Web組件工作問題。它在chrome,Edge和Firefox下似乎運行得很好,但IE11在組件的構造函數中失敗,「自定義元素構造函數未生成正在升級的元素」。從Typescript轉換到ECMAScript 5在IE11下失敗的自定義元素v1

UPDATE

奧利弗克魯爾的出色工作下面已經明確牽制的問題打字稿的編譯器輸出。是否有可能使其工作?

原始源(打字稿):

import "./AppDrawer.less" 

class AppDrawer extends HTMLElement { 
    get open() { 
     return this.hasAttribute("open"); 
    } 

    set open(val: boolean) { 
     val ? this.setAttribute("open", '') : this.removeAttribute('open'); 
    } 

    get disabled() { 
     return this.hasAttribute("disabled"); 
    } 

    set disabled(val: boolean) { 
     val ? this.setAttribute("disabled", '') : this.removeAttribute('disabled'); 
    } 

    static get observedAttributes() { return ["open"] }; 

    constructor() { 
     super(); 
    } 

    connectedCallback() { 
     this.addEventListener("click",() => { 
      this.open = !this.open; 
     }) 
     this.textContent = this.open ? "OPEN": "CLOSED"; 
    } 

    attributeChangedCallback(attr, oldVal, newVal) { 
     this.textContent = this.open ? "OPEN": "CLOSED"; 
    } 
} 


customElements.define("app-drawer", AppDrawer) 

輸出(bundle.js):

(function() { 
'use strict'; 

function __$styleInject(css) { 
    if (!css) return; 

    if (typeof window == 'undefined') return; 
    var style = document.createElement('style'); 
    style.setAttribute('media', 'screen'); 

    style.innerHTML = css; 
    document.head.appendChild(style); 
    return css; 
} 

__$styleInject("app-drawer {\n color: red;\n}\n"); 

function __extends(d, b) { 
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
    function __() { this.constructor = d; } 
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 
} 

var AppDrawer = (function (_super) { 
    __extends(AppDrawer, _super); 
    function AppDrawer() { 
     _super.call(this); 
    } 
    Object.defineProperty(AppDrawer.prototype, "open", { 
     get: function() { 
      return this.hasAttribute("open"); 
     }, 
     set: function (val) { 
      val ? this.setAttribute("open", '') : this.removeAttribute('open'); 
     }, 
     enumerable: true, 
     configurable: true 
    }); 
    Object.defineProperty(AppDrawer.prototype, "disabled", { 
     get: function() { 
      return this.hasAttribute("disabled"); 
     }, 
     set: function (val) { 
      val ? this.setAttribute("disabled", '') : this.removeAttribute('disabled'); 
     }, 
     enumerable: true, 
     configurable: true 
    }); 
    Object.defineProperty(AppDrawer, "observedAttributes", { 
     get: function() { return ["open"]; }, 
     enumerable: true, 
     configurable: true 
    }); 

    AppDrawer.prototype.connectedCallback = function() { 
     var _this = this; 
     this.addEventListener("click", function() { 
      _this.open = !_this.open; 
     }); 
     this.textContent = this.open ? "OPEN" : "CLOSED"; 
    }; 
    AppDrawer.prototype.attributeChangedCallback = function (attr, oldVal, newVal) { 
     this.textContent = this.open ? "OPEN" : "CLOSED"; 
    }; 
    return AppDrawer; 
}(HTMLElement)); 
customElements.define("app-drawer", AppDrawer); 

}()); 

而我的HTML:

<!doctype html> 
<html> 
    <head> 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.0-rc.8/webcomponents-lite.js"></script> 
     <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.0-rc.8/custom-elements-es5-adapter.js"></script> 
     <script src="bundle.js"></script> 
    </head> 
    <body> 
     <app-drawer open disabled></app-drawer> 
    </body> 
</html> 

回答

4

爲了讓custom elements v1工作交叉我們需要添加瀏覽器this native-shim(關於它的更多信息)。

這適用於所有主流瀏覽器(邊緣,safari,firefox等),但不在ie11!

當我們嘗試在ie11中導入它時,我們得到了一堆語法錯誤,因爲墊片是用一些es6編寫的。

一個簡單的解決方法是將墊片編譯爲es5並將其添加到es6版本(首先是es6,然後是es5以省略錯誤)。

這不是最乾淨的解決方案,但至少它工作。

我創建了一個repo一個工作示例(您的應用程序抽屜(由於衝突而刪除了disabled屬性))。

再次,它不VERRY乾淨,但它工作;-)

+0

@ mseddon我的答案幫助你了嗎? –

+0

好的,我已經嘗試了native-shim(在bundle.js之前添加),並觀察它現在在Edge,FF和Chrome中運行!但IE11仍然提出了相同的錯誤,其餘的我可以編譯成ES6。有沒有辦法讓它在包括IE11在內的所有平臺上工作? – mseddon

+0

噢,我也必須刪除'custom-elements-es5-adapter.js'才能在Chrome下正常工作。 – mseddon

2

的問題是打字稿的ES5類的實現與custom-elements-v1墊片不兼容。那麼,立即明顯的解決方案就是將TypeScript配置爲生成ES6並將其傳遞到Babel進行轉碼。

let rollupTs = rollupTypescript(require('./tsconfig.json').compilerOptions); 

rollup({ 
    entry: "src/client/main.ts", 
    plugins: [ 
     rollupTs, 
     less({insert: true}), 
     resolve({module: true, jsnext: true, main: true}), 
     babel({ 
      presets: [ 
       [es2015, { modules: false } ] 
      ], 
      plugins: ["external-helpers"], 
      exclude: "node_modules/**"}) 
    ], 
    dest: "bundle.js", 
    format: "iife" 
}) 

不過,看到接受的答案 - 似乎通過增加ES5 transpiled墊片的打字稿生成的代碼修復打字稿的ES5,而對巴貝爾編譯的代碼沒有任何影響。我已經接受它,因爲這是一個相當簡單的下拉式修復這個問題,與我不明白爲什麼它的工作原理