Rails 6: Webpacker+Yarn+Sprocketsを十分理解してJavaScriptを書く: 後編(翻訳)
(前編からの続き)
Rails 6: Webpacker+Yarn+Sprocketsを十分理解してJavaScriptを書く: 前編(翻訳)
今もJavaScriptコードをSprocketsで扱える
Webpackerドキュメントには以下のように書かれています。
(略)Webpackの主要な目的は「アプリのようなJavaScript」であり、画像やCSSのためではなく、ましてやJavaScript Sprinklesのためではない(これらは今後もapp/assetsの下に置ける)。
同ドキュメントより
つまり、ビューで何かJavaScriptを使いたいときや、使う必要に迫られたときは、これまでどおりSprocketsを使えるのです。
app/assets/javascripts
ディレクトリを作成する(複数形の"javascripts"になっていることに注意)app/assets/config/manifest.js
を上に合わせて更新する(//= link_directory ../javascripts .js
)- ビューに
javascript_include_tag
を書いて、Sprockets用JavaScriptファイルをインクルードする(以下の違いに注意)- Sprockets用は
javascript_include_tag
- Webpacker用は
javascript_pack_tag
- Sprockets用は
- 後は好きにやる
個人的にはこの手段をできる限り避けるようにしていますが、このことは知っておく価値があります。
原注: manifest.js
とconfig.assets.precompile
の配列は、どちらもコンパイル対象のトップレベルに露出させるという目的は同じなのに、どうしてファイルが2つもあるのかが気になる方もいらっしゃると思います。その目的は後方互換性のためです。Sprocketsのアップグレード手順では、後者をおすすめしていません。
Rails 6アプリケーションでbootstrap 4とfont-awesome 5を追加する手順
本記事をより深く理解いただくために、ここにある手順をそのまま適用することをおすすめします。JavaScriptの知見を深めるのに大いに役に立つでしょう。
1. Rails 6アプリケーションを新規作成する
rails new bloggy
以下にリストしたファイルを見てみましょう。目的は、皆さんにこれらを隅々まで理解してもらうことではなく、こういうファイルが存在するということを皆さんに知ってもらい、そこに何が含まれているのかというぼんやりとしたメンタルイメージを頭の隅に置いて、必要に応じていつでもそこに立ち返ることができるようにすることです。
Yarnのファイル:
- package.json
Webpackerのファイル:
- config/webpacker.yml
- app/javascript/packs/application.js
- app/views/layouts/application.html.erb
Sprocketsのファイル:
- app/assets/config/manifest.json
2. ルートページを追加する
rails generate controller welcome index
ついでにconfig/routes.rb
にroot to: 'welcome#index'
を追記します。
rails server
を実行し、問題なく動作することを確認します。
3. 必要なyarnパッケージを追加する
ここではBootstrap 4(jQueryとpopper.jsが必要です)とfont-awesome 5を追加したいと思います。
訳注(2021/06/10)
元記事はBootstrap 4を前提としていますが、その後Bootstrap 5がリリースされました。Bootstrap 5の場合は以下の手順と異なる部分がありますのでご注意ください。特にjQueryはBootstrap 5で必須でなくなっています。
Yarnパッケージの検索エンジンで、自分に必要なパッケージを検索し(各パッケージのダウンロード数の多さに気づくことでしょう)、このチュートリアルを続行します。
yarn add bootstrap jquery popper.js @fortawesome/fontawesome-free
パッケージがyarnによって./bloggy/node_modules/
にキャッシュされ、package.json
も更新されます。しかしこのままではアプリケーションから利用できませんので対応しましょう。まずはJavaScript部分をインクルードすることにし、CSS部分は後でやることにします。
4. bootstrapとfont-awesomeのJS部分をインクルードする
アプリのレイアウトには既にjavascript_pack_tag 'application'
が置かれています。これは、Webpackにapp/javascript/packs/application.js
のコンパイルを指示してその出力をレイアウトにインクルードします。bootstrapを追加するには、bootstrapをインクルードする専用のpackを別途作成するか、application.js
packを使います。本物のアプリを作るわけではありませんので、ここでは後者をやってみましょう。
以下をapp/javascript/packs/application.js
に追加します。
require("bootstrap");
require("@fortawesome/fontawesome-free");
原注: ここでbootstrap/dist/js/bootstrap.minではなくbootstrapをrequire
していることにご注意ください。その理由は、ファイルパスを指定しない場合はどのファイルをインクルードすべきかという必要な情報をモジュールのpackage.json
(つまりbloggy/node_modules/bootstrap/package.json
)が提供するからです。bootstrap/dist/js/bootstrap.minをrequire
すれば、それはそれで問題なく動くでしょう。
bootstrapとfont-awesomeの設定を続けましょう。Railsサーバーを起動してJavaScriptコンソールを開いてみると、application.jsでjQueryをrequire
していないにもかかわらず、問題なく動作していることを確認できます。
Webpackerを用いてbootstrapをインクルードする方法を他のチュートリアルで学んだ方の中には、他のチュートリアルのほとんどが最初にjQueryをrequire
し、次にbootstrapをrequire
していることに気づいた方もいるかもしれません。これは実際には無意味です。
その理由がわかりますか?私たちはjQueryをyarnでインストールしているので、bootstrap自身がjQueryを自動でrequire
できるのです。jQueryはapplication.jsの中で利用可能な状態になるので、jQueryをapplication.jsでrequire
する必要はありません。すなわち、jQueryをapplication.jsの中で直接使う必要がない限り、実際にはjQueryをapplication.jsでrequire
する必要はありません。
5. bootstrapとfont-awesomeの(S)CSS部分をインクルードする
私はSCSSを使うのが好きなので、bootstrapやfont-awesomeをインクルードする前にapplication.cssをapplication.scssにリネームし、コメントやSprockets用の指示を全部空にします。
続いて以下のコードを貼り付けます。
$fa-font-path: '@fortawesome/fontawesome-free/webfonts';
@import '@fortawesome/fontawesome-free/scss/fontawesome';
@import '@fortawesome/fontawesome-free/scss/regular';
@import '@fortawesome/fontawesome-free/scss/solid';
@import '@fortawesome/fontawesome-free/scss/brands';
@import 'bootstrap/scss/bootstrap';
原注: SprocketsはWebpackと異なり、インクルードするファイルを決定するためにnpmモジュールのpackage.jsonファイルを読み込みません。つまり、名前だけを指定してモジュールをインポートできません。実際にインポートしたいファイル名とそのパスを指定する必要があります(拡張子はあってもなくても構いませんが)。
ついに準備が整いました。
ビューに何かボタンとアイコンを追加して、問題なく動作しているかどうかを確認しましょう。
app/views/welcome/index.html.erbファイルに<a href="#" class="btn btn-primary">Yeah <i class="far fa-thumbs-up"></i></a>
を追加してRailsサーバーを実行し、primaryボタンとアイコンがbootstrapらしく表示されていることを確認します。
jQueryをあらゆるpackで利用する
jQueryのような依存関係を多くのpackで使う必要が生じた場合、それらをpackごとにいちいちrequire
するのは面倒です。私好みのソリューションは、設定を変えて全packで利用可能にすることです(繰り返しますが、あくまでpack内での話であり、ビューでは使えません)。
これを行うには、config/webpack/environment.jsに以下をコピペします。
const { environment } = require('@rails/webpacker')
var webpack = require('webpack');
environment.plugins.append(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
})
)
module.exports = environment
このスニペットによって、WebpackはjQueryモジュールを$
という名前を介して全packに「提供」します。これは、各packの冒頭に以下を追加するのと同等です。
import $ from 'jquery';
お読みいただいた皆さまに感謝いたします。
概要
原著者の許諾を得て翻訳・公開いたします。
タイトルは内容に即したものにしました。画像は元記事からの引用です。
更新情報