Pinning packages
bin/importmap pin resolves a package on a CDN, downloads it to vendor/javascript and writes the pin.
Vendoring from a CDN#
bin/importmap pins, unpins and updates npm packages in your import map. By default it asks JSPM's API to resolve a package and its dependencies, downloads each file and adds the pins to config/importmap.rb:
$ ./bin/importmap pin react
Pinning "react" to vendor/javascript/react.js via download from https://ga.jspm.io/npm:[email protected]/index.jspin "react" # @19.1.0The files land in vendor/javascript, which you check into source control; the asset pipeline serves them like any other asset. A package with a / in its name is stored with -- instead (@hotwired/stimulus becomes @hotwired--stimulus.js) and the pin gets a to: pointing at that file.
A version goes in the spec: pin react@18, pin [email protected]. A subpath works the way it does on npm: pin apexcharts/core.
To remove a downloaded pin and its file:
$ ./bin/importmap unpin react
Unpinning and removing "react"Choosing a CDN#
Other CDNs are one flag away. --from takes jspm (the default), unpkg, jsdelivr, esm.sh, skypack, or esm.run for jsDelivr's bundled builds (see esm.run bundles):
$ ./bin/importmap pin react --from unpkg
Pinning "react" to vendor/javascript/react.js via download from https://unpkg.com/[email protected]/index.js
$ ./bin/importmap pin react --from jsdelivr
Pinning "react" to vendor/javascript/react.js via download from https://cdn.jsdelivr.net/npm/[email protected]/index.jsThe CDN is recorded in the pin comment when it isn't jspm, and later commands go back to it — an unpkg download stays on unpkg through update and pristine. Pass --from again to move a package to another CDN. See Provenance.
Pinning to a remote URL#
--remote pins the CDN URL instead of vendoring a download.
$ ./bin/importmap pin react --remote
Pinning "react" to https://ga.jspm.io/npm:[email protected]/index.jspin "react", to: "https://ga.jspm.io/npm:[email protected]/index.js"A remote pin is respected from then on, no flag needed. When the package is pinned again or picked up by update — directly or as a dependency of another package — the pin stays remote: the URL is re-resolved from the CDN provider it already points at (ga.jspm.io, unpkg.com, cdn.jsdelivr.net, cdn.skypack.dev or esm.sh) instead of being replaced with a download. pristine skips remote pins, since there is nothing to redownload.
An explicit --from moves a remote pin to that CDN; without it the current provider wins. --remote on a package that is vendored today converts it: the pin gets the URL and the file in vendor/javascript is removed.
Custom URLs#
A pin pointing at any other host is yours: pin and update leave it completely untouched and report it as skipped.
$ ./bin/importmap pin md5
Skipping "md5" pinned to custom URL https://cdn.example.com/md5.jsPin options survive a rewrite#
When a pin is rewritten — by pin, update or pristine — the options on it are carried over: preload: false, preload: "admin", integrity: true and integrity: false all stay. An explicit integrity: hash is dropped when the URL changes, since the old hash would no longer match the new file; see Subresource integrity for pinning fresh hashes.
Pins that a resolution touches only as dependencies keep their options the same way. Pinning md5 re-resolves charenc and crypt with it, but a pin "crypt", preload: false you wrote stays preload: false.