<Hazm Blog />

Rails7 rails/importmap-railsの概要

Cover Image for Rails7 rails/importmap-railsの概要
Hazm
Hazm

Rails7からWebpack等のBundlerを使用しないアプリケーション開発手法が主軸となるようです。その中でESModuleをブラウザ上で直接フェッチするような形がとられています。ImportMapについて学びましょう!

ImportMapとは

ImportMapとは、import句でモジュールを取得する際の取得先URLを制御する仕組みです。
webpackやrollupなどのバンドラーを使用せずにESModuleを読み込むことのできるブラウザ環境で使用します。

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

バンドラーを使用しない環境では上記のような記載をした場合エラーをスローします。それを回避するにはURLを指定する必要があるでしょう。

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

そこでImportMapを提供することで、モジュール名を指定するだけでどこから取得すべきかをマッピングすることができます。

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

参考:WICG/import-maps

Rails7におけるImportMapの利用

Rails7ではconfig/importmap.rbの設定ファイルを介してImportMapの設定を行います。

Rails.application.importmap do
end

ImportMapはjavascript_importmap_tagsヘルパーを介して<head>タグに挿入されます。

<%= javascript_importmap_tags%>

これにより、application.jsなどのjavascriptからモジュールを参照できるようになります。application.jsもまた、この方法を使ってインポートされます。

ESModule非対応ブラウザの場合

Rails7ではes-module-shimsをインポートします。これによりESModule非対応ブラウザの場合でも動作が保証されます。

Rails7でのimportmapの使い方

インストールコマンドでimportmapを使う準備を行います。

$ ./bin/rails importmap:install

Add Importmap include tags in application layout
      insert  app/views/layouts/application.html.erb
Create application.js module as entrypoint
      create  app/javascript/application.js
Ensure JavaScript files are in the Sprocket manifest
      append  app/assets/config/manifest.js
Configure importmap paths in config/importmap.rb
      create  config/importmap.rb
Copying binstub
      create  bin/importmap

例えばvueを使いたい場合、importmap pinコマンドでマッピングします。自動的に2.6.14がマッピングされました。

$ ./bin/importmap pin vue

Pinning "vue" to https://ga.jspm.io/npm:vue@2.6.14/dist/vue.runtime.esm.js

しかし、自動でマッピングされるvueはブラウザでは動作しないものでしたので、browser esm互換のものへ手動で書き換えました。

pin "application"
pin "vue", to: "https://ga.jspm.io/npm:vue@2.6.14/dist/dist/vue.esm.browser.js"

実際に動かしてみる。

import Vue from 'vue'
var vm = new Vue({
  el: '#example',
  data: {
    domain: 'HAZM.JP'
  }
})
<div id="example">
  <h1>{{domain}}</h1>
</div>

出力結果

Image

importmapがhead内に提供され、vueがマッピングされた場所からインポートされたこと、そして動作を確認できました。

まとめ

HTTP/2とES6がほとんどのブラウザで標準サポートされるようになった現代では、トランスパイルをせずともあらゆるJSを動作させることができました。importma