あしたのチーム Tech Blog

はたらくすべての人に「ワクワク」を届けるべく、日々奮闘するエンジニアの日常をお伝えします。

CoffeeScript/Slimにもvue-migration-helperを使いたいんやー

大庭です。

下記のVue.js 2系へのアップデートでも触れましたが、Vue.jsの1系から2系へのアップグレードの補助ツールとしてvue-migration-helperがあります。

Vue.jsを2系にバージョンアップしました 🎉 - あしたのチームエンジニアブログ

CoffeeScriptに対して

まあ、これは想像に難くないでしょう。
assets:precompileをしてCoffeeScriptJavascriptに変換したものにvue-migration-helperを実行すればチェックが可能です。

ただ、そのままだと1ファイルにまとめられてしまい、どのファイルが対象か一目でわかりづらいので下記のようにしてvue.jsの関係しそうなファイルを1つずつprecompileされるようにしました。

[config/initializers/assets.rb]
Rails.application.config.assets.precompile += %w(view_models/*.js components/*.js directives/*.js filters/*.js mixins/*js)

CoffeeScriptはこれでバッチリです 😄

Slimに対して

SlimやRailsのviewヘルパーで書かれているものについては、vue-migration-helperのチェック率が悪いので、どうにかしてHTMLに変換されたものにチェックをかけたいです。

そこで、まずfeature specの各stepの最後にcapybaraのsave_htmlの機能を使ってHTMLファイルを保存し、それにvue-migration-helperを実行すればいいのでは?と考えました。

[spec/rails_helper.rb]
config.after(type: :feature) do
  page.save_page
end

しかし、これだと上手くいきませんでした 😢

というのも、この方法だとvue.jsが実行された後のv-forなどがなくなった素のHTMLになってしまい、vue-migration-helperでは何も引っかかりません 😅

なので、vue.jsが実行される前のv-forなどが入った状態のHTMLファイルをなんとか取得する必要があります。

Railsでrenderが行われた後のHTML文字列を取得できないものかと色々調べていると、response.bodyで取れることが分かりました。

そこで、application_controller.rbに下記のようにafter_actionでresponse.bodyをファイルに出力するようにしてみました。

after_action: html_save

def html_save
  File.open("#{Rails.root}/public/convert_html/#{params[:controller].gsub('/', '_')}-#{params[:action]}-#{Time.current.strftime('%Y%m%d%h%M%S%L')}.html", 'w') {|f| f.write(response.body) }
end
※ファイルの出力先はtmpとかだとvue-migration-helperがチェックしないので注意

これだと、v-forなどが残った状態なのでvue-migration-helperでちゃんとチェックすることができます。


ただ、このままだと部分テンプレートを多用しているとどのファイルかがわかりづらいですし、Slimから変換されたHTMLも見にくいので下記の設定と r7kamura/view_source_mapのgemを入れます。

[config/initializers/slim.rb]

Slim::Engine.options[:pretty] = true # HTMLを綺麗にインデント

[Gemfile]
gem 'view_source_map'

これで実際に画面を動かすなり、spec動かすなりすればファイルが出力されるので、それに対してvue-migration-helperを実行すればチェックが可能になります 💪🏻
※testモードの場合はview_source_mapが実行されないのでローカルでgemをちょっといじりました

終わりに

CoffeeScript/Slimにもvue-migration-helperを使えるようにしてみましたが、もっとスマートなやり方を知っている/思いついた方は教えてくだい!
なんならついでにお話ししませんか?