Rails5以前では、JSの格納ファイルは app/assets/javascriptでした。
Rails6からは、app/javascriptに格納していくこととなります。
と言いますのも、Rails6からは、デフォルトのJSの管理ツールがSprocketsからWebpackerに変更されたからです。
Webpackerってなに??
Webpackerとは、webpackをRailsで扱いやすくするためのラッパーです。
まぁつまり、webpackという既存のツールをRailsで使いやすくするためのツールという理解で良いです。
じゃあwebpackってなんやねんという話です。
wbpackってなに??
wbpackとは、JSをはじめとしたモジュールファイルのバンドラーです。
まぁつまり、複数のJSファイルを1ファイルにまとめてくれたりするツールです。
ただまとめるだけじゃあありません。
プラグインを入れることで、SaaSをCSSに変換してくれたりなど、
フロントエンド開発に使用するファイルを、良い感じに管理してくれるものです。
今現在、フロントエンド開発ツールのデファクトスタンダードになっています。
これを、Railsでも使えるようにしようや、というので、Webpackerというツールがあるわけです。
Webpackerはどうやって使うの??
どう読み込んでいるのか
application.html.erbを見てみてください。
javascriptを読み込む用に、以下のタグが書かれているはずです。
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
これは、app/javascript/packs/application.jsを読み込みますよ〜 という記述です。
ちなみに、webpackではなくsprocketを使用していた時は、ちょっと違って、以下のコードになっていました。
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
ではapplication.jsはどうなっているのかといういうと、読み込みたいJSのファイルがrequireで記述されています。
もし、自分で「app/javascript/hoge/index.js」というJSファイルを作成して、それを読み込ませたかったら、
application.jsに以下のように記述すれば良いのですー。
require("hoge")
上記はディレクトリごと読み込ませましたが、どういう粒度で読み込ませるのかは、
プロジェクトによりますので、そのプロジェクトのルールに従うのが良いです。
JSファイルを作成したのに読み込まれない
読み込まれない原因はいくつか考えられます。
単純にファイル名のtypoだったり、パスが違っていたり…。
読み込まれる仕組みという部分に今回はフォーカスを当ててみると、
webpackが読み込むファイルがそもそも作成されていないことも、原因として考えられます。
いや、ちゃんとhoge/index.jsのファイル作ったよ!ほら!
確かに作られています。
ただそれは、人が作ったファイルなだけで、webpackが読み込む用のファイルではないのです。
つまり、作ったファイルはちゃんとコンパイルされていますか?ということです。
コンソールから以下を実行することで、手動でコンパイルを走らせることができます。
bin/rails webpacker:compile
コンパイルが実行されビルドされると、public/packs/js 内に、ファイルが出力されます。
このファイルが成果物なので、もし今回作ったファイルの成果物が出力されていないなら、
コンパイルが通っていないことになりますね!
(ちなみに、出力されたファイルのファイル名に謎の文字列がくっついていたりしますが、それはブラウザによるキャッシュ対策で、フィンガープリントと呼ばれます)
いちいち手動で読み込ませるなんて面倒
そりゃあそうだ。
一応、Webpackerでは、javascript_pack_tagメソッドが実行されたら、対象となるファイルの更新の有無をチェックして、更新されていれば、自動ビルドが走る。
ただ、js更新後に、いちいちアクセスしないと検知しないとビルドされないので、また面倒。
そんな時はこれ…!
wbpack-dev-server!!!
webpack-dev-serverとは、webpackを使って開発しているときに使えるサーバーで、
起動しておくと、webpack管理下のファイルの更新を検知し、すぐにビルドを実行してくれるのだ!
これで面倒から解放される。
以下のコマンドで起動できるよ。
bin/webpack-dev-server
CSSもwebpackerで管理したいのだけども
rils6では、cssや画像はまだsprocketsで管理していますが、
application.jsに、読み込みを記述すれば、webpackerで管理できます。
require("stylesheets/application")
require.context("../images", true)
ちなみに、application.html.erbに、stylesheetのpack tagの記述をするのを忘れないように!(JSも書いてますよ★)
<%= stylesheet_pack_tag "application" %>
cssはsprockets、jsはwebpacker、という風に、sprocketsとwebpackerを併用するのが良いのかは、そのプロジェクトのフロントエンドの要がどのくらいなのか、チーム構成はどうなのかによって、変わってきます。
判断は難しいかもしれないけど、これをきっかけに考えてみてね!
PS. ちなみに、sprocketsやwebpackerなどのアセット系のツールを、アセットパイプラインと総称するよ。