6

Having set up a web project to use TypeScript/WebPack I cannot get Google Chrome to run the result:

enter image description here

The error reads: "Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function."

I learned that a shim is required for transpiling to ES5, but I still can't get this to work. That's probably because I don't want to add a <script> element to the HTML but instead I want to import "../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle"; in my .ts files.

How can I get this to work without adding <script> elements to my HTML files?

I took my tsconfig.json and webpack.config.js files from this tutorial.

3
  • 1
    Hopefully this helps – github.com/angular/angular/issues/24556 Commented Feb 4, 2019 at 0:38
  • It looks like this is making things work for Chrome, but IE11 fails with customElements is undefined. Commented Feb 4, 2019 at 17:30
  • 1
    Found it, thanks to your hint. I'll add the solution here. Commented Feb 4, 2019 at 17:41

1 Answer 1

6

Here's the solution:

npm install @webcomponents/webcomponentsjs --save-dev
import "@webcomponents/webcomponentsjs/webcomponents-bundle";
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js';

...

As far as I can see, this runs smoothly on Chrome, Firefox, Edge and IE11.

Sign up to request clarification or add additional context in comments.

3 Comments

As a rule of thumb, don't include polyfills with your components. Instead, they should be provided by the application consuming the component. I'm not sure if I understood your setup correctly, but usually both webcomponents-... and es5-adapter are imported using a <script> tag (which might be generated by the bundler/compiler) into the main page (which is an HTML page rather than a TS file).
To give an example for that kind of setup: in my webpack config, there's an entry defined for each polyfill, like { entry: { polyfills: '@babel/polyfill', 'wc/webcomponents-loader': resolve(__dirname, '../../../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader'), app: resolve(...) }, ... }
Web components are supposed to be served "as-is". There's no compilation step available when including web components. So the transpilation (incl. polyfills) needs to be done in advance, before publishing the web component. That's why it's a devDependency.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.