Control the behavior of JavaScript imports with Import Maps

Shipping in Chrome 89 are Import Maps, which allows control over what URLs get fetched when importing modules.

Let’s take a look at this very welcome addition.

When importing ES Modules (on the web), you need to refer to them using their full filenames or URLs:

import moment from "/js/moment/moment.js";
import { partition } from "/js/lodash-es/lodash.js";

In a Node environment however, you would write the snippet above as follows:

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

(Node will map things to the /node_modules folder all by itself)

👉 So depending on where you run your code, your import statements need to change. Meh.

~

Thankfully Import Maps provide a solution to this. They allow you to specify which file/URL should be loaded when importing a package.

{
  "imports": {
    "moment": "/js/moment/moment.js",
    "lodash": "/js/lodash-es/lodash.js"
  }
}

With this in place the browser can handle import { partition } from "lodash" just fine, as it will load the file /js/lodash-es/lodash.js. 🎉

💡 With services like Skypack in place I can already see tools pop up that would automate the generation of such an import map based on a package[-lock].json that you feed it.

~

An import map is a tad of JSON file which you need to put it in a script[type="importmap"] element:

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

☝️ In the future it’ll also be possible to to put your import map into an external file and load it by specifying an src

<script type="importmap" src="import-map.importmap"></script>

To play nice with Content-Security Policy (CSP) the server needs to send the proper MIME-type though:

application/importmap+json

For more advanced usage, it’s also possible to add scoping.

~

These Import Maps sure are a very welcome addition. Unfortunately browser support is currently limited to Chrome only.

Data on support for the import-maps feature across the major browsers from caniuse.com

💡 Shown above is a dynamic CanIUse.com image, showing an always up-to-date support table. By the time you are reading this browser support might have become better.

Let’s hope other browsers follow suit soon. Relevant bugs to track:

~

To help spread the contents of this post, feel free to retweet its announcement tweet:

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

The several ways to import React

With the release of React 17 we also had to change the way we import React:

Kent C. Dodds goes over all ways to import React into your code, and explains why the good ole import React from "react" no longer works and why he went for import * as React from "react"

Importing React Through the Ages →

Skypack — Load optimized npm packages with no install and no build tools

I was delighted to read that CodePen now has built-in support for Skypack. This is a huge step forward to working with packages on CodePen. Great addition to the product!

But what exactly is Skypack? Well, it’s the successor to the aforementioned Pika CDN with some extra juice: Skypack not only serves packages that export ES Modules, it also converts packages that export older CommonJS Modules to ES Modules while at it.

Ever tried to load JavaScript from a CDN and realized that it doesn’t work in a browser without a bundler? Skypack operates like your favorite CDN but with an important difference: packages are preoptimized for browser use.

But Skypack doesn’t stop there: it handles minification, browser polyfilling, gzip/brotli, HTTP/3, caching, and more!

Skypack is free to use for personal and commercial purposes, forever. The basic CDN is production-ready and is backed by Cloudflare, Google Cloud, and AWS. We’re fully committed to building a core piece of infrastructure you can rely on.

Fred K. Schott, one of its authors, announced it this summer at ESNext Conf — a virtual conference which I also gave a talk at.

(Fast forward to the 18 minute mark to get to the Skypack part)

Here’s a simple Confetti example:

See the Pen
Confetti
by Chris Coyier (@chriscoyier)
on CodePen.

Neat, right?

Skypack — Load optimized npm packages with no install and no build tools →
Skypack + CodePen →

Worth It: Modern JS edition

“Worth It: Modern JS edition” is a small tool to analyze how much less JavaScript is downloaded in modern browsers as a result of it using the module/nomodule pattern.

Worth It: Modern JS edition →

💡 The module/nomodule pattern is a technique to ship ES2015 modules to browsers that support, whilst also keeping older browsers (that don’t support it) happy. It was covered here on bram.us back in July 2017

jQuery, now using ECMAScript module syntax

A nice commit migrating away from AMD Modules to ECMAScript modules recently landed in the jQuery repo. Once published as a new release, you’ll be able to actually import $ using the modern ES module syntax:

import $ from "jquery";
$('#message').text('Hi from jQuery!');

Handy if you’re modernizing a legacy project that still uses jQuery.

💡 Up until now I’ve been either including jQuery separately or have been relying on webpack-merge-and-include-globally to include jQuery in my Webpack build.

Pika CDN – A CDN for modern JavaScript

Yesterday the aforementioned Pika announced some new things. One of the things that stood out is Pika CDN:

The Pika CDN was built to serve the 60,000+ npm packages written in ES Module (ESM) syntax. This module syntax runs natively in the browser, so you can build for the web without a bundler.

With our CDN, package authors can distribute more modern, unminified packages without worrying about how to serve them directly. Instead, our nifty package-builder automatically resolves each package — and any legacy sub-dependencies — into a single, minified, ready-to-import JavaScript file.

Nice! Do note that versioning is limited:

🤔 I do wonder if something like Subresource Integrity will land for ES Modules … and oh, don’t we need to self-host our assets? Computering is hard, ugh! #nuance

Pika CDN →

Related: The previously mentioned create-es-react-app also touches directly importing ES Modules

create-es-react-app – A create-react-app like template using only es-modules (no build step).

create-es-react-app is a create-react-app like template demonstrating how far you can get creating progressive web apps (using react) with no build step. It takes advantage of static and dynamic imports which enables you to break up your app into small reusable ES modules that are compiled for you by the browser at run time.

TIL: You can directly import ES modules from unpkg:

import { React, ReactDOM } from 'https://unpkg.com/[email protected]/index.js';
import htm from 'https://unpkg.com/[email protected]/dist/htm.mjs'
import csz from 'https://unpkg.com/[email protected]/index.js'

🤔 ES Modules? This video by Heydon Pickering has got you covered.

create-es-react-app Source (GitHub) →
create-es-react-app demo →