- From: Ashley (Scirra) <notifications@github.com>
- Date: Tue, 22 May 2018 10:41:50 -0700
- To: w3c/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/webcomponents/issues/645/391078723@github.com>
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