Tuesday 7th March, 2023
By Allan Jardine

Experiment: Import Maps

With ES modules gaining traction throughout the entire Javascript ecosystem, it is natural to want to use them directly in the browser. We can do that through the type="module" attribute for a script, but the browser needs to be able to resolve import names into Javascript files that can be loaded and executed. The importmap script type is the solution to that problem.

For DataTables, we could create a really simple import map like this (note that DataTables has a dependency on jQuery, hence we need to add a resolver for it as well, even if we don't actually write any jQuery code here):

<script type="importmap">
{
    "imports": {
        "jquery": "https://esm.sh/jquery@3.6.3",
        "datatables.net": "https://cdn.datatables.net/1.13.3/js/jquery.dataTables.min.mjs"
    }
}
</script>

Now that the browser has that mapping available, we can import and use DataTables as normal:

<script type="module">
import DataTable from 'datatables.net';

window.addEventListener('DOMContentLoaded',function () {
    new DataTable('#example');
});
</script>

You can see that script and loading here.

The goal in this post is to explore how we might be able to make DataTables easily usable via import maps with DataTables, assessing advantages and limitations of this approach.

The attraction of import maps

Import maps are a way of enabling the use of ES modules in the browser, allowing them to address external content with a simple name lookup. That's it!

The ES module import syntax is brilliant in its simplicity. Need a module; just import it. We get benefits of reuse, optimised loading, and simple to use syntax. Bundlers can use ES modules to implement tree shaking so code that isn't used, isn't served to the client. Combine this with the fact that there are a large number of files that make up the DataTables suite of software (depending on what features and styling you want to use), and ES modules make development work so much easier.

To select what DataTables modules to import, we have our download builder to help. The npm instructions and import statements shown at the bottom of the page match the import statements for this loader. At the time of writing there are 136 files that can be loaded for DataTables (normally you only need a few of those - you would never load all as they would conflict!). The upshot of this is that you don't want to create an import map for DataTables by hand. You want to just import a single map that covers everything, and then in your Javascript module import the libraries that you want.

External maps

At the time of writing (March 2023), no browser supports external import maps (e.g. remote loading of the JSON), although there is discussion about this in the Web Incubator Community Group. Therefore, to enable use of an externally located import map, we need to use Javascript to create the map for us - i.e. load a Javascript file that will create the map and allow us to use it.

Such a file for DataTables is available here:

JS

To make use of it, include it as a script on your page, and you'll immediately be able to use import statements for DataTabes - e.g.:

<script src="https://cdn.datatables.net/1.13.3/js/importmap.js"></script>
<script type="module">
    import DataTable from 'datatables.net';

    window.addEventListener('DOMContentLoaded',function () {
    new DataTable('#example');
    });
</script>

Limitations

Import maps have support in current versions of all evergreen browsers, and polyfills exist for older browsers, so availability isn't too much of a concern (unless you still need to support legacy browsers such as IE). However there are a number of material issues that limit the usefulness of import maps at this time.

No external JSON

We've seen above that there currently isn't support for external JSON, necessitating the use of a workaround that will create the import map from a Javascript file.

Single import map per document

The import map specification does not allow more than one import map per document. Only the first is parsed and the others ignored. The upshot is that you can't include an import map for DataTables, and another provided by Bootstrap or any other library - you must manually combine them together.

No Subresource Integrity

The import map specification does not support Subresource Integrity (SRI) at this time. There is no way for a map to say that the file resolved for datatables.net (or any other module), must have a certain hash, otherwise it should be considered invalid. This is an important part of web-development, particularly when including resources from an external CDN.

CSS

There is no equivalent for CSS. Often we see this, where Javascript development tools can outstrip CSS (bundlers are a common example, where CSS is added after the fact). DataTables, and other Javascript libraries strongly depend upon their CSS to display a nice looking front end to the end user. What's the point of having a single import map and then import statements in Javascript, if we still need a lot of link elements for the CSS?

Conclusion

I really hope the import map specification continues to develop and browser's fully implement it. It could be a great tool for development of web components, but at this time, its utility is limited, and I've not (yet) committed to providing an import map with each release of DataTables.