Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading static project without webpack or CDNs

I would like to statically serve a project, that uses webcomponents (using lit-html), without any packaging tools like webpack etc.

The example project is composed of this structure:

index.html
app.js
package.json

package.json:

{
  "name": "lit",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@webcomponents/webcomponentsjs": "^2.2.7",
    "lit-element": "^2.0.1"
  }
}

app.js:

import { LitElement, html } from 'lit-element';

class FooElement extends LitElement {
  render() {
    return html`<div>hello world!</div>`;
  }
}
window.customElements.define('x-foo', FooElement);

and finally, index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
  <script src="app.js" type="module"></script>
</head>
<body>
  <x-foo></x-foo>
</body>
</html>

I serve this using a static http server and, of course, this doesn't work. The browser raises the error: Error resolving module specifier: lit-element.

So we try altering the import directive to:

import { LitElement, html } from './node_modules/lit-element/lit-element.js';

The browser then fails with: Error resolving module specifier: lit-html in lit-element.ts:14:29

I've tried using systemjs version 3.0.1 with the following modified index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
</head>
<body>
  <script type="systemjs-importmap" src="systemjs.map.json"></script>
  <script src="./node_modules/systemjs/dist/system.min.js"></script>
  <script>
    System.import('app');
  </script>
  <x-foo></x-foo>
</body>
</html>

and a systemjs.map.json file:

{
  "imports": {
    "app": "./app.js",
    "lit-element": "./node_modules/lit-element/lit-element.js",
    "lit-html": "./node_modules/lit-html/lit-html.js"
  }
}

When loading this (again via a static webserver), we get in Firefox:

import declarations may only appear at top level of a module at app.js:1.

In Chrome: Uncaught SyntaxError: Unexpected token { at app.js:1

In Safari: Unexpected token '{'. import call expects exactly one argument. at app.js:1

All of which suggests that systemjs isn't treating app.js as a module.

Is there anyway that we can achieve static loading of modules that have a dependency tree within node_modules?

I've pushed the version of the code with systemjs to https://github.com/dazraf/lit-test.

Thanks.

like image 688
dazraf Avatar asked Mar 05 '23 08:03

dazraf


2 Answers

You can perhaps use something like this in your app.js

import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';

And this in your HTML code

<script type="module" src="./app.js">

It worked for me. If you don't want to use unpkg you can download it and serve it locally.

like image 141
Jerome Kerdreux Avatar answered Mar 09 '23 20:03

Jerome Kerdreux


We have a server that does just this, and only this: https://open-wc.org/developing/owc-dev-server.html

It's simple server that does the minimal amount of work required and is specifically designed to work with the native es module loader available in all major browsers.

In the future, this should no longer be necessary when import maps are standardized.

like image 32
passle Avatar answered Mar 09 '23 20:03

passle