Re: [w3c/webcomponents] HTML Modules (#645)

I've updated my HTML modules proof-of-concept to support module scripts: https://github.com/AshleyScirra/import-as-and-html-modules

This does pretty much everything HTML imports did, and more, since it supports modules. It's also implemented entirely in JavaScript. I think this is evidence that there does not need to be a specification for this. As per the extensible web manifesto, it's better to spec low-level stuff and leave the high-level features to libraries, exactly as done here.

## Overview
You can write working code like this, today:

```js
const htmlModule = importAs("myModule.html", HTMLModule);

// Use a class exported by a nested module
const MyClass = htmlModule.exports.get("MyClass");
const myClass = new MyClass();
myClass.Foo();
```

myModule.html would look something like this:

```html
<template id="foo">...</template>

<script src="myClass.js" type="module"></script>
```

and myClass.js would look something like this:

```js
const myModule = getCurrentHtmlModule(import.meta.url);
const myDocument = myModule.document;
const templateElem = myDocument.getElementById("foo");
// ... use template element ...

// Used for the call htmlModule.exports.get("MyClass")
export const TAG = "MyClass";

// Actual class exported
export default class MyClass {
    Foo() { /* ... */ }
};
```

## Use cases covered
- Import pretty much anything, e.g. `const str = await importAs("file.txt", String)`, `const imageBitmap = await importAs("image.png", ImageBitmap")` etc.
- Get HTML/elements in a script, e.g. `const doc = await importAs("file.html", Document)`, `const elem = await importAs("file.html", Selector("#elem"))`
- Get HTML/elements from an imported HTML module, e.g. `htmlModule.document.getElementById("foo")`
- Get HTML/elements from the HTML module that included the current `<script>` tag, e.g. `const elem = getCurrentHtmlModule(import.meta.url).document.getElementById("foo")`
- Export JavaScript modules from HTML modules, e.g. `htmlModule.exports.get("MyClass")`
- Import nested HTML modules using `<link rel="html-module">`, and still access exported JavaScript classes from script modules in deeply nested HTML modules, allowing for complex dependency trees
- Automatically applies styles to main document. Apparently this was problematic with HTML imports. Can easily be turned off if not desired.
- A HTML module can be used as a single-file package with markup, style and script, if it supports an inline `<script type="module">`
- no need for HTML or CSS in JS strings anywhere
- bi-directional: HTML modules can import script modules, and script modules can import HTML modules
- integrates nicely with JS modules, re-using existing module mechanisms like `import()` (HTML imports did not manage this)
- backwards-compatible with classic scripts
- lives in a JS library so flexible, future-proof and doesn't require a specification written; no "magic" needed
- all asynchronous and doesn't block HTML parsing in main document
- can load dynamically for on-demand usage

Things not covered:
- custom elements - I don't know enough about these to comment. I suspect this library should handle them well though.
- syntax so `import htmlModule from "./module.html" as HTMLModule` can work. Currently you can only do `const htmlModule = await importAs("module.html", HTMLModule)`, which is kind of OK already.

Are there any other use cases to cover?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/645#issuecomment-391078723

Received on Tuesday, 22 May 2018 17:42:16 UTC