Resolution, caching and errors
Resolution and caching
Section titled “Resolution and caching”srcresolves like a module specifier: relative to the importing document (or, inside a module, the importing module), or absolute. Bare specifiers go tohostResolve; in the browser that isimport.meta.resolve, so the page’s own<script type="importmap">applies. Import maps only map URLs; they never parse HTML. As in JavaScript,ui.htmlwithout./is a bare specifier.- A document’s
<html-import-settings base>replaces the document (or module) URL as the base for its relative specifiers. - Modules are cached by kind (HTML or JavaScript) and resolved URL as promises, so repeated and concurrent imports
share one fetch and parse. Failed loads are evicted and can be retried;
HTMLModules.unload(src)evicts one on purpose (registered tags stay registered, and a JavaScript module stays in the browser’s module map). - Circular dependencies between HTML modules are rejected with the cycle in the message, whether the modules load one after another or concurrently.
Errors
Section titled “Errors”Nothing fails silently. In markup, a failure is an error event (bubbling, composed, with detail.error) on the
element concerned, and a rejected el.ready; a failing <html-binding> fires on the binding and bubbles through its
import. In JavaScript it is a throw or a rejection. With errors="throw" it also reaches reportError() (the
console and window.onerror). Mistakes in a module’s source are SyntaxErrors naming the module, identical whether
the module is loaded or compiled. Some common ones:
| Situation | Error |
|---|---|
| Module fetch fails | Error: Failed to fetch HTML module …: 404 |
Invalid module (no template/style/JSON, duplicate or non-kebab name, two templates, bad shadow) |
SyntaxError naming the module |
A tag the delimiter makes invalid (as="ui" delimiter="." + card) |
SyntaxError: … <ui.card> is not a valid custom element name (it has no hyphen) |
| Circular dependency | Error: Circular HTML module dependency: a -> b -> a |
| Tag already bound to a different component | Error: Cannot bind <ui--card>: it is already defined by "card" from … (conflict="reuse" keeps the existing definition instead) |
| Missing export | SyntaxError: The requested module '…' does not provide an export named '…' |
A malformed binding in a template ({{ a + b }}), or an on*, style or srcdoc binding, at registration |
SyntaxError: …: Invalid binding "{{ a + b }}": a binding is the name of a host attribute, {{attribute-name}}. There are no expressions, filters or calls; write \{{ for a literal "{{" |
form-control without form-associated |
SyntaxError: <html-export name="<n>">: form-control="<selector>" needs form-associated: the component must take part in forms for its control's value to be the form value in <url> |
An unknown registry value |
SyntaxError: Invalid registry="<value>" on <html-import> in <url>: use "global" or "scoped" |
<html-import-settings> after an <html-import> |
SyntaxError: <html-import-settings> must come before any <html-import> … |
Every error, its exact message and where it is reported: Errors.