Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tbbooher/16f875e8d36eaf19a2000984fcc96900 to your computer and use it in GitHub Desktop.
Save tbbooher/16f875e8d36eaf19a2000984fcc96900 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Tim Booher">
<title>Improvement.Rocks</title>
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>
<%= javascript_include_tag 'https://www.google.com/jsapi' %>
<%= javascript_include_tag 'https://www.gstatic.com/charts/loader.js' %>
<%= javascript_importmap_tags %>
<%= csrf_meta_tags %>
</head>
<body id="page-top" class="index">
<!-- Navigation -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#page-top">The Improvement Project</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<%= render 'layouts/navigation_links' %>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
<!-- Header -->
<main role="main">
<%= yield %>
</main>
<!-- Footer -->
<footer class="text-center">
<div class="footer-above">
<div class="container">
<div class="row">
<div class="footer-col col-md-8">
<h3>Site is in development</h3>
<p>The site is improving daily. The current focus is on the user experience and the analytical engine.</p>
</div>
<div class="footer-col col-md-4">
<h3>About The Improvement Project</h3>
<p>
Few things are as important as your life system. This is how you track, observe and understand
the nature and direction of your life. We, a busy set of professionals, are looking to build
that system together. We are experts in computer security, AI and psychology. As life provides
challenges and opportunities, we update the system.
</p>
</div>
</div>
</div>
</div>
<div class="footer-below">
<div class="container">
<div class="row">
<div class="col-lg-12">
Copyright 2023 © Improvement.rocks
</div>
</div>
</div>
</div>
</footer>
<!-- Scroll to Top Button (Only visible on small and extra-small screen sizes) -->
<div class="scroll-top page-scroll visible-xs visible-sm">
<a class="btn btn-primary" href="#page-top">
<i class="fa fa-chevron-up"></i>
</a>
</div>
<% unless flash.empty? %>
<script type="text/javascript">
<% flash.each do |f| %>
<% type = f[0].gsub('alert', 'error').gsub('notice', 'info') %>
toastr['<%= type %>']('<%= f[1] %>');
<% end %>
</script>
<% end %>
</body>
</html>
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded any time
# it changes. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable server timing
config.server_timing = true
# we need to add hosts
config.hosts << "improvement.rocks"
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join("tmp/caching-dev.txt").exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise exceptions for disallowed deprecations.
config.active_support.disallowed_deprecation = :raise
# Tell Active Support which deprecation messages to disallow.
config.active_support.disallowed_deprecation_warnings = []
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Suppress logger output for asset requests.
#config.assets.quiet = true
# Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true
# Ensure public file server serves assets from the builds directory
config.public_file_server.enabled = true
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{1.hour.to_i}"
}
# Uncomment this if you see 'stylesheets/application.css' in logs
# config.assets.prefix = "/builds"
end
//= link_tree ../images
//= link_tree ../builds
{
"name": "app",
"scripts": {
"build:css": "yarn build:css:compile && yarn build:css:prefix",
"build:css:compile": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules",
"build:css:prefix": "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css",
"watch:css": "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \"yarn build:css\"",
"build:js": "esbuild app/javascript/application.js --bundle --outfile=app/assets/builds/application.js"
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"autoprefixer": "^10.4.19",
"bootstrap": "5.1.3",
"bootstrap-icons": "^1.11.3",
"nodemon": "^3.1.4",
"postcss": "^8.4.39",
"postcss-cli": "^11.0.0",
"sass": "^1.77.6",
"esbuild": "^0.14.0"
},
"browserslist": [
"defaults"
],
"packageManager": "yarn@4.3.1"
}

Rails 7 with Import Maps and CSS Bundling: Assets Not Served from /builds Directory

I'm working on a Rails 7 application where I'm using Import Maps for JavaScript and CSS Bundling via Yarn instead of Sprockets. Despite following the setup instructions, my assets aren't being served correctly from the /builds directory.

Issue:

When loading my homepage, the CSS file is not found, and I get the following error in the browser console:

Failed to load resource: the server responded with a status of 500 (Internal Server Error)
Request URL: http://localhost:3000/stylesheets/application.css

The rendered HTML for the home page includes:

<link rel="stylesheet" href="/stylesheets/application.css" media="all" data-turbo-track="reload">

However, my CSS file is located at /app/assets/builds/application.css.

Setup:

  • Rails Version: 7.1.3.4
  • Ruby Version: 3.2.2
  • CSS Bundling: Using Yarn scripts for compiling SCSS files
  • JavaScript: Using Import Maps

Directory Structure:

app/assets
├── builds
│   └── application.css
├── config
│   └── manifest.js
├── stylesheets
│   ├── application.bootstrap.scss
│   ├── application.scss

Config Files:

config/environments/development.rb:

Rails.application.configure do
  config.cache_classes = false
  config.eager_load = false
  config.consider_all_requests_local = true
  config.server_timing = true
  config.hosts << "improvement.rocks"

  if Rails.root.join("tmp/caching-dev.txt").exist?
    config.action_controller.perform_caching = true
    config.action_controller.enable_fragment_cache_logging = true
    config.cache_store = :memory_store
    config.public_file_server.headers = {
      "Cache-Control" => "public, max-age=#{2.days.to_i}"
    }
  else
    config.action_controller.perform_caching = false
    config.cache_store = :null_store
  end

  config.active_storage.service = :local
  config.action_mailer.raise_delivery_errors = false
  config.action_mailer.perform_caching = false
  config.active_support.deprecation = :log
  config.active_support.disallowed_deprecation = :raise
  config.active_support.disallowed_deprecation_warnings = []
  config.active_record.migration_error = :page_load
  config.active_record.verbose_query_logs = true

  config.public_file_server.enabled = true
  config.public_file_server.headers = {
    'Cache-Control' => "public, max-age=#{1.hour.to_i}"
  }
end

app/assets/config/manifest.js:

//= link_tree ../images
//= link_tree ../builds

app/views/layouts/application.html.erb:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Improvement.Rocks</title>
    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet">
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>
    <%= javascript_importmap_tags %>
    <%= csrf_meta_tags %>
  </head>
  <body>
    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header page-scroll">
          <a class="navbar-brand" href="#page-top">The Improvement Project</a>
        </div>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav navbar-right">
            <%= render 'layouts/navigation_links' %>
          </ul>
        </div>
      </div>
    </nav>
    <main role="main">
      <%= yield %>
    </main>
  </body>
</html>

Steps Taken:

  1. Ensured that application.css is generated in the /builds directory using the following Yarn script:

    "scripts": {
      "build:css": "yarn build:css:compile && yarn build:css:prefix",
      "build:css:compile": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules",
      "build:css:prefix": "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css",
      "watch:css": "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec "yarn build:css"",
      "build:js": "esbuild app/javascript/application.js --bundle --outfile=app/assets/builds/application.js"
    }
  2. Added public file server configuration in development.rb.

What I Need:

I need help understanding why the assets are not being served from the /builds directory and why the generated HTML still references /stylesheets/application.css instead of /builds/application.css.

Any advice or pointers to resolve this issue would be greatly appreciated!

Tags: ruby-on-rails, css, importmaps, yarn, rails-7, webpack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment