Skip to content

Iterating over the SystemJS registry #1918

Closed
@joeldenning

Description

I have two use cases where it would be nice to iterate over all keys/entries in the SystemJS registry and import map, which seems to currently be impossible with SystemJS 3. Afaik, there is no current spec or proposal for how browsers will allow users to access the browser's module registry or import maps, so implementing this would be a SystemJS specific API.

Use case 1 - Setting the public path for webpack code splits

Webpack projects that are compiled down to a format consumable by SystemJS do not use SystemJS to load their code splits. Which means that you often have to set the webpack public path dynamically in the browser if you want to have one bundle that works on multiple domains.

An initial attempt at setting the public path might look something like this:

System.resolve('name-of-module').then(resolvedUrl => {
  __webpack_public_path__ = resolvedUrl.slice(0, resolvedUrl.lastIndexOf('/') + 1)
})

The above has a race condition, since this can set the public path too late. Meaning that webpack has already begun to download css files, images, and js code splits that are synchronously imported during initial execution of the bundle. And that those things started before the promise resolved and so they will attempt to download them from the wrong URL.

An ideal solution would be a synchronous System.resolve, although that is not possible with import maps sometimes being downloaded instead of inlined. I think the second best thing would be to have access to the SystemJS final import map such that you can look up the entry for your webpack bundle and determine a public path from there.

Use case 2 - Tooling for System@3

I am planning on starting a new project, perhaps called system-inspector or import-map-inspector, which allows you to view your entire SystemJS registry and override the url for any module in the import maps for a current page. Overrides would work by setting a local storage flag that has a prefix (maybe package-override:react, for example) and then either adding an inline import map with those overrides or patching System.resolve to be aware of those overrides.

I'd be interested in your thoughts on this project idea ^, but also to implement it would need a System API that lets me list all current modules that are in the System registry and the import maps.

Proposed solution - Expose the import map and loader registry keys

System.getImportMap().then(importMap => {
  // do things with the import map
})

System.keys().forEach(moduleId => {
  // each imported module will show up here
})

These two things solve Use Case 2, but I'm not sure about Use Case 1. With use case 1, the System.keys() API is nice because it's synchronous, but I don't know if a module would be in the registry yet during the instantiation of the webpack bundle. If it is, then use case 1 is solved, otherwise I'm not quite sure what to do, besides patching System.register myself to create my own copy of the System registry.

I'm interested to hear your thoughts on best approach for these two use cases.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions