npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@single-spa/import-map-injector

v2.0.1

Published

Browser library adding small features to native import maps

Downloads

105

Readme

import-map-injector

import-map-injector is a browser library that adds a couple features to browser-native import maps:

  1. Support for multiple import maps on one page (by combining them into a single import map)
  2. Support for external import maps

The way this is accomplished is by combining multiple <script type="injector-importmap"></script> elements into a final <script type="importmap"></script>.

Installation

The import-map-injector.js file must execute before any ES module is loaded by the browser. Therefore, it's encouraged to load import-map-injector.js via <script> rather than install it as an npm package and then bundle it.

Via <script>

It's easiest to get best performance with import-map-injector by directly loading the import-map-injector.js file into your HTML page via <script type="text/javascript" src="./import-map-injector.js">. It is important to place the <script> element after any <script type="injector-importmap"> elements, but before any <script type="module"> or <script>import()</script> elements.

<!-- If you wish to auto-upgrade to latest import-map-injector versions, use the following URLs -->
<script src="https://cdn.jsdelivr.net/npm/@single-spa/import-map-injector"></script>
<script src="https://unpkg.com/@single-spa/import-map-injector"></script>

<!-- If you wish to pin to a specific version, swap VERSION with the version you're using -->
<script src="https://cdn.jsdelivr.net/npm/@single-spa/import-map-injector@VERSION"></script>
<script src="https://unpkg.com/@single-spa/import-map-injector@VERSION"></script>

<!-- If you wish to self host, that's possible too -->
<script src="./node_modules/@single-spa/import-map-injector/lib/import-map-injector.js"></script>

Via npm

As noted above, it's often easier to install import-map-injector via script rather than npm. Be aware that you might need to bundle/import import-map-injector separately from any web app you're trying to load, since import map installation is required before loading ES modules.

With those caviats in mind, import-map-injector is also available on npm:

npm install import-map-injector

When bundling

The following information only applies if you're trying to bundle import-map-injector via webpack, rollup, esbuild, etc. It doesn't apply in other contexts:

Then it should just be included in your browser bundle with the following import.

import "import-map-injector";

It's better for performance to put the import statement at the top of your bundler's main entry file, since import map installation is crucial to page load times.

Usage

import-map-injector combines multiple <script type="injector-importmap"></script> elements into a final <script type="importmap"></script> element, which is injected into the <head> element of the web page. The browser spec for import maps requires the <script type="importmap"></script> to be injected before any ES modules are loaded via <script type="module"> or import().

In your HTML page, add the following:

<html>
  <head>
    <script type="injector-importmap">
      {
        "imports": {
          "module1": "./module1.js"
        }
      }
    </script>
    <script type="injector-importmap">
      {
        "imports": {
          "module1": "./module1.js"
        }
      }
    </script>
    <script src="./import-map-injector.js"></script>
  </head>
  <body></body>
</html>

After import map installation finishes, your HTML page will have an additional <script type="module"> script appended to the <head>.

<html>
  <head>
    <script type="injector-importmap">
      {
        "imports": {
          "module1": "./module1.js"
        }
      }
    </script>
    <script type="injector-importmap">
      {
        "imports": {
          "module2": "./module1.js"
        }
      }
    </script>
    <script src="./import-map-injector.js"></script>
    <script type="importmap">
      {
        "imports": {
          "module1": "./module1.js",
          "module2": "./module2.js"
        }
      }
    </script>
  </head>
  <body></body>
</html>

Once import map installation has finished, you can proceed with loading modules via import().

Detecting when import map installation is complete

As per the Import Maps spec, no ES modules can be loaded until import map installation is completed. This means that you cannot use <script type="module"> or import() until after import map installation completes.

Note that the import map spec currently does not provide a way to use import map specifiers inside of <script type="module"> elements. However, it is still possible to load modules in your import map via <script type="module"> if you use a URL path rather than the import map specifier.

Synchronous import map installation

If you're not using external import maps (<script type="injector-importmap" src="./external-url.importmap">), import map installation occurs synchronously once the import-map-injector.js file is executed. This means you can use <script type="module"> and import() in your HTML file, so long as they are after the import-map-injector.js file is executed.

Example:

<script type="injector-importmap">
  {
    "imports": {
      "my-module": "./hello-world.js"
    }
  }
</script>
<script type="injector-importmap">
  {
    "imports": {
      "my-module2": "./hello-world2.js"
    }
  }
</script>
<script src="./import-map-injector.js"></script>
<!-- Since there are no external import maps, the import map is installed synchronously and we can immediately load modules -->
<script type="module" src="./hello-world.js"></script>
<script>
  // Loading with mapped import specifiers can be done with dynamic imports
  import("my-module2");
</script>

Asynchronous import map installation

When using external import maps, import-map-injector must wait for the network request(s) loading external import map(s) to complete before it can install the browser-native import map. This means you cannot use <script type="module"> and import() in your HTML file until after the import-map-injector's initPromise Promise has been resolved:

Example:

<script type="injector-importmap">
  {
    "imports": {
      "my-module": "./hello-world.js"
    }
  }
</script>
<script type="injector-importmap" src="external-url.importmap"></script>
<script src="./import-map-injector.js"></script>
<!--
  Since there is an external import map, the import map is installed asynchronously and so we must wait for import map installation
  before loading modules with <script type="module"> or import()
-->
<script>
  window.importMapInjector.initPromise.then(() => {
    console.log("Ready to dynamically import modules");
    import("my-module");
  });
</script>

Compatibility

import-map-injector is compatible with import-map-overrides@>=4.1.0 via an in-code integration. To use the two projects together, do the following:

  1. Load import-map-overrides.js before import-map-injector.js
<!-- overrides before injector. [email protected] or greater required -->
<script src="import-map-overrides.js"></script>
<script src="import-map-injector.js"></script>
  1. Add the use-injector attribute to the <meta name="importmap-type"> element that configures import-map-overrides. See import-map-overrides docs for more details
<meta name="importmap-type" use-injector />