ビューファイル毎に読み込ませるjsファイルを変えたい
ビューファイル毎に読み込ませるjsファイルを変えたい
ビューファイル毎に読み込ませるjsファイルを分ける方法を自分の備忘録として、こちらにまとめます。
Railsでは、アセットパイプラインによりマニフェストファイルからアセット(CSSファイルやJSファイル)をまとめて読み込み、アセットをまとめて読み込んでいるマニフェストファイルをレイアウトファイルで読み込んでいるというロジックになっている為、特定のページでのみで使用するjsファイルも違うページで読み込んでしまい存在しないDOMに対してaddEventListenerなどが実行されてしまい開発者ツール上で以下のようなエラーになってしまう。
これの解決方法としては、ビュー毎に読み込むjsファイルを分ければ良い。
方法は、以下のようになります。
現時点では、以下のようになっています。
app/javascripts
フォルダ以下にそれぞれの機能毎のjsファイルが以下のように存在します。
上記の機能毎のjsファイルを以下のようにマニフェストファイルで読み込んでいる。
[app/javascript/packs/application.js] // This file is automatically compiled by Webpack, along with any other files // present in this directory. You're encouraged to place your actual application logic in // a relevant structure within app/javascript and only use these pack files to reference // that code so it'll be compiled. require('jquery') require("@rails/ujs").start() require("@rails/activestorage").start() require("channels") require('bootstrap') import 'bootstrap'; import '@fortawesome/fontawesome-free/js/all'; import '../javascripts/search_cooking_select_box'; # ここで読み込んでいる import '../javascripts/search_calculate_cooking_time_select_box'; # ここで読み込んでいる import '../javascripts/search_cooking_memory'; # ここで読み込んでいる import '../javascripts/image_preview'; # ここで読み込んでいる window.$ = $; // Uncomment to copy all static images under ../images to the output folder and reference // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) // or the `imagePath` JavaScript helper below. // // const images = require.context('../images', true) // const imagePath = (name) => images(name, true)
上記のマニフェストファイルを以下のようにレイアウトファイルで読み込んでいる。
[app/views/layouts/application.html.slim] doctype html html head title = page_full_title(yield(:title)) = csrf_meta_tags = csp_meta_tag = stylesheet_link_tag 'application', media: 'all' ここでCSSのマニフェストファイルを読み込んでいる = javascript_pack_tag 'application' ここでJava Scriptのマニフェストファイルを読み込んでいる body - if logged_in? = render partial: 'shared/after_login_header' - else = render partial: 'shared/before_login_header' = render partial: 'shared/flash_message' = yield
このような過程で全てのビューファイルで全てのjsファイルが読み込まれてしまっている為、以下のように変更する。
まず以下のようにマニフェストファイルから特定のビューでしか使用しないjsファイルを削除する。
[app/javascript/packs/application.js] // This file is automatically compiled by Webpack, along with any other files // present in this directory. You're encouraged to place your actual application logic in // a relevant structure within app/javascript and only use these pack files to reference // that code so it'll be compiled. require('jquery') require("@rails/ujs").start() require("@rails/activestorage").start() require("channels") require('bootstrap') import 'bootstrap'; import '@fortawesome/fontawesome-free/js/all'; # ここで読み込んでいたビュー毎のjsファイルを削除 window.$ = $; // Uncomment to copy all static images under ../images to the output folder and reference // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) // or the `imagePath` JavaScript helper below. // // const images = require.context('../images', true) // const imagePath = (name) => images(name, true)
レイアウトファイル(app/views/layouts/application.html.slim)からは、そのままマニフェストファイルを読み込むようにする。
[app/javascript/packs]フォルダ以下に以下のように自分でマニフェストファイルを作成する。
以下のように作成したマニフェストファイルからビュー毎に使用するjsファイルを読み込む。
[app/javascript/packs/image_preview.js] import '../javascripts/image_preview';
[app/javascript/packs/search_calculate_cooking_time_select_box.js] import '../javascripts/search_calculate_cooking_time_select_box';
[app/javascript/packs/search_cooking_memory.js] import '../javascripts/search_cooking_memory';
[app/javascript/packs/search_cooking_select_box.js] import '../javascripts/search_cooking_select_box';
※読み込むjsファイルは相対パスで記載する必要がある。
上記のようなマニフェストファイルを以下のようにjsを使用するビューファイル毎で直接読み込むようにする。
[app/views/cooking_informations/index.html.slim] = javascript_pack_tag 'search_cooking_select_box' = content_for(:title, (t '.title')) .search-wrapper .container .row.justify-content-md-center .col-md-10 = search_form_for @q, url: cooking_informations_path do |f| .mt-4 = f.collection_select :fish_kind_eq, @fishes, :kind, :kind, { include_blank: "#{t 'defaults.search_for_fish'}" }, {class: 'search-select-form'} = f.collection_select :handle_pattern_eq, @handles, :pattern, :pattern, { include_blank: "#{t 'defaults.search_for_fish'}" }, {class: 'search-select-form'} = button_tag type: 'submit', class: 'btn btn-primary search-button' do i.fas.fa-search = render @cooking_informations = paginate @cooking_informations
これで使用するビューファイルだけでjsファイルを読み込むようになるため、開発者ツールでもエラーにならなくなる。
参考記事
webpacker でページごとにスタイルを分ける - Qiita
WebpackerでJavaScriptを使ってハマった話 - sasaboの生活
Webpacker::Manifest::MissingEntryErrorの対処法 | ゆみしん夫婦のブログ
Railsで特定のページのみJavaScriptを読み込む方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
Rails6で、アプリの特定のビューでJavaScriptを動かす。 : リア充キラキラ系のnoteです。@kuromitsu_ka
javascript — ビューごとのJavaScriptファイルRails
http://www.code-magagine.com/?p=4609
Railsでページごとのscssを管理する方法 -- blog.10rane.com
Ruby on Rails のアセットパイプラインの挙動を環境ごとに学ぶ - 30歳からのプログラミング
RailsでcssファイルとJavascriptファイルをマニフェストファイルから読み込む | Boys Be Engineer 非エンジニアよ、エンジニアになれ