A browser javascript library for being able to override import maps. This works with native browser import maps or with the SystemJS polyfill for import maps.
Import maps are a way of controlling which url to download javascript modules from. The import-map-overrides library allows you to dynamically change the url for javascript modules by storing overrides in local storage. This allows developers to override individual modules to point to their localhost during development of a module, without having to boot up a local environment with all the other modules and a backend server.
You should not use import-map-overrides as the only import map on your page, since you cannot count on everyone's local storage having valid values for all of your modules. Instead, import-map-overrides should be viewed as a developer experience enhancement and dev tool -- developers can develop and debug on deployed environments instead of having to boot up a local environment.
The import-map-overrides library is used via a global variable window.importMapOverrides
. The global variable exists because import-map-overrides needs
to be usable regardless of build config and without dependence on ESM modules, since
once you use ESM modules you can no longer modify the import map.
It is preferred to install import-map-overrides with a <script>
tag in your html file.
<!--
Make sure to put this BEFORE any <script type="module"> elements or any System.import() calls, but
AFTER all other import maps
-->
<script
type="text/javascript"
src="https://unpkg.com/import-map-overrides"
></script>
<!-- optionally include the UI for import map overrides -->
<import-map-overrides-full></import-map-overrides-full>
Alternatively, you can use it as an npm package:
npm install --save import-map-overrides
# Or
yarn add import-map-overrides
/*
Make sure this js file gets executed BEFORE any <script type="module"> elements or any System.import() calls,
but AFTER any other import maps that are on the page.
*/
import "import-map-overrides"; // this only will work if you compile the `import` down to an iife via webpack, rollup, parcel, etc
If you are using import-map-overrides for native import maps, no configuration is required.
However, if you're using SystemJS as a polyfill for import maps, you'll need to tell import-map-overrides to make a
<script type="systemjs-importmap">
element instead of <script type="importmap">
. To do this, you must add a <meta>
element to your html file before the import-map-overrides library is loaded.
<meta name="importmap-type" content="systemjs-importmap" />
The import-map-overrides library can override a server-rendered inline import map, an import map that is loaded via src=""
, or
any other import map. The key to making this work is to ensure that the import-map-overrides library is loaded after all other
import maps that are on the page, but before the first <script type="module">
or System.import()
.
import-map-overrides provides the following functions. Note that these functions are always put onto window.importMapOverrides, even if you installed it as an npm package.
Returns the override import map as an object. The returned object represents the overrides that will take effect the next time you reload the page, including any additions or removals you've recently made after the current page's acquiringImportMaps boolean was set to false.
const overrideMap = window.importMapOverrides.getOverrideMap();
console.log(overrideMap);
/*
{
"imports": {
"module1": "https://mycdn.com/module1.js",
"lodash": "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.js"
}
}
*/
Accepts a string moduleName
and a string url
as arguments. This will set up an override which takes effect
the next time you reload the page. Returns the new override import map.
window.importMapOverrides.addOverride("react", "https://unpkg.com/react");
Accepts a string moduleName
as an argument. This will remove an override which takes effect the next time you
reload the page. Returns a boolean that indicates whether the override existed.
const wasRemoved = window.importMapOverrides.removeOverride("vue");
console.log(wasRemoved); // Either true or false
Removes all overrides from local storage, so that the next time the page is reloaded an override import map won't be created. Accepts no arguments and returns the reset override import map.
window.importMapOverrides.resetOverrides();
The import-map-overrides library fires an event called import-map-overrides:change
on the window whenever the
override import map changes. The event is a CustomEvent
that has no detail property.
Example usage:
window.addEventListener("import-map-overrides:change", logImportMap);
// Later on you can remove the event listener
window.removeEventListener("import-map-overrides:change", logImportMap);
function logImportMap(evt) {
console.log(window.importMapOverrides.getOverrideMap());
}
The UI for import-map-overrides gives visual indication when any module is overridden, so that you know whether to blame your override or not when things are broken. It also lets you view and modify urls for all the modules in your import map.
You use the import-map-overrides UI via web components. This means you just need to put some HTML into the DOM in order for it to work. You have three options for the UI, depending on how much you want to customize the UI:
<!-- The full UI, including the omnipresent "trigger" button that pops up the UI -->
<import-map-overrides-full></import-map-overrides-full>
<!-- Alternatively, just the black popup itself -->
<import-map-overrides-popup></import-map-overrides-popup>
<!-- Or if you only want the actual import map list and UI for overriding -->
<import-map-overrides-list></import-map-overrides-list>
The UI is completely optional. If you don't want to use it, simply don't include the <import-map-overrides-full>
custom element in your page. Additionally, you can use the
/dist/import-map-overrides-api.js
file
instead of /dist/import-map-overrides.js
,
which avoids downloading the code for the UI and reduces the library size.