0

My app works perfectly when run in local server but when I deploy it with Heroku it wont find the mentioned JS libraries.

I've tried precompiling with bundle exec rake assets:precompile RAILS_ENV=production RAILS_GROUPS=assets before pushing to Heroku and modifying the order of my JS required libraries in application.js but it wont work.

I'm new to web development so don't hesitate on pointing out everything you see wrong with my code and correct me as much as you want.

The error displayed on the JS console:

GET https://mr-cocktail-lutzcc1.herokuapp.com/assets/jquery.js net::ERR_ABORTED 404 (Not Found)
GET https://mr-cocktail-lutzcc1.herokuapp.com/assets/jquery_ujs.js net::ERR_ABORTED 404 (Not Found)
    DevTools failed to load SourceMap: Could not load content for chrome-extension://cjdnfmjmdligcpfcekfmenlhiopehjkd/node_modules/axios/dist/axios.map: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME
    cocoon-75a0c16d7d8256fc1f97eec1f4f552daa8ffd9ae5b4833390c0f2f4a2e939c78.js:142
Uncaught ReferenceError: jQuery is not defined
            at cocoon-75a0c16d7d8256fc1f97eec1f4f552daa8ffd9ae5b4833390c0f2f4a2e939c78.js:142
        (anonymous) @ cocoon-75a0c16d7d8256fc1f97eec1f4f552daa8ffd9ae5b4833390c0f2f4a2e939c78.js:142

enter image description here

application.js

import 'bootstrap';

require("@rails/ujs").start();
require("turbolinks").start();
require("@rails/activestorage").start();
require("channels");

//= require bootstrap
//= require jquery
//= require jquery_ujs
//= require jquery3
//= require jquery_nested_form
//= require cocoon
//= require_tree

manifest.js

//= link_tree ../images
//= link_directory ../stylesheets .css
//= link cocoon.js

config/webpack/environment.js

 const { environment } = require('@rails/webpacker')

// Bootstrap 4 has a dependency over jQuery & Popper.js:
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
  })
)

module.exports = environment

gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# front-end
gem 'autoprefixer-rails'
gem 'font-awesome-sass', '~> 5.12.0'
gem 'simple_form'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.2', '>= 6.0.2.2'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

gem 'cloudinary', '~> 1.12.0'
gem 'cocoon'
gem 'dotenv-rails', groups: [:development, :test]
gem 'jquery-rails'
gem 'nested_form_fields'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'rspec-rails', '4.0.0.beta3', group: [ :test ]
gem 'rails-controller-testing', group: [ :test ]

