Skip to content

nevir/html-exports

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTML Exports

Why let JavaScript have all the fun? HTML documents can be modules too!

The Syntax

Declaring Exports

Just like ES6 modules, you can choose particular values to export from a HTML document. Simply place an export attribute on any element with that you wish to export:

<div export id="user">...</div>

You can also declare the default export of the document by tagging an element with default (id is optional).

<section export default id="post">...</section>

If you don't declare a default export, the document is exported.

Declaring Dependencies

You can also declare dependencies on other modules from HTML.

<import src="Polymer"/>

Similar to ES6's import syntax, you can import particular values from the module, too. A default export can be imported via:

<import src="jQuery" as="$"/>

Named exports can also be imported via the values attribute:

<import src="ng/di/annotations" value="Inject"/>

Not supported yet: Some way of aliasing named imports. The technical side is straightforward, but a decent syntax is unclear. Suggestions welcome!

Using Imported Values

We also introduce the concept of "scoped" <script> elements, that is a close analogue to the <module> element, but for ES5. It gives you the following:

  • Any values imported by the document are made available to a scoped script.
  • Scoped scripts run in strict mode.
  • Scoped scripts execute asynchronously (i.e. once all modules have loaded).
  • Scoped scripts can export values via CommonJS-style exports.

For example:

<import src="jQuery" as="$"/>
<script type="scoped">
$(function() {
  // doing things!
})
</script>

That example is equivalent to the ES6 form:

<module>
import $ from 'jQuery'
$(() => {
  // doing things!
})
</module>

Exporting Values From Script

As mentioned above, you can export values from a scoped script! These values are exported as part of the HTML module. You can even mix and match:

<template export id="tentacle">...</template>
<script type="scoped">
exports.default = function Squid() {
  // Oh hay there, I'm a squid!
}
</script>

Importing HTML Modules Via ES6

Just treat a HTML module as you would any other module:

import { user, post } from './templates.html'

user and post are the elements exported by templates.html!

Using It

Include html-exports.min.js (~0.8KB gzipped) in your page, after loading es6-module-loader and SystemJS.

<script src="es6-module-loader.js"></script>
<script src="system.js"></script>
<script src="html-exports.min.js"></script>

This gives you the default behavior where any module with a .html extension is treated as a HTML module. SystemJS is only necessary if you are loading ES5 code (e.g. CommonJS or AMD modules).

Compatibility

This library currently supports IE9+ and evergreen browsers.

For browsers that do not support HTML imports (i.e. everything but Chrome), you will need to polyfill it:

<script src="HTMLImports.min.js"></script>
<script src="html-exports.min.js"></script>

SystemJS

Alternatively, you can use the SystemJS plugin by grabbing a build of it, renaming your build to html.js and placing that build somewhere on your load path for SystemJS to discover.

You can then load HTML modules via:

// Implicit plugin name
import { user, post } from './templates.html!'
// Or explicit plugin name:
import { user, post } from './templates.html!html'

Playing With It

Try out the demo:

gulp demo

Hacking On It

Run this in the background for continuous testing/building:

gulp

Understanding It

For a deeper understanding of how HTML Exports works, take a look at the annotated source.