@ledsun blog

無味の味は佳境に入らざればすなわち知れず

Rails 7はESモジュールをどう扱うのか?

www.youtube.com

の手順で作成したRailsアプリケーションの動作を見てみましょう。 このRailsアプリケーションの http://localhost:3000/posts のHTML、特にheadタグを見ます。

f:id:ledsun:20210923091546p:plain
Post一覧画面のheadタグ

なかでも気になるのは次の行です。

<script type="module">import "application"</script>

アプリケーション用のJavaScriptとして読み込まれているのはこれだけです。 しかし、ダウンロードしているJavaScriptファイルはほかにもたくさんあります。

f:id:ledsun:20210923091913p:plain
Post一覧画面で取得するJavaScriptファイル

import "application"

を実行してダウンロードしているJavaScriptのURLは http://localhost:3000/assets/application-a7fd3fc58be844f89656edec1ec73e18f9ab627e54b2aea67a97aad4613b6305.js です。 この変換はどうやって行われているのでしょうか? ここで使われているのがimport mapsです。

<script type="importmap" data-turbo-track="reload">{
  "imports": {
    "application": "/assets/application-a7fd3fc58be844f89656edec1ec73e18f9ab627e54b2aea67a97aad4613b6305.js",
    "@hotwired/turbo-rails": "/assets/turbo-94dc4be4d3faa69556020cfe3ec669a335da7afc2d6dd761ffff2b6b32ce5507.js",
    "@hotwired/stimulus": "/assets/stimulus-1dab13c83984da6c66f781836453a03a48016ed2271eb4f29667c71d51d5babf.js",
    "@hotwired/stimulus-importmap-autoloader": "/assets/stimulus-importmap-autoloader-7366d931317007a1e7e62c8dd8198dbc6d6b438207ff8d8539d06019597bf2f7.js",
    "trix": "/assets/trix-1563ff9c10f74e143b3ded40a8458497eaf2f87a648a5cbbfebdb7dec3447a5e.js",
    "@rails/actiontext": "/assets/actiontext-28c61f5197c204db043317a8f8826a87ab31495b741f854d307ca36122deefce.js",
    "controllers/application": "/assets/controllers/application-0a88d7da94dddbd4b5db3a7e58aba83c761c0de29f578c197e4e41a3a79d014f.js",
    "controllers/hello_controller": "/assets/controllers/hello_controller-2e432c9c8e58ad81938077ebef677e45d3981ac2c5393b0694ca66464a26b7e9.js",
    "controllers": "/assets/controllers/index-f6aa019eef4d0e13975a27efdf6d17ba2c6446417bfcb3139efd889f948a5dfc.js"
  }
}</script>

ブラウザは、この1行目にあるマッピング

"application": "/assets/application-a7fd3fc58be844f89656edec1ec73e18f9ab627e54b2aea67a97aad4613b6305.js",

をみて、applicationモジュールのURLを解決しています。 取得したapplicationモジュールの中身は次のようになっています。

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext";

ここにもimport文があるので、これを使って芋づる式に必要なJavaScriptファイルを取得しています。

showtell\app\javascript\application.jsを見ると

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext"

ダウンロードしたapplicationモジュールとまったく一致しています。

Rails 7では、JavaScriptのimport文で定義されている依存関係をそのままつかって、JavaScriptファイルを取得していることがわかります。 ES2015でJavaScriptimport/export文が定義されました。 その頃は1~2年もすればブラウザが対応して、ESモジュールを定義すればNode.jsでもブラウザでも動かせるユニバーサルなモジュールが定義できると夢見ていました。 それから6年、ついにユニバーサルなモジュールがプロダクション環境のWebアプリケーションで使える日が見えてきました。