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

At TPAC I was asked to post the Polymer team's strawman for HTML Modules, so here it is. It's just one set of potential answers to a few choices that HTML modules bring up. We're more concerned with the capabilities than the specifics.

/cc @rniwa @travisleithead 

# HTML Modules Strawman

## Overview

We would like a version of HTML Modules that is capable of declaring a single-file element, including its template and script defining the element class. We also want to be able to define multiple components in a single file, or bundle HTML Modules, so this requires executing multiple scripts, and control of exports from an HTML module.

This strawman is a set of choices that enables that.

Previously there was some disagreement about how exports are defined and how multiple scripts behave, or whether they're supported at all. We hope this set of choices mayb provide a simple, explicit, non-magical answer to those disagreements.

By defaulting to exporting only the document and elements with id, we avoid problems of merging exports from multiple scripts. A script with an id of "default" allows for full manual control of exports.

## High-level priorities

 * P0: Some way of importing HTML, possibly inert
 * P0: Some way of when you import, getting access to `<template>`s, including re-exported `<template>`s from other HTML modules.
 * P1: Some was of exporting/importing arbitrary DOM.
 * P1: Execute `<script>`s in some reasonable way.
 * P1: Allow a `<script>` to control the HTML module's exports.

## Specific Design Choices
 * You can import an HTML file
 * The file defines a Document
 * Scripts execute, all scripts are deferred
 * Custom elements upgrade (and connect?)
 * Styles do not apply to main document
 * By default exports are defined in DOM:
   * The default export of the module is the document
   * Any element with an `export` attribute whose value is a valid JS identifier is exported as a const binding.
   * There is no special case for `<script>` tags: if they have an export attribute, they are exported as a script element, not the module they define.
 * (_this idea needs work, it conflicts with the previous point_) If a script has an `id` attribute value of "default", then its exports become the exports of the HTML module. The default script is completely responsible for all exports, there is no export merging.
 * Inline modules can be imported via a fragment URL that references their export attribute value:
   * `import * as bar from 'foo.html#bar';`
   * `import.meta.url` in inline scripts refers to the url of the HTML module.

## What would you export from HTML modules?
 * Templates. Probably multiple per file. Multiple per file then implies that you should be able to compose/re-export, when you split a 5-template file into 5 1-template files.
 * Custom elements. Importing the class? Or just importing the side effect of registration (i.e. no actual export).

## Examples

Example with a few experimental ideas such as single file modules and bundling ideas

### foo.html:

```html
<script type="module" id="scriptA">
  export let baz = 5;
</script>

<script type="module" id="scriptB">
  export const baz = true;
</script>

<template export="myTemplate">
  <style>
    :host {display: block}
  </style>
</template>
```

### bar.html:

```html
<template export="template">
  <div>Display!</div>
</template>

<script type="module" id="bar">
  export const qux = 1;
</script>

<script type="module" id="default">
  // reference the script module with id "bar" with a fragment URL
  export {qux} from './bar.html#bar';
  export default const doc = import.meta.scriptElement.ownerDocument;
</script>
```

### app.js:

```js
import fooDoc from './foo.html';
import {baz as a_baz} from './foo.html#scriptA';
import {baz as b_baz} from './foo.html#scriptB';
import barDoc, {qux} from './bar.html';

const template = barDoc.querySelector('template');
```

### Declarative Custom Elements

```html
<define name="my-element" export>
  <template shadowmode="open">
    <button>
      <!-- this part is exposed for styling to the including document -->
      <div class="site-logo" part="site-logo"></div>
      Share
    </button>
  </template>
</define>
```


-- 
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-343601237

Received on Friday, 10 November 2017 22:14:32 UTC