All threads / How to use Bootstrap with Webpack & Rails Discussion

Ask A Question

Notifications

You’re not receiving notifications from this thread.

How to use Bootstrap with Webpack & Rails Discussion

Thanks for posting this and the previous video on using tailwindcss. It's helpful to see the main themes reinforced in each of the videos. One thing that I'm struggling with is what seems like a violation of POLS and the Rails-way in general where we are now putting SCSS files inside a javascripts folder. I understand that webpacker can just figure this out for us, but if I'm debugging a styling issue in an app I'm unfamiliar with I'm not sure I'd start by looking in a javascripts folder. Is there not a way to keep the separation of concerns explicit and store the stylesheets outside of the javascripts folder?

The recommended place for stylesheets in Rails 6 is still the asset pipeline. Tailwind is a css framework generated by JS so it needs to be more tied to things than Bootstrap.

This is all just side effects of whats going on in modern frontend. Rails is just trying to make that easier, unfortunately it is pretty messy I think, but its also doing more complex things now.

@Chris Bloom

You can set up webpacker to look in app/assets too. I tend to keep using app/assets/javascripts and app/assets/stylesheets, but app/javascripts for vue/stimulus/… components.

See for example:
https://gist.github.com/risen/076916a3cea81c83cb0752760772d8bf

Hi Chris,

Another concern is the location of custom javascript. I am new to Rails so please excuse my ignorance.
In Rails 5 we would add custom js to their own .coffee files. For Blog model I would write custom js in blog.coffee file and so on.
In Rails 6 all javascript gets added to a single file i.e application.js
How can I keep them seggregated?

Reply

I've created a demo app with Rails 6 + Webpacker + Bootstrap (with CoreUI), no Sprockets https://github.com/jasl/cybros_core

Reply

Hey Chris ,

I'm getting this error:

Webpacker can't find application in /Users/robthomas/Dropbox/rails/sample/public/packs/manifest.json. Possible causes:

  1. You want to set webpacker.yml value of compile to true for your environment unless you are using the webpack -w or the webpack-dev-server.
  2. webpack has not yet re-run to reflect updates.
  3. You have misconfigured Webpacker's config/webpacker.yml file.
  4. Your webpack configuration is not creating a manifest. Your manifest contains: { }

Extracted source (around line #10):


    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

The error is on the

<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

You can run bin/webpack to run webpack and see what the compilation error was.

Did you later find a way to solve this? I have the same issue today.

Reply

I'm getting

error Command "webpack" not found.
Reply

I did and I got this:

yarn install v1.16.0
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.45s.

Reply

Hi there,
What is stylesheet_pack_tag really for in Rails 6? I mean if you import your styles in packs/application.js as done in this episode, webpack doesn't generate any css file. Moreover if you inspect your HTML there is no reference to css file neither.

I have done teh same in a sample app, without including stylesheet_pack_tag and the styles are anyway applied to the view.

This is making me very confused,

The stylesheet pack tag is used for serving stylesheets in production, or in development if you have it configured that way.

@chris any comment on using stylesheet_pack_tag with Hot Module Reloading (hmr)? The README states:

If you have hmr turned to true, then the stylesheetpacktag generates no output, as you will want to configure your styles to be inlined in your JavaScript for hot reloading. During production and testing, the stylesheetpacktag will create the appropriate HTML tags.

From Sigfrid's comment above, I'm guessing we should avoid stylesheet_pack_tag and instead import the css in packs/applications.js.

This article suggests a similar approach:

In order to do so [use hmr], we need to activate it in webpacker.yml
and not import the stylesheets via stylesheetpacktag since they will be included from packs/application.js

However, it seems to me that the suggested solution still uses stylesheet_pack_tag:

# packs/application.js
import './stylesheets'

and

# app/views/layouts/application.html.erb
<%= stylesheet_pack_tag 'stylesheets', 'data-turbolinks-track': 'reload' unless Webpacker.dev_server.hot_module_replacing? %>
Reply

Hi there,

thanks for all of the webpack/rails 6 tutorials. They've been really helpful in upgrading a very old rails app to the latest and greatest.

I'm having one small error however. I have a couple of Bootstrap modal dialogs that get populated via an AJAX request. These POST data to the server, which responds with a JS file with

$('#myModal').modal('hide');

WIth the old asset_pipeline method this worked, but I'm now getting this error:

Uncaught TypeError: $(...).modal is not a function

if I include a jQuery command in the file it's available, but any bootstrap function isn't. Any idea on how to expose all of the Bootstrap functions to the entire application?

Reply

The $(…).modal is not a function is usually caused because scripts are loaded in the wrong order . The browser will execute the scripts in the order it finds them. If in a script you attempt to access an element that hasn't been reached yet then you will get an error. Make sure that you don't have a script above one that it requires.

Plugin dependencies

Some plugins and CSS components depend on other plugins. If you include plugins individually, make sure to check for these dependencies in the docs. Also note that all plugins depend on jQuery (this means jQuery must be included before the plugin files).

Multiple jQuery instances

Sometimes this warning may also be shown if jQuery is declared more than once in your code. The second jQuery declaration prevents bootstrap.js from working correctly. The problem is due to having jQuery instances more than one time. Take care if you are using many files with multiples instance of jQuery. Just leave one instance of jQuery and your code will work.

Thanks for the reply @leneborma

I should have been a little clearer in my explanation. The modal dialog, and all other bootstrap JS (eg tooltips, popovers etc), works well when browsing around the site normally, it's just when I return Javascript from the server after processing the form that appeared in the modal dialog that I get that error.

Step by step:

1) Browse to "New Order Page"
2) Fill in form
3) Click on "Add New Item" button, which opens a modal dialog (via data-behaviour tags) that retrieves a form from the server.
4) Submit the "Add New Item" form. This returns some javascript from the server (via AJAX) which puts a new row on the bottom of the order, and attempts to close the modal dialog. It's at this point that the $('#myModal').modal('hide'); causes an error.

So, I'm not sure why it works at the start, and then stops working when processing the Javascript from the server. The jQuery that adds the new row works, but the modal command fails. There's nothing in the Javascript from the server that reloads the jQuery, so I'm not sure if it's Turbolinks being weird, or if it's something altogether.

Thanks.

Hey, same issue here, did you find anything out?

Thanks.

Reply

Find the solution in the @Jun Jiang repo cybros_core.
We need to expose jQuery to the window object :

# packs/application.js

import JQuery from 'jquery';
window.$ = window.JQuery = JQuery;
Reply

Why HTML rendering faster instead css/js on this tutorial? Can they explain to me, thank you

Reply

Chris thanks for the tutorial.

I've noticed though in a comment you mentioned its still best to use css inside assets/stylesheets.

However with this in place you can't use mixins.
If my style sheet is in javascript/stylesheets the mixin has no problems

When i add @import "../node_modules/bootstrap/scss/bootstrap"; to my stylesheet inside assets stylesheets, the mixins work but thats making webpack redundant so im at a loss.

Doesnt this completely make the asset pipeline redundent or am i missing something ??

You should be able to use mixins in the asset pipeline, as long as your filename ends in .scss so it gets processed with scss.

It won't hurt to use Webpacker for everything. In fact, you need to in some cases like when you're using TailwindCSS.

Images don't really need to go through it since they don't need to be preprocessed and if you have simpler CSS, then the asset pipeline is still around for that.

Thanks for the reply.

I can use mixins if i import bootstrap into a .scss stylesheet inside of assets/stylesheets.

If i use the setup in the video then i can use bootstrap javascript but mixins are not available inside .scss assets/stylesheets. They are only available in javascript/stylesheets.

I thought it may be some error on my side but after trying three different fresh rails projects all had the same outcome


h1 {
color: white;
}
@include media-breakpoint-only(xs) {
h1 {
margin-top: 500px;
}
}

Thats the simple scss im using.
I'll stick to using webpack then for stylesheets. If its all loaded using yarn doesnt make sense to add it another way just for styling.

adding the below into asset pipeline stylesheet fixes the mixin problem though.

@import "../node_modules/bootstrap/scss/bootstrap";

I might just remove the asset pipeline all together seeing as though im not going to use it at all and webpack can handle images too.

Reply

Chris,

I followed your instructions, and everything works well except when a view is rendered from an action of a controller that does not inherit from ApplicationController. If the controller inherits directly from ActionController::Base, the view is not styled by bootstrap.

What's the deal with that? Any insight you can offer would be greatly appreciated!

Does it render a different layout? And if so, have you included the stylesheet tag in that layout?

Chris, thanks for the qick reply!

Your comment about "layout" inspired me to read the docs and now I understand how controllers decide what layout to use. Inserting layout "application" in the controller inheriting from ActionController::Base fixed the issue. I now understand too that I could have made a sperate layout with the same name as the controller, or its parent, and put the stylesheet tag in it, and all would work as expected.

Appreciate your help! Keep up the great work!

Reply

Hey Chris,

I'm getting the following output when trying to deploy to Heroku:

2019-12-06T07:10:10.191890+00:00 app[web.1]: * Environment: production
2019-12-06T07:10:13.694812+00:00 heroku[web.1]: State changed from starting to crashed
2019-12-06T07:10:13.476484+00:00 app[web.1]: ! Unable to load application: NoMethodError: undefined method `stylesheets' for Rails:Module
2019-12-06T07:10:13.476614+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.6.0/bin/puma)
2019-12-06T07:10:13.476667+00:00 app[web.1]: NoMethodError: undefined method `stylesheets' for Rails:Module

Since I'm a Rails newbie I'm not sure exactly what this means or what to do. The URL for my app on Heroku is here: https://limitless-basin-97153.herokuapp.com/

And my app on Github is here: https://github.com/raybullard/ruby-rails-tutorial

Have you seen these errors before? Any and all help is appreciated!

Thanks,

Ray

Reply

doesnt work on rails 6.0.2.rc1 any advice?

Sounds like you probably missed a step somewhere. I just installed Rails 6.0.2.rc1 and went through the screencast. Everything works correctly.

Reply

Hi Chris,
I did yarn add bootstrap jquery popper.js and import bootstrap into the app.
Also, bootstrap's popover and tooltip style works well.
But when I add a toast in page and run $('div.toast').toast('show') in chrome's console, it says $(...).toast is not a function
Do you know what's wrong?

Sounds like you missed a step. I just updated the repository to include toasts in the example and they work just fine.

https://github.com/gorails-screencasts/bootstap-with-webpack-4/commit/49846a028f0d6674b0024fbd4c1f6051c8757884

Compare your code with the repository and see what you missed.

Hi Chris,
thanks for your reply.
I just recreate a rails project, add bootstrap and config everything follow your video. And when I put a toast html block in page, it did show.
but when I run $('#toast').toast('hide') in browser's console, it still warning

Uncaught TypeError: $(...).toast is not a function
at <anonymous>:1:13

is there any thing wrong about how I use toast() function.

Reply

Hi Chris,

thanks so much for this tutorial! :-)
I've been able to follow the process and setup a rails app, that's working like a charm in "development".
When I'm trying to change to "production" with:
export RAILS_ENV=production
rake assets:precompile
rails s
I'm always ending up with my content getting served with no CSS/Bootstrap.
I assume, I'm missing a (few) step(s) when moving to production.
Any hint appreciated! Thanks in advance!

Reply

I can`t even imagine that to find info you need for disertation could be so difficult. But I found that information, so that is why I will share with you http://bestresearchpaper.com (the service which can edit your dissertations and make it perfect). Hope there are students and that help you.

Reply
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 34,885+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.