Tilted sphere with longitudinal stripes Modern Web Guides Docs Blog Toggle darkmode

Plugins: Import Maps

Plugin for resolving imports using Import maps.

Import Maps can be used to resolve imports in your code as an alternative to the --node-resolve flag, or to mock modules.

Import Maps

Description from the original proposal readme

This proposal allows control over what URLs get fetched by JavaScript import statements and import() expressions. This allows "bare import specifiers", such as import moment from "moment", to work.

The mechanism for doing this is via an import map which can be used to control the resolution of module specifiers generally. As an introductory example, consider the code

import moment from 'moment';
import { partition } from 'lodash';

Today, this throws, as such bare specifiers are explicitly reserved. By supplying the browser with the following import map

<script type="importmap">
  {
    "imports": {
      "moment": "/node_modules/moment/src/moment.js",
      "lodash": "/node_modules/lodash-es/lodash.js"
    }
  }
</script>

the above would act as if you had written

import moment from '/node_modules/moment/src/moment.js';
import { partition } from '/node_modules/lodash-es/lodash.js';

Installation

Install the package:

npm i --save-dev @web/dev-server-import-maps

Add the plugin to your web-dev-server.config.mjs or web-test-runner.config.js:

import { importMapsPlugin } from '@web/dev-server-import-maps';

export default {
  plugins: [importMapsPlugin()],
};

Basic usage

When the plugin is installed any import maps found in HTML files are used to resolve imports in modules imported by the HTML file:

<html>
  <head>
    <script type="importmap">
      {
        "imports": {
          "chai": "/node_modules/@esm-bundle/chai/chai.js",
          "./app.js": "./mocked-app.js"
        }
      }
    </script>
  </head>

  <body>
    <script type="module">
      // mapped to /node_modules/@esm-bundle/chai/chai.js
      import chai from 'chai';
      // mapped to ./mocked-app.js
      import app from './app.js';
      // any imports inside ./foo.js will be mapped as well
      import './foo.js';
    </script>
  </body>
</html>

In the test runner, you can author tests in HTML to use import maps in your test.

Import map options

Check the official proposal for all possible options.

Injecting import maps

The import map plugin can also inject import maps to HTML files using the inject option.

import { importMapsPlugin } from '@web/dev-server-import-maps';

export default {
  plugins: [
    importMapsPlugin({
      inject: {
        importMap: {
          imports: { foo: './bar.js' },
        },
      },
    }),
  ],
};

Including or excluding file

You can control which html files the import map is injected into using the include option. This is a glob matched against the browser path:

import { importMapsPlugin } from '@web/dev-server-import-maps';

export default {
  plugins: [
    importMapsPlugin({
      inject: {
        include: '/pages/*.html',
        importMap: {
          imports: { foo: './bar.js' },
        },
      },
    }),
  ],
};

The exclude option can be used to exclude files:

import { importMapsPlugin } from '@web/dev-server-import-maps';

export default {
  plugins: [
    importMapsPlugin({
      inject: {
        exclude: '**/*.fragment.html',
        importMap: {
          imports: { foo: './bar.js' },
        },
      },
    }),
  ],
};

Multiple Import Maps

The inject option can also take an array with multiple import maps:

import { importMapsPlugin } from '@web/dev-server-import-maps';

export default {
  plugins: [
    importMapsPlugin({
      inject: [
        {
          include: '/pages/a.html',
          importMap: {
            imports: { foo: './bar1.js' },
          },
        },
        {
          include: '/pages/b.html',
          importMap: {
            imports: { foo: './bar2.js' },
          },
        },
        {
          include: '/test/**/*.test.html',
          importMap: {
            imports: { foo: './bar3.js' },
          },
        },
      ],
    }),
  ],
};