On Aug 28, 2014, at 10:10 AM, Ian Hickson <i...@hixie.ch> wrote: > Here are the changes that would be needed to make the ES6 loader > infrastructure underpin the Web platform's loader infrastructure > (basically, placing the ES6 loader the management layer between the Web > platform APIs on top, and Service Workers underneath). > ... > If we can reuse this for the rest of the Web platform, it gives authors a > really uniform API for all loading operations.
The module loader isn't the right layer for the kinds of things you're trying to do. I understand you're trying to avoid having similar mechanisms at multiple layers of the platform, but repurposing the module loader system as a general purpose web resource loading system means conflating web resources and modules, which leads to a mixing of concerns exposed to the development model. Let me go into some more detail. ## What the `System` module loader is for First, let's talk about what the module loader *is* for, and what the important requirements the browser's default `System` loader should address. In particular, I'm *not* saying that there should be *no* reflection of web assets to the JS module system. ### JS module name resolution * *Basic name resolution for JS modules.* Refer to global and relative modules. * *Module naming conventions that work across JS ecosystems.* Conventions that work on both client and server, particularly with npm. Straw-examples: ```javascript import _ from "underscore"; // global module import spinner from "./spinner.js"; // relative module ``` ### HTML interop * *Making JS modules available to HTML.* Allow HTML files to import from JS. Straw-examples: ```html <!-- for now: --> <script type="module"> import $ from "jquery"; import frobify from "/scripts/frobify.js"; $(".frob").each((i, elt) => { frobify(elt); }); </script> <!-- eventually, but we can save this discussion for another day: --> <module> import $ from "jquery"; // etc. </module> ``` * *Reflecting web assets as JS modules.* Make web assets available to JS as modules that export a DOM element. Straw-example: ```javascript import icon from "./icon.png"; console.log(icon instanceof HTMLImageElement); // true ``` ### Installing HTML/CSS components via module import * *Applying CSS via import.* Mechanism for applying stylesheets by importing them from JS. Straw-example: ```javascript import "./main.css"; // guarantees CSS is loaded and applied by the time this module executes import $ from "jquery"; $("#main").show(); ``` * *Installing HTML imports via import.* Mechanism for installing HTML imports by importing them from JS. Straw-example: ```javascript import widget from "./widget.html"; console.log(widget instanceof DocumentFragment); // true ``` ### Enriched response API * *Cross-origin fetch.* Cross-origin requests should succeed by returning and opaque response, just as ServiceWorker does, that cannot be inspected but can be returned back into the pipeline for execution. * *Streaming fetch.* It should be possible for a request to return a stream instead of a string, to allow asynchronous stream processing; this should use the API that results from the stream standardization process. ## What the `System` module loader is NOT for * *Bundling requests.* While it's attractive to use the loader for serving multiple assets in a single payload, this wants a more general solution for bundling arbitrary assets -- perhaps for performance (since despite the impending coolness of HTTP2, people will likely still use bundling as a successful optimization technique for a long time), but also for ergonomic deployment and inclusion. Jeni Tennison has done an excellent [proposal based on the link tag](https://github.com/w3ctag/packaging-on-the-web), and I've started exploring another approach based on URLs. Meanwhile people can experiment in userland with ServiceWorker-based techniques for bundling payloads. * *Repurposing the module registry to reflect caching of arbitrary browser fetches.* The registry is meant to record installation of things that are conceptually modules, not arbitrary network fetches of web assets. It's not the right place to store a cache of fetches. In particular, notice how above I said that it makes sense for modules to be able to import from, say, PNG files. In that case, the developer has explicitly requested that a web resource be reflected as a module, and it should be installed as a module. But using the registry for all web fetches means that non-JS is polluting the module registry with random modules reflecting arbitrary assets in the application. * *Forcing resource management to be reflected as modules.* The ServiceWorker API gives programmatic control over fetching of network payloads and a caching API. The module loader API gives programmatic control over fetching of modules and a caching API. What you're describing is using the latter for programmatic control over fetching and caching web assets, but that means you force them -- in the exposed API -- to be reflected as modules. * *Exposing loaded assets in a permanent global table.* The registry is a strongly mapped global table. If the DOM eliminates a resource that was loaded from the network, and that is necessarily installed in the module registry, it's pinned by the registry and uncollectable. ## What I suggest It's still not completely clear to me what your use cases are, so I'm not sure exactly how much user-visible API you need. But if you are trying to reflect the browser's fetching policies and priorities based on different types of assets, then you are looking for a layer in between ServiceWorker and module loader -- call it an asset manager or resource manager. I'd be happy to discuss this with you and see if we can flesh out the use cases and requirements to get a better handle on the problem space. Dave _______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss