概要

久しぶりに、Ruby on RailsでWebアプリケーションを作成しています。

Rails 7.0からimportmap-railsという名前のパッケージを利用して、JavaScriptを利用しているのですが、こちらについてReactとの相性が微妙ということがわかりました。

ここでは、なぜReactを利用するときにimportmap-railsが微妙なのかについて書きました。

環境

  • Ruby on Rails 7.0.2.3
  • importmap-rails 1.0.3

importmap-railsについて

importmap-railsは、RailsでJavaScriptを扱うための方法を提供するRubyのGemです。そのため、主にRubyのコードでできており、これを利用することで、Rails上からJavaScriptのファイルを配信して、ブラウザで実行することができます。

GitHub - rails/importmap-rails: Use ESM with importmap to manage modern JavaScript in Rails without transpiling or bundling.

Rails 7.0からimportmap-railsは提供されるようになったのですが、その前のRailsでは、SprocketsやWebpackerなどの別のツールを用いてJavaScriptのファイルをブラウザに提供していました。これらのツールでは、昨今のJavaScriptの実行環境へ適応するために、外部のJavaScriptファイルをバンドルしたり、古いブラウザへ対応するために、トランスパイルを行ったりと、ビルド機能がありました。これは、とても便利なことではあるのですが、特にWebpakcerは内部でWebpackを使っているため、Node.jsの環境が必須という難点がありました。

しかし、最近のブラウザでは、トランスパイルを行わずともコードを実行できたり、外部のJavaScriptファイルをブラウザの側でインポートできるようになったりと、今までのビルド環境があまり必要とされなくなりました。

importmap-railsでは、このようなビルド環境は提供せず、ブラウザの機能を用いて、ファイルの依存関係を解決しようとします。つまり、Railsの利用時にNode.jsの環境がいらなくなります。

importmap-railsを使って気づいたこと

私は、RailsでWebアプリケーションを作る際に、JavaScriptのライブラリとしてReactを利用しました。しかし、このReactを利用していて気づいたことがありました。

それは、ReactでHTMLを生成する際に便利なJSXが使えないということです。なぜ使えないのかというと、importmap-railsでは、トランスパイルを行いJSXの記述を変換しないためです。

実は、GitHubのプロジェクトのページには、トランスパイルをしないということに書かれています。そのため、JSXが使えないことは分かっていたのですが、実際にコードを書いてみると、JSXがとても便利でやめられないという気持ちになりました。

こちらについて、一応の解決方法、代替方法はあり、htmというライブラリを使う方法があります。

GitHub - developit/htm: Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.

しかし、htmを利用した記法が必ずしもJSXと同じようにコードを書けるわけではないです。そのため、ある程度妥協できるのであれば、おすすめですが、Reactをメインに使っていくのであれば、正直なところ使いにくいです。

このような顛末から、少なくとも私はimportmap-railsを使うのは時期尚早だと思うようになりました。

jsbuilding-railsを使う

Railsでは、importmap-rails以外にも、JavaScriptを利用する方法を提供しています。そのひとつにjsbuilding-railsというGemを使う方法があります。こちらは、Node.jsの環境が必要となりますが、Webpackやesbuildなどのビルド環境を選択でき、それのインストールと一緒に設定まで行います。

GitHub - rails/jsbundling-rails: Bundle and transpile JavaScript in Rails with esbuild, rollup.js, or Webpack.

ビルド環境があるため、ReactにおけるJSXなどの利用が可能です。さらにトランスパイルが可能なため、JavaScriptではなく、TypeScriptを利用することも可能です。

少なくとも、私の利用用途では、importmap-railsよりもjsbuilding-railsの方が合っていました。

さいごに

JSXを利用しない、TypeScriptを利用しないなど、ある程度の割り切りができるのであれば、importmap-railsはNode.jsを利用しないため、とても扱いやすいツールであると思います。

しかし、昨今のTypeScriptを利用するような環境や、大量のJavaScriptコードを書くようなアプリケーションでは、あまり向かないように思います。

あくまでも、JavaScriptがメインでない環境ではimportmap-rails、JavaScriptを大量に書くような時には、jsbuilding-railsと使い分けした方が良さそうです。