Background
Drupal core now includes support for importmaps
If you are using one of the contributed modules (importmap, importmaps) you should uninstall these modules and add your importmaps to MODULENAME.importmap.yml files instead.
Import maps allow you to bundle your JavaScript and exclude third-party dependencies, leaving them as naked imports.
e.g.
import React from 'react';
Ordinarily the browser can't understand that.
With an import map it can.
You can only have one <script type="importmap"></script> in the page, and hence this functionality belongs in core.
Usage
A module can declare an importmap entry by adding a MODULENAME.importmap.yml or THEMENAME.importmap.yml to the root of the extension folder.
For example adding something like this to a hypothetical module called react which is installed in modules/contrib/react:
imports:
react:
path: js/dist/react.js
react-dom:
path: js/dist/react-dom.js
would result in the following added to the <head> element
<script type="importmap">
{
"imports": {
"react "/modules/contrib/react/js/dist/react.js",
"react "/modules/contrib/react/js/dist/react-dom.js",
}
}
</script>
If you need to load different versions of a library depending on a path, you can make use of scopes.
imports:
react:
path: js/dist/react.js
react-dom:
path: js/dist/react-dom.js
scopes:
js/legacy:
react:
path: js/dist/react-17.js
react-dom:
path: js/dist/react-dom-17.js
In this scenario, any code found in js/legacy inside your module that included import React from 'react' would load react from js/dist/react-17.js
A note on bundling
If you want to make use of importmaps, you probably want to use something like Vite/Rollup externals e,g
// vite.config.ts
defineConfig({
// other stuff
build: {
rollupOptions: {
external: ["react", "react-dom",],
},
},
// more other stuff
})
Webpack has a similar functionality
In this example, react and react-dom are being flagged as external. This instructs the bundler not to include the source code from these packages in your bundled code, and will result in the output code looking something like this:
import React from 'react';
// your code here
When encountering the import line above, the browser will consult the importmap and load the code using a dynamic import.