bdon.org

I am lacking a PhD in JavaScript packaging

As of now all of the Protomaps front-end packages produce 3 output formats:

  • CJS or “CommonJS” which is used by NodeJS command line and server programs.
  • ESM or “ECMAScript Module” which is adopted across all “front-end” tooling but still an experimental opt-in for node.
  • IIFE or “Immediately Invoked Function Expression” which is a convention and not a standard. This makes loading the library possible via a single script tag in a page header, and populates a single global variable e.g. pmtiles.

It is 2024 but making a bit of JS/TS code and publishing it to be widely useful is harder than before instead of easier.

It is possible to load ESM natively in browsers, but complex apps like a web map have dozens of internal dependencies, and would need to fetch dozens of individual module files. And, developers expect to author in TypeScript instead of raw JS.

So the Protomaps libraries all use esbuild for transpiling to 3 output formats, via a wrapper tsup (thanks Ben for the tip).

For publishing web maps, there’s a diverse range of front-end rendering libraries and developer preferences:

Leaflet

The lightweight Leaflet library works really well if you prefer build-free JavaScript. The quick start loads Leaflet from unpkg:

 <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""></script>
 <script>
 	var map = L.map('map').setView([51.505, -0.09], 13);
 	...

If you are using Leaflet in this way you will want to refer to pmtiles via the IIFE build on a CDN or your own host:

<script src="https://unpkg.com/pmtiles@4.0.1/dist/pmtiles.js"></script>

OpenLayers

OpenLayers takes the opposite path: the quick start tells you to create a NPM project with a bundler:

npm create ol-app my-app

it is possible to load core OL via a single script-includes like I do in this example but it will download a large bundled file (likely due to OL’s many features); you will instead want to build your own bundle from ESM for any production project.

npm install ol-pmtiles will let you use the ESM build (in most bundlers) and access TypeScript types, etc.

MapLibre GL

MapLibre works just fine wither either script tags or bundlers:

MapLibre script tag example

or npm install pmtiles alongside npm install maplibre-gl in your project, like in the protomaps docs repo.

Other

The CJS output exists for NodeJS programs that manipulate PMTiles archives and map styles. For example, the CloudFormation template for deploying a lambda proxy is a single YAML file; this works because you can inline the entire JS code in the YAML, but it only accepts CJS and not ESM!

If you have a suggestion for how to improve this you can find me on Bluesky or Mastodon.