Creating an Import Map
Import maps provide a way for developers to use shorter and more descriptive module specifiers in their code, which can improve code readability and maintainability. Instead of having to remember and type out lengthy URLs for each module, developers can use simple and memorable module specifiers that map to the correct URLs in the import map. Developers can still use tools like bundlers and minifiers, but now they can ship bare modules specifiers to production, and map those specifiers to the original source or to minified bundles.
Bare import specifiers are a shorthand for module specifiers that are used in JavaScript code. They allow developers to write simpler and more concise module specifiers, without having to specify the full URL of the module.
What are import maps?
Import maps are a feature of modern web browsers that allow developers to map between module specifiers and their implementing files. This enables developers to use short, easy-to-remember module specifiers in their code, while the import map takes care of resolving the correct URL for the module.
Why use import maps and bare import specifiers?
Prior to the adoption of import maps, developers had to manually specify the full URL of each module they wanted to import in their code, or use a build step to "resolve" those specifiers, prior to publishing. This made code harder to read and write, and made it more difficult to manage dependencies as they evolved over time.
Example:
<!-- // Import map -->
<script type="importmap">
{
"imports": {
"@patternfly/elements/pf-card/pf-card.js": "path/to/pf-card.js"
}
}
</script>
<!-- // Bare module import specifier -->
<script type="module">
import '@patternfly/elements/pf-card/pf-card.js';
</script>
Using generator.jspm.io
generator.jspm.io is a website that provides a free service to generate import maps for your JavaScript projects using the jspm.io content delivery network (CDN). generator.jspm.io provides a simple interface for generating import maps for your JavaScript projects.
To use it, follow these steps:
- Open your web browser and navigate to generator.jspm.io.
- Enter the module specifiers you want to map in the "Add Dependency" field. Each module specifier should be on a separate line.
- Change the version of the module using the dropdown, if necessary.
- Modify the entry point of the module by clicking "Add Package Export", if necessary.
- The importmap JSON and script tags update in real time as you add dependencies.
- Copy the generated import map
<script type="importmap">...</script>
. - Paste that importmap script tag into the
<head>
of your HTML document.
Once you've generated your import map and added it to your project, you can use it in your JavaScript code by specifying bare import specifiers for your modules. The import map will automatically resolve the correct URL for each module specifier at runtime.
<!--
JSPM Generator Import Map
Edit URL: https://generator.jspm.io/#U2NgYGBkDM0rySzJSU1hcChILClJLcpLy6nUT81JzU3NKyl2MNIz0DPQL0jTTU4sSoHRelnFAN524ZI8AA
-->
<script type="importmap">
{
"imports": {
"@patternfly/elements/pf-card/pf-card.js": "https://ga.jspm.io/npm:@patternfly/elements@2.5.0/pf-card/pf-card.js"
},
"scopes": {
"https://ga.jspm.io/": {
"@lit/reactive-element": "https://ga.jspm.io/npm:@lit/reactive-element@2.0.2/reactive-element.js",
"@lit/reactive-element/decorators/": "https://ga.jspm.io/npm:@lit/reactive-element@2.0.2/decorators/",
"@patternfly/pfe-core/controllers/slot-controller.js": "https://ga.jspm.io/npm:@patternfly/pfe-core@2.1.0/controllers/slot-controller.js",
"lit": "https://ga.jspm.io/npm:lit@3.1.0/index.js",
"lit-element/lit-element.js": "https://ga.jspm.io/npm:lit-element@4.0.2/lit-element.js",
"lit-html": "https://ga.jspm.io/npm:lit-html@3.1.0/lit-html.js",
"lit-html/": "https://ga.jspm.io/npm:lit-html@3.1.0/",
"lit/": "https://ga.jspm.io/npm:lit@3.1.0/",
"tslib": "https://ga.jspm.io/npm:tslib@2.5.0/modules/index.js"
}
}
}
</script>
<script type="module">
// resolves to https://ga.jspm.io/npm:@patternfly/elements@2.5.0/pf-card/pf-card.js
import '@patternfly/elements/pf-card/pf-card.js';
</script>
Overall, generator.jspm.io provides a simple and convenient way to generate import maps for your JavaScript projects. By using import maps and bare import specifiers, you can write cleaner, more concise code that is easier to read and maintain over time.
As an alternative to generator.jspm.io, you can also use the @jspm/generator. Install it using npm install @jspm/generator
. The ES module generator can be used to generate import maps with code for a more custom setup. The @jspm/generator can also be used against most common CDNs by configuring the defaultProvider
, defaulting to the JSPM CDN.
Writing import maps manually
If you prefer not to use a tool like generator.jspm.io or @jspm/generator, you can write importmaps
manually. Here's how:
- Create a new
<script type="importmap"></script>
tag. - Edit the contents of the script tag to specify the mapping between your module specifiers and the URLs of their implementations. For example:
<script type="importmap">
{
"imports": {
"module-specifier": "./path/to/module.js"
}
}
</script>
Replace "module-specifier" the module you want to map, and "path/to/module.js" with the relative path to the module's implementation.
Writing import maps manually can be a bit more tedious and error prone than using a generator like generator.jspm.io, but it gives you more control over the structure and content of your import map. If you're comfortable working with JSON files and URLs, writing import maps manually can be a good option.
Using multiple versions of the same module
Import maps allow you to specify multiple versions of the same module. This can be useful if you want to use different versions of the same module in different parts of your application. For example, you might want to use a newer version of a module in a new feature, while continuing to use an older version of the module in other parts of your application.
<script type="importmap">
{
"imports": {
"module-specifier@2": "./path/to/v2/module.js",
"module-specifier@3": "./path/to/v3/module.js",
}
}
</script>
Scoped import maps
By utilizing import maps scopes, you can specify the same module specifier for different parts of your application.
<script type="importmap">
{
"imports": {
"module-specifier": "./path/to/module.js"
},
"scopes": {
"/path/to/feature/": {
"module-specifier": "./path/to/v2/module.js"
}
}
}
To go into more detail about import maps visit developer.mozilla.org or the import map specification.