ども、@kimihom です。
ActionText の実装をしていて、実際の利用でハマった点をまとめておく。今まで ActionText の記事として2つ書いてあるので、興味があれば読んでみていただけたらと思う。
Webpacker の利用が前提
ActionText を利用する上で完全にハマったポイントだ。Rails 6 に上げた段階で、デフォルトとなった Webpacker については下記記事にあるように調査はした。
今までの AssetPipeline で作り上げてきた Rails 5 の JavaScript コードを、いきなり Webpacker の import
や require
でクラスで分けるのは手間がかかる割に、挙動は何も変わらなくて無意味だなと感じてしまった。てことで Webpacker を使わない選択をした。そうすれば、Rails ディレクトリ内に無駄にファイルがたくさんできずに、平穏な Rails プロジェクトを保ち続けられると思ったからだ。Webpacker を入れたら、以下のようなファイルがバンバン追加されていくのである。
- config/webpack/environment.js
- config/webpacker.yml
- app/javascript/packs/application.js
- babel.config.js
- postcss.config.js
- etc...
てことで AssetPipeline で JavaScript も管理するようにして平和を取り戻したと思ったのだが、ここで表題にあるように ActionText の利用は Webpacker の利用が前提となっているということに ActionText を本格的に使うようになって初めて気づいた。
ActionText を使うときに、app/javascript/packs/application.js
に以下の記述をする前提となっている。
require("trix") require("@rails/actiontext")
この @rails/actiontext
を AssetPipeline で同様に記述することが不可能だった。
// NG! //= require @rails/actiontext //= require_tree . // => Uncaught SyntaxError: Cannot use import statement outside a module
ActionText のソースを見ると、"@rails/activestorage" から import する処理が書かれており、actiontext
自体で独立した JavaScript ファイルが存在せず、AssetPipeline では実現できないようだった。
rails/attachment_upload.js at master · rails/rails · GitHub
なお、ActionText さえ使わなければ、他の rails-ujs
や turbolinks
は 独立したライブラリのため、 AssetPipeline でも問題なく利用できる。
てことで最終的には ライブラリ系のロードは Webpacker を使い、それ以外の今まで利用していた JavaScript は AssetPipeline を使うという二重の利用方法で落ち着いている。もちろん、これが最適解だとは決して思っていないが、現状はこれがベストだと考えている。つまりヘッダは以下の通りである。
<%= stylesheet_link_tag 'application', media: 'all' %> <%= javascript_pack_tag 'application' %> <%= javascript_include_tag 'application' %>
終わりに
今回は ActionText と AssetPipeline の相性の悪さについて書いた。私が調査した中ではの話なので、もし ActionText を AssetPipeline で使う方法があれば教えていただけたら有難い。とはいえ今後の Rails の風潮としては Webpack 側に寄っていくような感じもあるので、今の JavaScript コードを Webpacker の方で正しく動くようにコードを整備する方が正しい流れなのかもしれない。 もし今後 CSS や 画像なども 基本 Webpacker で入れるのが Rails のデフォルト動作になれば、そのように従っていく予定だ。
最高のユーザー体験を提供するために、ActionText の理想的な利用をこれからも追い続けよう。