個人のアプリケーションを今まではデフォルトのアセットまわり(CSS等)をSprockets
、JavaScriptをWebpacker
でビルドするような形にしてたのですが、
今回はstylesheetをWebpacker
で管理するようにしたので、そのへんの手順をメモしておきます📝
対応したアプリケーションのRailsのバージョンは6.0.3.2
、Webpackerのバージョンは5.1.1
です。
.css
ファイルをWebpacker
で管理する
今回は.css
(.scss
)ファイルをWebpacker
で管理するための手順をまとめていきます。
assets
配下の.css
ファイルをjavascript
配下に移動
まずはSproketsで管理しているapp/assets
配下の.css
ファイルをWebpackerで管理するためにapp/javascript
配下に移動します。
※webpacker.yml
でentryまわりの変更している場合は、その設定に従って移動先を指定してください。
今回はWebpackerの公式のドキュメントがapp/javascript/stylesheets
配下においてそうだったので、そこに移動するようにしました🙋
# https://github.com/rails/webpacker/blob/master/docs/css.md
app/
javascript/
stylesheets/
application.scss
posts.scss
comments.scss
entryの.js
で.css
ファイルをimportしてWebapckerのビルド対象にする
Webpacker(Webpack)はentryでimportされたファイルをビルド対象とするので必要な.css
ファイルを
entryの.js
(デフォルトだとapp/javascript/packs
配下のjs)でimportしてあげます。
※Webpackerはデフォルトでsass-loader
、css-loader
等がinstallされて設定もよしなにしてくれるようです。
// app/javascript/application.js import '../stylesheets/application.scss'
Webpacker v5
からはpacks
配下にentryのjsと同名のcssを配置すると自動でimportしてくれるようになったようです、便利✨
By Webpacker convention (as of Webpacker v5), this will bundle application.js and application.scss as part of the same entry point (also described as a multi-file entry point in the webpack docs). https://github.com/rails/webpacker/blob/master/docs/css.md#importing-css-as-a-multi-file-pack-webpacker-v5
これでbin/webpack
時にimportしたcssファイルがビルドされて読み込まれるようになりました🙌
しかしデフォルトだとhead
内に直接ビルドされたstyleが記述されてしまいます。
styleが比較的軽量な場合は問題ないのですが、S3から.css
ファイルを配信するため別ファイルで出力したいケースは多いかと思います。
.css
ファイルを個別のファイルとしてビルドするようにする
Webpackerにはmini-css-extract-plugin
を使用してimportしたファイルを個別ファイルで出力する機能が提供されています。
使用するためにはwebapcker.yml
のextract_css
をtrue
に設定することで.css
ファイルを個別のファイルとして出力することができます。
default: &default # Extract and emit a css file extract_css: true development: &default # Extract and emit a css file extract_css: true // その他環境でも必要に応じて同様に設定
Viewでビルドされた.css
ファイルを読み込む
個別に出力された.css
ファイルはjavascript_pack_tag
と同様にView側の読み込む必要があります。
cssの場合はstylesheet_pack_tag
を使って読み込みを行います。
<%= stylesheet_pack_tag 'application' %>
これで.css
ファイルをWebapckerでビルドして個別ファイルに出力し、それをView側で読み込むことができるようになりました🎉
おまけ:eslintの対象からCSSまわりを除外する
package.json
のlintまわりの設定を下記のような形にしていたのですが、javascript
配下のcssがeslintの対象となってしまい。。。🤔
"scripts": { "lint": "eslint app/javascript/**/* --ext .vue,.js,.ts", "lint-fix": "eslint app/javascript/**/* --ext .vue,.js,.ts --fix",
色々調べてみたところ--ext
オプションがファイル指定の場合に効かないようで、、、eslintignore
で指定するようにしたのですが、
app/javascript/stylesheets
Note: --ext is only used when the arguments are directories. If you use glob patterns or file names, then --ext is ignored. https://eslint.org/docs/user-guide/command-line-interface#ext
これでは、eslintがeslintignore
と実行時の指定のどちらを優先すればいいかわからず、warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override.
の警告が発生してしまいます😢
If you pass a specific file to ESLint, then you will see a warning indicating that the file was skipped. https://eslint.org/docs/user-guide/configuring#ignored-file-warnings
最終的には下記のようなディレクトリ指定にして--ext
オプションが効くようにして対応しました🙇♂️
"scripts": { "lint": "eslint app/javascript --ext .vue,.js,.ts", "lint-fix": "eslint app/javascript --ext .vue,.js,.ts --fix",
おまけ: Sproketsの無効化
アセットまわりもWebpackerでビルドするようにするとSproketsはもう必要ないので無効化してあげると依存gemも減らせていい感じです。
※ちなみに新規にアプリケーションを作る場合は--skip-sprokets
を指定してrails new
すればOKなので楽です👌
Sproketsのrequireをやめる
application.rb
でrequire 'rails/all'
をしているとsprockets/railtie
もrequire
されてしまうので、
%w( #... sprockets/railtie ).each do |railtie| begin require railtie # https://github.com/rails/rails/blob/6-0-stable/railties/lib/rails/all.rb#L18
sprockets/railtie
を除いて個別にrequireするようにします。
require 'active_record/railtie' require 'active_storage/engine' require 'action_controller/railtie' require 'action_view/railtie' require 'action_mailer/railtie' require 'active_job/railtie' require 'action_cable/engine' require 'action_mailbox/engine' require 'action_text/engine' require 'rails/test_unit/railtie'
config系のファイルからassetsまわりの設定値を削除する
その後config/enviroments
配下の各ファイルからconfig.assets
関係の設定を削除していきます。
各設定値の詳細はこちら
(config.assets.enabled
をfalse
にしといた方がいいのかな?🤔)
私の個人アプリだとこの辺の設定を削除しました。
# config/environments/development.rb config.assets.debug = true # 削除 config.assets.quiet = true # 削除 # config/environments/production.rb config.assets.compile = false # 削除
そして、config/initializers/assets.rb
も削除します。
sass-rails
をGemfileから削除する
最後にGemfile
からsass-rails
を削除してbundle install
します。※uglifier
等も残っていたら削除します。
gem 'sass-rails', '>= 6' # 削除
これでSproketsも無効化できました🎉
おわりに
今回はstyleまわりを例にAssets PipelineからWebpakerに移行する手順をちょっと整理してみました。(今回行ったのは.css
だけだったのでシンプルでしたが、実際の案件ではこんなにすんなりはいかなさそう。。。)
Webpack移行の前段としてSproketsとの併用をやめて、Webpacker単体の環境に移行しておくと移行対象が減るので、いいかもですね👀