PIYO - Tech & Life -

Railsのjs-routesをWebpackerでも使うには

Rails Webpacker JS

Railsのjs-routesgemはクライアントサイドでURLヘルパーを使えるようにできるgemで、大変便利です。

Gemfileにgem "js-routes"を書いてインストールしたうえで、asset pipelineのapplication.jsあたりでrequire js-routesとしておきます。すると、Rails側で使えるuser_path(@user.id)みたいなヘルパーメソッドがJSでも使えるようになって、↓なふうに使えます。

Routes.user_path(1)

ハードコーディングしなくてよくなるのでなかなか便利です。

ところでこの導入手順ではJSがSprocketsに乗っています。つまりWebpackerのみを使っているプロジェクトではこの方法での導入ができません。

Webpackerで使うには

js-routesgemにはRubyのクラスJsRoutesというのがいます。これがgenerateメソッドとgenerate!メソッドを持っています。

まずはわかりやすい方のgenerate!から。こちらはuser_pathなどの定義を書いたJavaScriptのコードをファイルに書き出すというものです。

generateは、というとJavaScriptのコードを文字列として返すメソッドです。Webpackerではこちらを使うと良いです。

というのはStack Overflowからの受け売りなのですが、実際に試してみました。

How to make it works with webpacker? · Issue #237 · railsware/js-routes · GitHub
Rails 5.2 introduce Webpacker gem which can help you to avoid using Sprockets. Is there any way to make JS-Routes usable with Webpacker?

まずはjs-routesgemを普通にインストールします。

続いてerb-loaderを有効にしておきます。erbを使う方法についてはこちら↓の記事でも書いています。

gemが持ってるJSをwebpackerで読み込むには - PIYO - Tech & Life -
手持ちのレガシー目なRails案件をいい加減Webpackerに直す活動を始めていまして、まずは仕事以外のプロジェクトからやってます。 JS用のgemだったりrails-assetsあたりはyarn化の

Routes用のファイルを用意

Webpackerのエントリポイントのファイルがapp/javascripts/packs/application.jsだったとして、1つ上の階層にjs-routes.js.erbつまり(app/javascripts/js-routes.js.erb)というファイルを作ります。

中身はerbでgenerateの結果がそのままJSになるように書いておきます。

<%= JsRoutes.generate %>

Ruby側のJsRoutesがJavaScriptコードを書き出してくれるので、それをそのままこのjs-routes.js.erbの内容としておくわけです。

Webpackerでimport

あとはメインのファイル(app/javascripts/packs/application.js)にて、このファイルをインポートします。

import Routes from '../js-routes.js.erb'
// 必要に応じてグローバルに
window.Routes = Routes

Webpackerでも使えるようになりました。