Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with Angular Element support in chrome and IE11 simultaneously

I have been playing around with Angular Elements and trying to achieve the best browser compatibility possible. However I seem to have hit a dead end, since when I add an IE polyfill for Shadow DOM, it breaks the Element in chrome.

Initially I had the error 'Failed to construct HTML element', so I changed the 'target' in my tsconfig.json to es2015/es6.

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

Component

// @dynamic
@Component({
    selector: 'flexybox-cardmanagement',
    templateUrl: './card-management.component.html',
    styleUrls: ['./card-management.component.scss'],
    encapsulation: ViewEncapsulation.ShadowDom
})

Changing the target happened to break IE though, since es2015/es6+ is not supported. So I happened to find the custom-elements-es5-adapter in the @webcomponents package, which wraps ES5 to provide the neccessary ES6 functionality to the browsers that needs it. And then I also had to add support for custom-elements.

polyfills.ts

/*****************************************************************************************
 * APPLICATION IMPORTS
 */
 import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js';
 import '@webcomponents/custom-elements/custom-elements.min';

At this point it works in Chrome but i get the following error in IE

SCRIPT438: Object doesn't support property or method 'attachShadow'

So I tried adding polyfill for Shadow DOM by adding the following to my polyfills.ts:

import '@webcomponents/shadydom';

Which seems to fix the issue in IE, but now gives me the following error in chrome:

Uncaught TypeError: Cannot read property 'defineProperties' of undefined

like image 252
Jonas Mohr Pedersen Avatar asked Feb 19 '19 10:02

Jonas Mohr Pedersen


2 Answers

Getting custom elements to work in IE11 is really a torture. I may not bring you there, but at least one step further.

I think you did almost everything right, I've gone through the same steps, but I used diffrent polyfills, so maybe you want to try these:

angular.json

"scripts": [
  // removed polyfill `document-register-element.js` that may be included with ng add @angular/elements
]

polyfills.ts

import '@webcomponents/shadydom/shadydom.min.js';
import '@webcomponents/custom-elements/src/native-shim';
import '@webcomponents/custom-elements/custom-elements.min';

To check if it might be a version problem:

package.json (relevant parts)

{
  "dependencies": {
    "@angular/**": "~7.2.1",
    "@webcomponents/custom-elements": "^1.2.1",
    "@webcomponents/shadydom": "^1.4.2",
    "core-js": "^2.5.4",
  }
}

Info: With this configuration, the custom element works in Chrome, Firefox and IE11 for me, but I don't get output bindings to work in IE11. I don't know why this is caused, if you are interested in this and find a solution to it, you may provide it here.


Genral tip for IE11:
Not your problem now, but if IE11 throws one of its various erros, it helped me a lot to use import 'core-js/shim' in polyfills.ts. This imports all shims at once to check if IE11 misses one of those. If so, you can tackle it down further, if not you know you have to look elsewhere.

Angular Elements polyfill
If you want to stay with the polyfill used by Angular, you may try to use version 1.8.1. I read somewhere (but can't remember where) that later versions cause problems in IE at the moment.

like image 51
jowey Avatar answered Nov 16 '22 22:11

jowey


If I understand it correctly the issue relates to the fact that IE11 doesn't support classes and that Chrome must have classes for webcomponents. There is a wrapper that lets you have one bundle and then wrap the functional-approach in a class for chrome, but I would recommend having two seperate bundles for this instead, and not compile to es5 for browsers that understand classes.

like image 1
Filip Bech-Larsen Avatar answered Nov 16 '22 23:11

Filip Bech-Larsen