importmapを受け入れよう

Rubyという言語、Railsというアプリケーションで長らくWebアプリケーションを作り続けてきた。 今の仕事でも使っている言語だからという愛着もあるのだけれども、JavaScriptの大量にある非同期処理と同期処理を書き分ける開発と比べて取っ付きやすくなった気がする。

そんな状態が長く続いていた。

しかし、フロントエンドとバックエンドをどう組み合わせるか、デプロイはどうするかは永遠の課題でアプリケーションはデプロイし続けてはいたがあまり長続きするものはなかった。 コンパイルは遅いけれども、WebpackでReactとRailsを組み合わせるのが最近になって最適解だったのではないかと思い始めていた。そんな矢先であった。

気づけばWebpackerは死んでいた。

そしてCreate React Appも死んだ。 普段やっているやり方を大きく変えなければならなくなっていた。

そんな闇に颯爽と現れたのはViteだった。Viteは素晴らしかった。 Railsが作ったディレクトリにViteで作ったアプリケーションを組み合わせるのは少々不格好だったが、これはすんなりと機能した。 従来のRailsがバックエンドでReactがフロントエンドをそれぞれ担当している。 今でもこれは私の中でも選択肢のひとつである。 さすがに同一のディレクトリで管理しようとは思わなくなった。

遅かったWebpackerでも開発が心地よく感じられたのはrails serverコマンドを実行すればWebpackerも自動で起動してくれたからだと思う。 1つのファイルを変更しただけで長くて1分近く待たされるけれども、すぐにサーバーを起動できるということは非常に魅力的である。 昔はWebpackerの起動も別に行っていた気がするのだけれども、いつの間にかrails serverだけで済むようになっていた。 ForemanとかOvermindは大げさだし、毎回Dockerfileを作る必要もない。 Dockerが出てきてから開発もデプロイも楽にはなったが、最近はむしろまたローカルマシンにRubyをインストールするようになったし、デプロイするまではsqlite3でテーブルを作っている。 毎回要塞のようなサーバーを作る必要はないのである。

RailsにReactを組み込む方法が全くないわけではない。 しかしjsbundling-railsやvite-railsはうまくいかなかった。 断っておくとこれらのgemが悪いわけではない。 最初にrails newするときですらエラーが発生したりして驚かされるがそれは些細なものである。 これらの方法が私のソリューションには合致しなかった。ただそれだけである。 Railsの起動は唯一railsコマンドであるべきだし、ユーザーに同意なくProcfileを追加したり、devコマンドという抽象的なものであってはならない。 望むらくはこれらのgemがrails serverに統合される時を待つばかりである。

そういう事情があって長らくRails 7を敬遠してきた。 余談ではあるが(最近kamalという名前に変更された)mrskというツールが発表されて間もない頃、私はこのツールをすんなり取り込むことができた。 たとえExpressで書かれた古いプロジェクトですらDockerfileがあれば簡単にデプロイできる。 このように新しいものを取り入れたくないわけではないのである。 せっかくRails 7にアップデートしたにも関わらず、ずっとrails new --minimalコマンドばかりを使っていた。

お世辞にもrails new --minimalで生成されるアプリケーションの開発体験は素晴らしいものとは言いにくい。 単純であるからこそ先述の方法よりはましに感じられたものの、npm installしてnode_modulesディレクトリからCSSとJSファイルを取り出してvendorディレクトリへ放り込むのが実は面倒である。 昔ながらのjQueryを使っていたRailsの時代に後退した気分である。 とはいえ今さらjQueryの開発をする気力もないし、そもそも忘れてしまった。

そうなると必然的に趣味の開発をする気力もなくなってくる。 ある程度まではいいのだが、やっぱりステートに応じてローディングの画像を出したり、プログレスバーやスナックバーを表示したくなってくる。 そうなると先述したViteを無理やりねじ込む方法しか残されていなかったりする。

それはそうとして、今日はまた新しいアプリケーションを作ってみることにした。 最近私のウェブサイトの構成を変えたので、それに合わせたブログとかアプリケーションを作ってみたくなったのだ。 そこで偶然sourcemapを使ってみることにした。 もともとsourcemapはCDNの利用が前提で、インターネット接続が必須でオフラインの開発なんてできないものと勘違いしていた。 sourcemapはvendor/javascriptのディレクトリに含まれているファイルを自動でpinすることができるようだ。 CDNからファイルを拾ってきてはいるようだが、その方法が若干ブラックボックスなので不気味であるからやはり従来のようにNPM経由でインストールするようにはしている。

ちょっと触ってみるとBootstrapのようなCSSやJSのライブラリを使う分にはよい。 私もいずれCDN経由でライブラリを追加することに抵抗がなくなる頃には直接pinを使うようになっているだろう。

しかし残念ながらReactないしJSXとは非常に相性が悪いようだ。 GraphQLのように文字列リテラルで括ってJSXを認識させるhtmというライブラリを使う方法があるのだけれども、試してみようとすら思えなかった。 sourcemapは昨今では当たり前になったスクリプト言語をコンパイルすることがない。 こればかりはViteを使ったほうがよさそうだ。 この背景を知っているとなぜRailsにはわざわざStimulusやTurboといったライブラリが存在している理由や、つい先日投稿されたTurbo 8がTypeScriptをサポートするのをやめたのもなんとなくわかってくる。

一般的なWeb開発ではどんな言語を使っていても基本的にはJavaScriptからは逃れることはできない。 Rails APIではない純粋なRailsアプリケーションにNPMを加えようと試みるとたちまちコンテナは濁ってしまう。 まだsourcemapを使ってデプロイまではしていないのだけれども、実はvendorにファイルをコピーする運用とさして変わりないことに気づいてしまったこととnpmやNode.jsを入れる必要がなければデプロイもいくらか簡単になるはずだ。 Stimulusを使うかどうかはさておき、sourcemapそのものがRailsの正当進化として受け入れる覚悟がようやく出来た。 今後は--minimalをなるべく使わずに新しくなったRailsを徐々に理解していけるような自分でいたい。