Rails 7からimportmap-rails
を使ったフロントエンド環境が提供される予定です。
Rails new時にimportmap-rails
を使用するoptionも追加され試しやすかったので、軽く使ってみました。
利用方法とかメモしておきます📝
import mapsとは
簡単にいうと以下のような定義を元に、
<script type="importmap"> { "imports": { "moment": "/node_modules/moment/src/moment.js", "lodash": "/node_modules/lodash-es/lodash.js" } } </script>
以下のようにimportを表現出来る機能なようです。
import moment from "moment"; import { partition } from "lodash";
詳細な説明は以下を参照してください🙇♂️
これによりwebpackのようなbuildツールを使わなくてもimportを利用することが出来るのと、HTTP/2により並列で取得出来るファイル数に制限がなくなった。IE11のEOLも迫りES6が動かないブラウザはほとんど無いということで、importmapを利用した環境を採用し、Railsからnodeの依存を外そうということでimportmap-rails
を使ったフロントエンド環境が候補に上がったようです(?)
importmap-rails
を使ってRailsでimportmapでフロントエンド環境を構築してみる。
今回は簡単なReactのコンポーネントをimport maps
を使ってレンダリング出来るとことまでをやってみようと思います。
importmap-rails
を使うにはrails
のmain
ブランチからinstall後に以下のコマンドを実行することでimportmap-rails
を導入した状態でRails newを行う事ができます🚃
$ rails new --javascript=importmap
Rails newしたあとに以下のコマンドを実行しimportmap-rails
のセットアップを行います。
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 asset pipeline manifest append app/assets/config/manifest.js Configure importmap paths in config/importmap.rb create config/importmap.rb Copying binstub create bin/importmap
importmap-rails
は現状assets:precompile
でbuildしたjsを読み込むような挙動になっているようです👀
install後にbin/importmap pin name
を使ってライブラリのCDNのURLを登録します。
$ bin/importmap pin react-dom Pinning "react-dom" to https://ga.jspm.io/npm:react-dom@17.0.2/index.js Pinning "object-assign" to https://ga.jspm.io/npm:object-assign@4.1.1/index.js Pinning "react" to https://ga.jspm.io/npm:react@17.0.2/index.js Pinning "scheduler" to https://ga.jspm.io/npm:scheduler@0.20.2/index.js
このときのライブラリの名前とCDNのURLの解決は以下が利用されているようです👀
実際に登録されているライブラリはconfig/importmap.rb
で見ることが出来ます📦
pin "application" pin "react", to: "https://ga.jspm.io/npm:react@17.0.2/index.js" pin "object-assign", to: "https://ga.jspm.io/npm:object-assign@4.1.1/index.js" pin "react-dom", to: "https://ga.jspm.io/npm:react-dom@17.0.2/index.js" pin "scheduler", to: "https://ga.jspm.io/npm:scheduler@0.20.2/index.js"
これらの登録したライブラリはjavascript_importmap_tags
で読み込まれます。
<!DOCTYPE html> <html> <head> <title>SampleApp</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_importmap_tags %> </head> <body> <%= yield %> </body> </html>
これでライブラリを登録できたので適当なページを用意してapplicaton.js
にReactのコードを記載してみます。
<h1>TOP</h1> <div id="root"> </div>
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails console.log("application.js"); import ReactDOM from "react-dom"; ReactDOM.render("Hello, world!", document.getElementById("root"));
以下の通りimport-maps
利用したインポートが行われ
<script type="importmap" data-turbo-track="reload">{ "imports": { "application": "/assets/application-e92f8138755b2135e2a621bfbb917dc7f07214686408cf58ca18cf919cf1cc72.js", "react": "https://ga.jspm.io/npm:react@17.0.2/index.js", "object-assign": "https://ga.jspm.io/npm:object-assign@4.1.1/index.js", "react-dom": "https://ga.jspm.io/npm:react-dom@17.0.2/index.js", "scheduler": "https://ga.jspm.io/npm:scheduler@0.20.2/index.js" } }</script> <link rel="modulepreload" href="/assets/application-e92f8138755b2135e2a621bfbb917dc7f07214686408cf58ca18cf919cf1cc72.js"> <link rel="modulepreload" href="https://ga.jspm.io/npm:react@17.0.2/index.js"> <link rel="modulepreload" href="https://ga.jspm.io/npm:object-assign@4.1.1/index.js"> <link rel="modulepreload" href="https://ga.jspm.io/npm:react-dom@17.0.2/index.js"> <link rel="modulepreload" href="https://ga.jspm.io/npm:scheduler@0.20.2/index.js"> <script src="/assets/es-module-shims-c7d42ad90c35e70ec01698a6f481a4eacabafe8c30cae13fa50c7c0d287a1563.js" async="async" data-turbo-track="reload"></script> <script type="module">import "application"</script>
コンポネントも表示されています🎉
おわりに
小規模でJSも少しだけしか使わないケースにはnodeの依存もなくせて、良いかもですね👀