1

Context: until now I didn't mind about how import template html file to my vanilla webcomponent because I always wrote small html codes. So I have coded html on top of my webcomponent .js file and do something like:

const template = document.createElement("template");
template.innerHTML = `<div id="firstdiv"><input id="inputAny"/></div>`;

class anyVanillaWebComponent extends HTMLElement {
...
  connectedCallback() {
    this.attachShadow({ mode: "open" });
    this.shadowRoot.appendChild(template.content.cloneNode(true));
    const inputAny = this.shadowRoot.getElementById("inputAny");
...

This is quite common find in tutorials, blogs and foruns. Now I want to separate html from javascript assuming this will make my project tree more clear.

Searching around I found some discussion based on assumption that "import" will not be supported anymore in Browsers [(see UPDATE discussion on bottom about alternatives to import)].1

Basically this drove me to two possibilities:

1 - importing .js file to html from html Exemplifying:

<template id="my-webcomponent-template">
  <link rel="stylesheet" href="./some.css">
   <div>some content ...</div>
</template>
<script src="MyWebcomponent.js"></script>

2 - fetch asynchronously my-webcomponent.html from .js file

(async () => {
  const res = await fetch('/MyWebcomponent.html');
  const textTemplate = await res.text();
  const HTMLTemplate = new DOMParser().parseFromString(textTemplate, 'text/html')
                           .querySelector('template');

  class MyWebcomponent extends HTMLElement {...

Based on such discussion from 2017, it seems I should avoid the option 1 but it is not clear for me why and if there is some real advantage on option 2. So my straight question is: is there any real diference between "importing" and "fetching" html file while coding Vanilla Webcomponents which is expected to be rendered straight by browsers that support natively Webcomponents (for instance, Chrome)?

AppleJam
  • 1,039
  • 8
  • 18
Jim C
  • 3,957
  • 25
  • 85
  • 162
  • 1
    When talking about web components, you really want to keep your component's DOM code strongly tied to the JS, because a webcomponent isn't "the JS", it's "the JS + the (shadow) DOM it needs to render itself". Whether you do that through an html template string or JS-based DOM building is up to you, but keep everything together. And remember that a web component should come with, and also _only_ come with, the code required to render _itself_ and nothing more: children rendering correctly is the responsibility of each child. – Mike 'Pomax' Kamermans Aug 06 '19 at 16:01
  • I totally agree with " your component's DOM code strongly tied to the JS". I am interested to divide in two files, one html and another javascript, because I believe it will be more friendly and easier to organize from developer perspective. I don't intend to re-use the javascript file separated from html. Both will be coded with each othere in mind. BTW, my question is focused on two ways to do that and if they offer some advantage over another. Maybe a third alternative might be suggested and be wellcomed also. – Jim C Aug 06 '19 at 17:01
  • That feels like a false savings: get a good code editor or dedicated IDE and keep your custom component code in a single file with an easy to browse structure. Multiple files just makes it infinitely easier to break your custom component by not linking the right files in, where no linking would reasonably even be required. – Mike 'Pomax' Kamermans Aug 06 '19 at 20:55
  • Thanks for sharing your preference about not dividing js from html. BTW, my main question is opened. – Jim C Aug 06 '19 at 21:32

2 Answers2

2

If you don't plan to use your custom element in various pages then the 2 solutions are good.

In the first one it could be faster because you will save an HTTP request, for the HTML template is immediately available in the main HTML page.

But if you plan to reuse the custom element (or for better code separation), the second solution is better because the consumer is separated from the web component.

Supersharp
  • 29,002
  • 9
  • 92
  • 134
  • Excellent explanation. And what about Browsers that will support nativa webcomponent remove html import feature? Are you aware about that like the article mentioned few years ago? – Jim C Aug 07 '19 at 14:54
  • If you are confident I shouldn't worry about Browsers removing "import" than cerrtainly you answered my question – Jim C Aug 07 '19 at 15:01
  • 1
    @JimC Sorry I didn't understand you wanted to use HTML Imports in your first solution. I tought you wanted to include the – Supersharp Aug 07 '19 at 18:52
  • No worries. You are basically saying that I should prefer Option 2. – Jim C Aug 07 '19 at 21:19
2

You can always look at a bundler/packager. Webpack and others work well.

I wrote this one specifically for Web Components: https://www.npmjs.com/package/component-build-tools

It allows zero or more templates as real HTML files and allows importation of Locale based strings if you want to localize your components.

It also allows you to write your component using ES6 import and then cross-compile to ES5 if needed and allows output as an ES6 module file, a CJS file or a simple IIFE file.

Intervalia
  • 10,248
  • 2
  • 30
  • 60
  • Although not straight to my question title I found your answer quite usefull. I am taking a look at this. Is your component-build-tools desined for unit and integrataed test? I really miss some open source coded for vanilla webcomponents with testing strenghs. You may find several questions opened from me surronding somehow this idea in this forum. Specially with Karma + Jasmine it seesm there is some bridge not clear when weebcomponets come to mind. You may find interest in my yesterday question https://stackoverflow.com/questions/57384762/why-web-server-404-absolutec-when-running-karma – Jim C Aug 07 '19 at 15:00
  • 1
    When I wrote this I placed the majority of my logic into separate files and just imported them. Each of these files can be imported into Karma and tested. The nicest thing about that was that I greatly reduced repetitive code by creating these small, reusable files and importing them where needed. To test the overall component I also used Karma and tested just the functionality that was specific for the component. – Intervalia Aug 07 '19 at 17:33
  • I am trying separate a simple Vanilla Webcomponet in two files (html separated from javascript) and test them with Karma but I keep getting “[web-server]: 404: https://stackoverflow.com/questions/57384762/why-web-server-404-absolutec-when-running-karma. I create a folder named to-try with 3 web components: (1) js and html in same file, (2) js fetching html file and another (3) html importing js. Only the tentative 1, karma test runs without complaining about undefined variable. https://github.com/jimisdrpc/skyscanner-webcomponents. Thanks a lot if you can see it! – Jim C Aug 07 '19 at 21:37