config/environments/production.rb

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true

  # Eager load code on boot. This eager loads most of Rails and
  # your application in memory, allowing both threaded web servers
  # and those relying on copy on write to perform better.
  # Rake tasks automatically ignore this option for performance.
  config.eager_load = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
  # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
  # config.require_master_key = true

  # Disable serving static files from the `/public` folder by default since
  # Apache or NGINX already handles this.
  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

  # Compress CSS using a preprocessor.
  # config.assets.css_compressor = :sass

  # Do not fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = 'http://assets.example.com'

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

  # Store uploaded files on the local file system (see config/storage.yml for options).

  config.active_storage.service = :cloudinary # HEREEEEE

  # Mount Action Cable outside main process or domain.
  # config.action_cable.mount_path = nil
  # config.action_cable.url = 'wss://example.com/cable'
  # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  # config.force_ssl = true

  # Use the lowest log level to ensure availability of diagnostic information
  # when problems arise.
  config.log_level = :debug

  # Prepend all log lines with the following tags.
  config.log_tags = [ :request_id ]

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Use a real queuing backend for Active Job (and separate queues per environment).
  # config.active_job.queue_adapter     = :resque
  # config.active_job.queue_name_prefix = "rails_mister_cocktail_production"

  config.action_mailer.perform_caching = false

  # Ignore bad email addresses and do not raise email delivery errors.
  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
  # config.action_mailer.raise_delivery_errors = false

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation cannot be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Use default logging formatter so that PID and timestamp are not suppressed.
  config.log_formatter = ::Logger::Formatter.new

  # Use a different logger for distributed setups.
  # require 'syslog/logger'
  # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

  if ENV["RAILS_LOG_TO_STDOUT"].present?
    logger           = ActiveSupport::Logger.new(STDOUT)
    logger.formatter = config.log_formatter
    config.logger    = ActiveSupport::TaggedLogging.new(logger)
  end

  # Do not dump schema after migrations.
  config.active_record.dump_schema_after_migration = false

  # Inserts middleware to perform automatic connection switching.
  # The `database_selector` hash is used to pass options to the DatabaseSelector
  # middleware. The `delay` is used to determine how long to wait after a write
  # to send a subsequent read to the primary.
  #
  # The `database_resolver` class is used by the middleware to determine which
  # database is appropriate to use based on the time delay.
  #
  # The `database_resolver_context` class is used by the middleware to set
  # timestamps for the last write to the primary. The resolver uses the context
  # class timestamps to determine how long to wait before reading from the
  # replica.
  #
  # By default Rails will store a last write timestamp in the session. The
  # DatabaseSelector middleware is designed as such you can define your own
  # strategy for connection switching and pass that into the middleware through
  # these configuration options.
  # config.active_record.database_selector = { delay: 2.seconds }
  # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
  # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end

Thanks!

  • If you don't provide secret key base then you keep struggling. First check https://stackoverflow.com/questions/25426940/what-is-the-use-of-secret-key-base-in-rails-4 to learn why you need it. – Amit Patel Apr 28 '20 at 03:27
  • Thanks for the info, secret key base is now set. I was abe to run `bundle exec rake assets:precompile RAILS_ENV=production RAILS_GROUPS=assets` and precompile before pushing to Heroku, but the issue with jquery and jquery_ujs is still there. Any sugestion? – Luis César Apr 28 '20 at 16:18

1 Answers1

0

Environment variables, secret keys and API keys that are unique to your app need special treatment (to keep them safe and secure).

First principal, never commit them into your git repo.

This leads to the strange scenario where you have these important configuration variables all nicely setup on your development machine, but how to get them on your server?

With heroku's set environment variable command, that's how :)

See here: https://devcenter.heroku.com/articles/config-vars

Try this:

$> rake secret   # to generate a new key
$> heroku config:set secret_key_base='put new key here'

I also suggest you read Heroku's 12 Factor App principals, an easy read that explains good app deployment principals. Item 3 Config is worth a read. https://12factor.net/

Evolve
  • 8,939
  • 12
  • 51
  • 63
  • Thanks, the secret keys issue is now solved. I was abe to run `bundle exec rake assets:precompile RAILS_ENV=production RAILS_GROUPS=assets` and precompile before pushing to Heroku, but the issue with jquery and jquery_ujs is still there. Any sugestion? – Luis César Apr 28 '20 at 16:17
  • Not alot of ideas on my end. I notice you're running jquery-rails gem, I had a quick look at their documentation, maybe you don't need to include all those jquery files in application.js https://github.com/rails/jquery-rails – Evolve Apr 28 '20 at 17:41
  • I was able to "fix it" (still getting same error in the console but now is working. Weird) by modifying config/webpack/environment.js. I added the complete path for the plugin. `'jquery/src/jquery'` instead of just `'jquery'` – Luis César Apr 28 '20 at 17:47
  • Ah I can half see an issue now. Originally rails just supported js via application.js, and gems like jquery-rails basically injected it in for you. Since the added support for Webpack via Webpacker.. there is a second way to get js libraries into your rails app. Seems you've been loading jquery twice. Once via jquery-rails and another via webpack. Try removing the gem and see if that still works. Reduces issues to have only one copy loaded if u can. – Evolve Apr 28 '20 at 18:12