@ledsun blog

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

rails ujsを学ぶ

一昔前のRailsではJavaScriptを簡単に使う機能としてrails ujsがありました。 Rails ガイドにも説明があります。

railsguides.jp

「UJS: Unobtrusive(控えめな)JavaScript

主な用途は

www.inodev.jp

  • JSの処理で確認ダイアログとして「マジでログアウトすんのか?」という表示をする
  • JSの処理でログアウトのために「deleteメソッドとして」HTTPのPOSTリクエストをする

なんだかんだ言って、削除ボタンとか確認ダイアログとか簡単に実装できて便利です。

JavaScriptとして動く部分の実装は https://github.com/rails/rails/tree/cfa728478935dc48d9d6e2463dc500ffafee802b/actionview/app/assets/javascripts/rails-ujs/features にあります。 たかだか300行のCoffeeScriptです。 読もうと思えば読めそうです。 今回は読みません。

https://github.com/rails/rails/tree/cfa728478935dc48d9d6e2463dc500ffafee802b/actionview/app/assets/javascripts がプロジェクトのルートです。

npmパッケージを作っているのは、もう少し上の https://github.com/rails/rails/tree/cfa728478935dc48d9d6e2463dc500ffafee802b/actionview です。依存しているGemの定義がactionview.gemspecに書いてあるからだと思います。

ビルドするにはnpm run buildを実行します。 次のように環境を設定します。

git clone git@github.com:rails/rails.git
cd rails
bundle install --without db
cd actionview/

次のようにnpm run buildを実行するとビルドできます。

ledsun@MSI:~/r/actionview[1]►npm run build

> @rails/ujs@7.1.0-alpha build
> bundle exec blade build

Building assets…
[created] lib/assets/compiled/rails-ujs.js
npm notice
npm notice New minor version of npm available! 8.3.0 -> 8.6.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.6.0
npm notice Run npm install -g npm@8.6.0 to update!
npm notice

CoffeeScriptのビルドには GitHub - javan/blade を使っています。

https://github.com/javan/blade/blob/2d6e0ae9ebe4e2b405550d998b9f1bb2d2b4300a/lib/blade/assets/builder.rb#L22

     manifest.compile(logical_paths)

https://github.com/javan/blade/blob/2d6e0ae9ebe4e2b405550d998b9f1bb2d2b4300a/lib/blade/assets/builder.rb#L35-L37

    def manifest
      @manifest ||= Sprockets::Manifest.new(environment.index, compile_path)
    end

結局Sprocketsを呼び出しています。 https://github.com/rails/sprockets/blob/3aa96f7499eb3043eb686d918a308152f658bb53/lib/sprockets/manifest.rb#L161 の辺りですが、Sprocketsは訳わからないっす。

https://github.com/javan/blade/blob/main/blade.gemspec#L27

  spec.add_dependency "coffee-script"

bladeの依存関係にcoffee-script gemが入っています。 なんらかの魔法の力によって、これが呼び出されているのだと思います。 どうせ最終的に GitHub - jashkenas/coffeescript: Unfancy JavaScript が呼ばれると思うので、npm scriptから直接こいつを呼び出しては?みたいな気分になります。