DEV Community

Cory Rylan
Cory Rylan

Posted on • Originally published at coryrylan.com

Using Import Maps and Lit Element Web Components

When using JavaScript modules we often import with node package paths.
When loading JavaScript in the browser, the browser will not know where the package folder is because it is not a relative directory path. The path points to a node_modules directory where our packages are installed.

import { html } from 'lit-element';
Enter fullscreen mode Exit fullscreen mode

When using tools like Webpack or Rollup, they update the paths and bundle this code for us. This is a problem if we want to prototype without any build tools.

Web Component APIs in the browser are relatively low-level APIs. We can use tools like lit-html and lit-element to provide high-level abstractions. When using lit-element to build Web Components, we typically need a build step. Lit-element ships as modern es2015+ JavaScript; however, it uses import paths that are not relative file paths. Luckily an upcoming browser feature called import maps are a potential solution to save us from build tooling.

JavaScript Module Import Maps

Import maps are a new proposed feature for JavaScript modules. Import maps allow us to tell the browser when it sees one path for a module to use another. Our example we import from lit-element.

import { html } from 'lit-element';
Enter fullscreen mode Exit fullscreen mode

With an import map we can tell the browser to swap out lit-element
to use a CDN URL instead.

<script type="importmap">
  {
    "imports": {
      "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module"
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

This snippet maps our import to our new path which points to a CDN version of the lit-html package.

import { html } from 'https://unpkg.com/lit-html@latest/lit-html.js?module';
Enter fullscreen mode Exit fullscreen mode

This mapping is helpful since we don't want to have to use a build step to transform the paths for us. Import maps are still a newly proposed feature, so to use them, we need to use a shim JavaScript file to provide the functionality. We will use the es-module-shims polyfill.

<!doctype html>
<html>
  <head>
    <script defer src="https://unpkg.com/es-module-shims@latest/dist/es-module-shims.js"></script>
    <script type="importmap-shim">
      {
        "imports": {
          "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module",
        }
      }
    </script>
    <script type="module-shim">
      ...
    </script>
  </head>
  <body>
   ...
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

To use the shim, we have to suffix the module types with shim, so the polyfill/shim has time to process and update the paths. To use lit-element, we need to update a few paths since lit-element has a few different import paths.

<script type="importmap-shim">
  {
    "imports": {
      "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module",
      "lit-element": "https://unpkg.com/lit-element@latest/lit-element.js?module",
      "lit-html/lit-html.js": "https://unpkg.com/lit-html@latest/lit-html.js?module",
      "lit-html/lib/shady-render.js": "https://unpkg.com/lit-html@latest/lib/shady-render.js?module"
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Now that we have the import map set up out we can start using lit-element in our JavaScript.

<!doctype html>
<html>
  <head>
    <script defer src="https://unpkg.com/es-module-shims@latest/dist/es-module-shims.js"></script>
    <script type="importmap-shim">
      {
        "imports": {
          "lit-html": "https://unpkg.com/lit-html@latest/lit-html.js?module",
          "lit-element": "https://unpkg.com/lit-element@latest/lit-element.js?module",
          "lit-html/lit-html.js": "https://unpkg.com/lit-html@latest/lit-html.js?module",
          "lit-html/lib/shady-render.js": "https://unpkg.com/lit-html@latest/lib/shady-render.js?module"
        }
      }
    </script>
    <script type="module-shim">
      // you can also set a external script src with type "module-shim"
      import { LitElement, html, css } from 'lit-element';

      class XComponent extends LitElement {
        static get styles() {
          return css`
            :host {
              color: red;
            }
          `;
        }

        render() {
          return html`
            Hello from lit-element!
          `;
        }
      }

      customElements.define('x-component', XComponent);
    </script>
  </head>
  <body>
    <x-component></x-component>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Lit HTML Web Components with Import Maps

We can now import from lit-element and start writing our Web Components.
Import maps with lit-element is excellent for quick prototyping and trying out different Web Component libraries. Want to learn more about lit html check out my other blog post Web Components Building Web Components with lit-html. Check out the full working demo on Stackblitz.

Top comments (0)