環境
Ruby 2.7.1, Rails 6.0.3, PostgreSQL 11
webpacker 5.1.1
Bootstrap 4.5.0, jQuery 3.5.1 (gemを使用せずwebpackerにてインストール)
Docker上のローカル環境
Bootstrapのスタイルは正常に適応されている状態です
問題
BootstrapのModalが正常に動作しない
(CDNからBootstrapをインストールすると正常に動作する)
CDNインストールでお茶を濁しておりましたが、
プロダクション環境では問題ないものの、デプロイ環境ではjQueryがBootstrapよりも先に読み込まれていない旨のエラーが出ており、
根本解決が必要かと思い質問を挙げさせていただきました。
検証
プロダクション環境、modalの動作が期待される場面で
Chromeのコンソールで確認すると
Uncaught TypeError: $(...).modal is not a function...
そこで<head>
タグ内に以下のように記述し、
CDNからインポートを試みるとmodalは正常に動作するようになります。
(jQueryとStylesheetのCDNインポートは不要でした)
html
1 <head> 2 ... 3 <%= stylesheet_pack_tag "application", media: "all", "data-turbolinks-track": "reload" %> 4 <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track": "reload" %> 5 <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> 6 <!-- font awesome --> 7 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" 8 integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous"> 9 <!-- Bootstrap --> 10 <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" 11 integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"> 12 </script> 13 </head>
このことから
- ビューに記載されたスクリプトは適切
- modalのclass, id記述も問題ない
かと考えています。
また上記<head>
内で
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
よりも上の行でBootstrapをCDNからのインポートすると、
同様にChromeのコンソールにて、jQueryに依存しているから先にインストールしてくれとのエラーが生じます
このことからwebpackerでのjQueryのインストールまではうまくいっており
- Bootstrapのインストールがうまく行ってない
- jQuery > Bootstrapの順で呼び出されていない
といった原因なのかと推察しているのですが、
これ以上検証、解決のすべが思い浮かばず質問させていただきました。
長文、お手数ですが後学のためアドバイスをお願いいたします。
ソース
config/webpack/environment.js
javascript
1const { 2 environment 3} = require('@rails/webpacker') 4 5const webpack = require('webpack') 6 7environment.plugins.prepend('Provide', 8 new webpack.ProvidePlugin({ 9 $: 'jquery', 10 jQuery: 'jquery', 11 Popper: ['popper.js', 'default'] 12 }) 13) 14 15module.exports = environment
app/javascript/packs/application.js
javascript
1// This file is automatically compiled by Webpack, along with any other files 2// present in this directory. You're encouraged to place your actual application logic in 3// a relevant structure within app/javascript and only use these pack files to reference 4// that code so it'll be compiled. 5 6require("@rails/ujs").start() 7require("turbolinks").start() 8require("@rails/activestorage").start() 9require("channels") 10require("@fortawesome/fontawesome-free") 11 12import 'bootstrap' 13import 'bootstrap/dist/js/bootstrap'; 14import './bootstrap_custom.js' 15import '../stylesheets/application' 16 17 18 19// Uncomment to copy all static images under ../images to the output folder and reference 20// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) 21// or the `imagePath` JavaScript helper below. 22// 23// const images = require.context('../images', true) 24// const imagePath = (name) => images(name, true)
importの内容は重複していますが、
それぞれ個別に試してもエラーは解消されませんでした
また、以下のサイトを参考に、
import 'bootstrap/js/dist/modal
を含むbootstrap_custom.js
を作成し
Bootstrapのjavascriptを明示的にimportしてみたのですが
これもうまくいかず
How to install bootstrap 4.3 on a Rails 6 app using Webpack | by Guilherme Pejon | Medium
app/javascript/packs/bootstrap_custom.js
javascript
1import 'bootstrap/js/dist/alert' 2import 'bootstrap/js/dist/button' 3import 'bootstrap/js/dist/carousel' 4import 'bootstrap/js/dist/collapse' 5import 'bootstrap/js/dist/dropdown' 6import 'bootstrap/js/dist/index' 7import 'bootstrap/js/dist/modal' 8import 'bootstrap/js/dist/popover' 9import 'bootstrap/js/dist/scrollspy' 10import 'bootstrap/js/dist/tab' 11import 'bootstrap/js/dist/toast' 12import 'bootstrap/js/dist/tooltip' 13import 'bootstrap/js/dist/util'
package.json
json
1{ 2 "name": "myapp", 3 "private": true, 4 "dependencies": { 5 "@fortawesome/fontawesome-free": "^5.13.1", 6 "@rails/actioncable": "^6.0.0", 7 "@rails/activestorage": "^6.0.0", 8 "@rails/ujs": "^6.0.0", 9 "@rails/webpacker": "5.1.1", 10 "bootstrap": "4.5.0", 11 "clipboard": "^2.0.6", 12 "jquery": "^3.5.1", 13 "popper.js": "^1.16.1", 14 "turbolinks": "^5.2.0" 15 }, 16 "version": "0.1.0", 17 "devDependencies": { 18 "webpack-dev-server": "^3.11.0" 19 } 20}
ビュー(.erb)
html
1<script> 2 $(window).on('load', function () { 3 $('#modal_initial').modal(); 4 }); 5</script> 6 7<div class="modal fade" id="modal_initial" tabindex="-1" role="dialog" aria-labelledby="modal_initialCenterTitle" 8 aria-hidden="true" data-backdrop="static"> 9 ... 10</div>
$('#modal_initial').modal();
の部分を$('#modal_initial').show();
や$('#modal_initial.modal').show();
とするとよいなどのアドバイスも海外サイトで見られましたが、いずれも駄目でした
追記
デプロイ環境でのみ、jQueryがないと言われるエラーについては
以下のように変更することで解消しました
config/webpack/environment.js
javascript
1const { 2 environment 3} = require('@rails/webpacker') 4 5const webpack = require('webpack') 6 7#以下'jquery'から'jquery/src/jquery'に変更 8environment.plugins.prepend('Provide', 9 new webpack.ProvidePlugin({ 10 $: 'jquery/src/jquery', 11 jQuery: 'jquery/src/jquery', 12 Popper: ['popper.js', 'default'] 13 }) 14) 15 16module.exports = environment
現状の問題点は
- webpackerで管理しているBootstrapのスタイルは適応されるが、特定のjavascriptが動かない
- <head>内でCDNからBootstrapをインストールすると、前述のjavascriptが動く
対症的解決法はあるのですが、後学のため根本解決のためのアドバイスを引き続きお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/22 01:34
2020/07/22 01:41
2020/07/22 01:59
2020/07/22 02:04
2020/07/22 04:59
2020/07/22 12:50
2020/07/23 00:10
2020/07/23 01:52
2020/07/23 04:41
2020/07/23 05:26
2020/07/29 00:06
2020/07/29 05:06
2020/07/29 07:42
2020/07/29 08:30 編集
2020/07/29 14:31 編集
2020/07/29 16:18