importmap-rails reference
What are import maps?
Import maps is a proposal that provides control over what URLs get fetched by JavaScript import
statements. The basic idea is that you can ship modular JavaScript like the below directly to the browser without transpiling it through a tool like Webpack:
import moment from "moment";
import { partition } from "lodash";
For this to work, you supply the browser with an importmap like this:
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/src/moment.js",
"lodash": "/node_modules/lodash-es/lodash.js"
}
}
</script>
which would essentially translate to:
import moment from "/node_modules/moment/src/moment.js";
import { partition } from "/node_modules/lodash-es/lodash.js";
Import maps = no Webpack = Win!
Even better, you can avoid NPM and Node.js altogether by supplying HTTP paths instead:
<script type="importmap">
{
"imports": {
"moment": "https://ga.jspm.io/npm:moment.js",
"lodash": "https://ga.jspm.io/npm:lodash"
}
}
</script>
Is it safe to use?
There’s native support for import maps in Chrome / Edge 89+. There’s also a shim for browsers with basic ESM support so that it should work for around 95% of users.
Import maps in Rails
How to install
importmap-rails
is included by default in Rails 7+ applications.
For older Rails apps, you can do:
- Run
./bin/bundle add importmap-rails
- Run
./bin/rails importmap:install
Configuration
The import map is configured in config/importmap.rb
and will look something like this in a fresh Rails 7 project:
# frozen_string_literal: true
# Pin npm packages by running ./bin/importmap
pin 'application', preload: true
pin '@hotwired/turbo-rails', to: 'turbo.min.js', preload: true
pin '@hotwired/stimulus', to: 'stimulus.min.js', preload: true
pin '@hotwired/stimulus-loading', to: 'stimulus-loading.js', preload: true
pin_all_from 'app/javascript/controllers', under: 'controllers'
This import map is then included in the app/views/layouts/application.html.erb
via <%= javascript_importmap_tags %>
. You can view the output in your browser’s devtools.
Add to importmap via CDN
You can use the ./bin/importmap pin
command to get Rails to resolve NPM packages via the jspm.org CDN. For example, suppose you want to pin alpinejs, you can run:
./bin/importmap pin alpinejs
and Rails will append the following to your config/importmap.rb
:
pin 'alpinejs', to: 'https://ga.jspm.io/npm:alpinejs@3.8.1/dist/module.esm.js'
Add to importmap via /vendor directory
If you don’t want to use a CDN, you can download vendored files from the CDN instead:
./bin/importmap pin alpinejs --download
This will output something like:
Pinning "alpinejs" to vendor/javascript/alpinejs.js via download from https://ga.jspm.io/npm:alpinejs@3.9.5/dist/module.esm.js
You can then use the download vendor/javascript/<package>
in your application.
View importmap
You can use the ./bin/importmap json
command to view your importmap:
./bin/importmap json
{
"imports": {
"application": "/assets/application-37f365cbecf1fa2810a8303f4b6571676fa1f9c56c248528bc14ddb857531b95.js",
"@hotwired/turbo-rails": "/assets/turbo.min-96cbf52c71021ba210235aaeec4720012d2c1df7d2dab3770cfa49eea3bb09da.js",
"@hotwired/stimulus": "/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js",
"@hotwired/stimulus-loading": "/assets/stimulus-loading-685d40a0b68f785d3cdbab1c0f3575320497462e335c4a63b8de40a355d883c0.js",
"alpinejs": "https://ga.jspm.io/npm:alpinejs@3.8.1/dist/module.esm.js",
"controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
"controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js",
"controllers": "/assets/controllers/index-2db729dddcc5b979110e98de4b6720f83f91a123172e87281d5a58410fc43806.js"
}
}
Remove from importmap
./bin/importmap unpin alpinejs
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment