Photo by Julian Hochgesang on Unsplash
Rails app is searching for stylesheets in the app/assets/stylesheets directory instead of app/javascript/stylesheets
Situation
When Rails app is running, it incorrectly searches for stylesheets in the app/assets/stylesheets
instead of the intended app/javascript/stylesheets
, resulting in issues with the correct functioning of the stylesheets.
Current configuration
Brief explanation
This situation is likely due to the default asset pipeline configuration.
In Rails 6 and later, JavaScript and stylesheets are often managed differently, with JavaScript using Webpacker and stylesheets using the asset pipeline.
However, if you want to centralize your stylesheets in the app/javascript/stylesheets
directory and use them in your application, you must ensure the following steps.
Check Webpacker installation
Via npm
npm list | grep webpacker
Output
calaca@calaca-PC ~/var/www/edume (courses-initial-configuration)$ npm list | grep webpacker
├── @rails/webpacker@5.4.4
Snapshot
Via bundle
bundle list | grep webpacker
Output
calaca@calaca-PC ~/var/www/edume (courses-initial-configuration)$ bundle list | grep webpacker
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
* webpacker (5.4.4)
Snapshot
Open the webpacker.yml file
The file is located in config/webpacker.yml
.
UPdate the source_path
In config/webpacker.yml
:
# config/webpacker.yml
source_path: app/javascript
You file should look something like the following
# Note: You must restart bin/webpack-dev-server for changes to take effect
default: &default
source_path: app/javascript
source_entry_path: packs
public_root_path: public
public_output_path: packs
cache_path: tmp/cache/webpacker
webpack_compile_output: true
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: []
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
# Extract and emit a css file
extract_css: false
static_assets_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .tiff
- .ico
- .svg
- .eot
- .otf
- .ttf
- .woff
- .woff2
extensions:
- .mjs
- .js
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
development:
<<: *default
compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: false
# Inline should be set to true if using HMR
inline: true
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
pretty: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: '**/node_modules/**'
test:
<<: *default
compile: true
# Compile test packs to a separate directory
public_output_path: packs-test
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true
Snapshot
Restart the Webpacker server
In your terminal emulator:
./bin/webpack-dev-server
Output
Import stylesheets into application.js
In the main javascript file, which is app/javascript/packs/application.js
, add the stylesheets:
# app/javascript/packs/application.js
import "stylesheets/application"
import "stylesheets/courses"
Or with the following syntax:
# app/javascript/packs/application.js
import "../stylesheets/application.scss"
import "../stylesheets/courses.scss"
It'll look something like this:
# 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.
import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import 'bootstrap/dist/js/bootstrap'
import 'bootstrap/dist/css/bootstrap'
import "bootstrap"
import "stylesheets/application"
import "stylesheets/courses"
import "channels"
import "@fortawesome/fontawesome-free/css/all"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
Refact
Create an index file
In app/javascript/stylesheets/
, create a file called index.scss
:
touch app/javascript/stylesheets/index.scss
This file will serve as an entry point for your SCSS imports.
Include all imports
In app/javascript/stylesheets/index.scss
:
@import 'application';
@import 'courses';
Output
Add index to the javascript entry point file
In your JavaScript entry point file, which is app/javascript/packs/application.js
, import the index.scss
file:
# app/javascript/packs/application.js
import 'stylesheets/index.scss';
Snapshot
Check the result
Rails server
View page
Celebrate
You've made it!
Let's become friends
Final thoughts
I hope this article has been helpful to you. Please feel free to reach out if you have any questions. Your thoughts, suggestions, and corrections are more than welcome.
By the way, don't hesitate to drop your suggestions for new blog articles.
I look forward to seeing you next time.