Rails: Heroku assets in vendor getting 404 - javascript

I have a javascript in the vendors/assets/javascripts folder, and I have this line of code:
<script src="assets/grid.js"></script>
in one of my app/views page.
This grid.js file (inside the vendors directory) works when I test it out in localhost, but when I precompile and push my application to heroku, it says:
GET http://www.domain.com/assets/grid.js 404 (Not Found)
Why is this occurring?
Thanks

I would use the javascript_include_tag instead and that should work
<%= javascript_include_tag("grid.js") %>
In production I believe that the asset pipeline adds a hash onto the name of grid.js for fingerprinting (Section 1.2 of that documentation) so you can't use that path <script src="assets/grid.js"></script>

I tried: Set config.assets.compress = true in my config/environments/production.rb and all was fine, but it is a bad practice and gain bad performance. Yo can see this for more details config.assets.compile=true in Rails production, why not?
My solution:
Run in your local project RAILS_ENV=production bundle exec rake assets:precompile and push all the files generated in public/assent/ in your github repo and deploy in heruko. Yo can read this for more details https://devcenter.heroku.com/articles/rails-asset-pipeline#compiling-assets-locally

Related

Phoenix - no route found for GET /static/js/some.js

I am migrating my rails application to phoenix framework.
I added some javascript (say some.js) and css files to web/static/js and web/static/css dir.
<%= static_path(#conn, "/js/some.js") %> in the front page page/index.html.eexdidn't work. It raised the exception (dev env):
Phoenix.Router.NoRouteError at GET /static/js/some.js
no route found for GET /static/js/some.js (VisualTrader.Router)
If I copied some.js to priv/static/js dir, it worked. So what I missed? I thought the assets pipeline worked like the one in rails, which auto precompiled resources.
Below list my phoenix framework environments:
Elixir version
elixir -v
Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.3.0-dev (187f4f8)
Phoenix version
defp deps do
[{:phoenix, "~> 1.1.2"},
...
If you want to include the Javascript File to be precompiled you'd need to add the following line of code.
Add your Javascript file in web/static/js directory.
In web/static/js/app.js include your file
import "./some-file"

javascript_include_tag file is missing on the production environment ( 404 )

On the development environment (with therubyracer) all works great. Now I set nginx + passenger to run my rails app for the production environment. All works fine except one (slides_index.js) file for which I get 404.
That file contains jQuery code which has to be run just on one page.
To do so I use <%= javascript_include_tag "slides_index" %> on that page.
I run rake assets:precompile which created public/assets/application-1774b3421bf0b4433ea3628c1c5dce38.js. There is no any other .js file in the that path, especially no slides_index.js (that one is in app/assets/javascripts/).
It's quite obvious that if there's not slides_index.js in the public/assets/ path than I get 404 for it. The question is why it works fine with therubyracer (development environment) and how to fix it in a proper way ?
By default Rails only compiles application.js as a standalone file. You can add other files to be compiled in config/application.rb with config.assets.precompile, so add the slides_index:
config.assets.precompile += ['slides_index.js']

Rails application not pre-compliling asset into public\assets

I'm working on a Rails 4.0 app with following directory structure
-app
|->javascript
|->page-specific
|->myjavasript.js
In my application.css I have removed required tree directive to make sure I don't include all js on every page.
//= require_tree .
Now to include my javasript I used following syntax on my page:
The application works fine on my development environment but when I push my changes to my production environment, I get 404 when I browser make a call to get javascript.
I call made in production is:
server-name/javascripts/page_specific/myjavasript.js
I call made in develop machine is:
server-name/assets/page_specific/myjavasript.js?body=1
I read a bit about asset pipelines and added following to my production.rb:
config.assets.precompile += ['page_specific/myjavasript.js']
But still my public\assets folder doesn't contain myjavasript.js, and keep on getting a 404.
I have a couple of questions, I do I add page specific (not-cpntroller specific) assets to my app?
Why is it working on development and not in production, what is done differently?
How can I fix it?
In firebug I see:
"NetworkError: 404 Not Found - https://my-server/javascripts/page_specific/myjavasript.js"
Just try,
config.assets.precompile += ["page-specific/*"]
Then, open up rails console and run the below line to know whether page-specific folder is there under your app asset paths:
Rails.application.config.assets.paths
Hope it helps :)

Export static HTML+CSS+JS from Rails

When creating static apps I often start a new Rails app. This makes quite some things easier, like compilation (Coffeescript, SCSS), minimization (JS, CSS) and browser limitations (the page is being served from localhost:3000 so external sources can be loaded etc.).
At the end I want to export the app so I can put it online. Then I just need the HTML+CSS+JS. One can go and pluck the files out manually, but there probably is an easier way for this.
So: is there a tool that stores the compiled, minimized HTML+CSS+JS files from a Rails app?
If you just want to basically copy the website as it will be rendered by rails (and there is no need for server side code execution), you could just mirror the rails-website using
wget --page-requisites --convert-links http://URL-to-Start
However, this will only download those files that are referenced from the entry URL, so you might need to run it on all sub-URLs individually.
Source: Download a working local copy of a webpage
Agree with Screenmutt. I've tried a couple of the ones mentioned but have had most success with:
http://middlemanapp.com/
Does pretty much everything you are asking for and let's you export to static HTML.
install:
gem install middleman
create project:
middleman init my_new_project (or even better with template --template=html5)
run in local server for live edits:
bundle exec middleman
dump static code:
bundle exec middleman build
Perhaps you can 'scrape' the HTML from the localhost serving it?
There seem to be some tools for downloading sites in general... You can probably limit them to download resources from localhost:3000 only.
http://www.httrack.com/
http://www.linuxjournal.com/content/downloading-entire-web-site-wget
UPDATE: Here's another tutorial that might help Use Rails 3.1 for Static Sites
This is not a common usage. You might be able to extract all the static pages by manually caching everything.
I would recommend taking a look at some alternatives.
I'm sorry that this isn't a good answer, but to be honest... You are using Rails for something that it was never intended to do. There are much better ways of making static sites.
Also, a static site is not an "app". :)
All you have to do is switch to Rails production mode locally so that assets are combined and minified. Then all you have to do is view source for the HTML, CSS, and JS. This should only take a few seconds.
So the steps are
config.assets.compress = true in development.rb
view the app locally
view source, copy and paste into an index.html file
click on compressed CSS and JS form source and save those relative to your index.html making sure they link correctly
You can use Wget (as it's already mentioned). I would go with:
wget --mirror --convert-links --adjust-extension --page-requisites --no-parent http://www.yourdomain.com
Yo can also use Httrack.
Be sure when you set Httrack you exclude all external websites with scripts so you don't download f.e. Google Analytics js files or Adsense or Facebook scripts. In Httrack, you exclude it in Preferences with:
-*.googlesyndication.com/* -*.facebook.net/* -*.google-analytics.com/*
After you are done you still need to rewrite all links because they will point at .../some-page/index.html You need .../some-page/. This solves Dynamic to Static Script.
You shouldn't serve them from rails or do anything that binds your static files to being served from rails. You may one day decide to serve your app from a CDN.
JS
One big tip would be to look at using AMD (async module definition), which would allow you to specify your JS file dependencies. Then you can use require.js and r.js(a tool that crawl and compile your dependencies in you precompile step). That would work for your JS.
CSS
For CSS, you could use sass or less. You'd include 1 file at the end of the day on your page, but the compilation process would involve merging your CSS files together. Once again this can be done at the pre-compile step.
CDN
There are gems out there that show take your assets and pass them over to something like S3, this answer and others like it would help: Is there a way to asset pipeline assets to s3 when pushing to heroku? ; however, that isn't necessary when you are first starting.
I did it with a Rake task that would fetch each of the Rails routes one at a time. It needed a bit of jiggery pokery to handle the fact that you might have conflicting routes - e.g. wget would fetch /objects as a file called "objects" but then when you want to fetch /objects/4 it would overwrite that file with a folder called "objects" with a nested file called "4". So I move each downloaded page to "index.html" inside a directory with the same name.
Here's my code, which I out in lib/tasks/export.rake:
def adjust_paths(path)
text = File.read(path)
new_contents = text.gsub(/("|\.\.\/)(assets|packs)\//, "\\1../\\2/")
new_contents = new_contents.gsub("http://localhost:3020", "")
File.write(path, new_contents)
end
namespace :static do
desc 'Generate static site in ./out/ directory'
task :export => [
'assets:clean',
'assets:precompile',
:start_rails_server
] do
begin
out_prefix = "dist"
paths = Rails.application.routes.routes.map do |route|
route.path.spec.to_s
end.uniq.reject { |p| p.starts_with?("/rails") || p == "/cable" || p == "/assets" }
paths = paths.map { |p| p.sub("(.:format)", "") }
paths.sort_by(&:length).each do |path|
if path.include?(":id")
# You'll have to use your own method for deciding which ids to use
ids = ["1", "2", "3", "4"]
else
ids = [""]
end
ids.each do |id|
id_path = path.sub(":id", id)
`wget -P #{out_prefix} -nH -p -k http://localhost:3020#{id_path}`
if id_path != "/"
file_path = "#{out_prefix}#{id_path}"
FileUtils.mv(file_path, "#{file_path}.tmp", force: true)
FileUtils.mkdir_p(file_path)
result = FileUtils.mv("#{file_path}.tmp", "#{file_path}/index.html", force: true)
puts "Moving #{id_path} to #{id_path}/index.html: #{result}"
# Will then need to relativise all of the asset paths, since we've moved it
adjust_paths("#{file_path}/index.html")
end
end
end
ensure
# stop the server when we're done
Rake::Task['static:stop_rails_server'].reenable
Rake::Task['static:stop_rails_server'].invoke
end
end
desc 'Start a Rails server in the static Rails.env on port 3020'
task :start_rails_server do
`RAILS_SERVE_STATIC_FILES=1,RAILS_ENV=static rails s -p 3020 -d`
end
desc 'Stop Rails server'
task :stop_rails_server do
`cat tmp/pids/server.pid | xargs -I {} kill {}`
end
end
Then you can just do bundle exec rake static:export

javascript not running on heroku with rails 3.1

I've migrated a rails 3.0 app to 3.1 on Heroku. It's running on the cedar stack and everything is fine except that the app's javascript won't run. The application.js file is compiled and looks just as it should. It's accessible by going to myapp.com/assets/application.js. It just doesn't get run!
If I run the app locally, the javascript works, so I suspect that there must be some simple configuration issue that I'm missing. Here's my production.rb file:
FloridaBirdTrail::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
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = true
# Compress JavaScripts and CSS
config.assets.compress = true
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
end
edit
Replacing the contents of production.rb with that of development.rb has allowed at least some of my javascript to run (gmap3 isn't working, for some reason). But which of the settings is making the difference?
Open your application.rb file and make sure your Bundler require statement looks like the following:
Bundler.require *Rails.groups(:assets)
By default it looks like
# If you precompile assets before deploying to production, use this line
Bundler.require *Rails.groups(:assets => %w(development test))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
Manually precompiling worked for me.
bundle exec rake assets:precompile before you push to heroku.
Were you sure to switch Heroku to the Cedar stack? Here are some docs for upgrading
http://devcenter.heroku.com/articles/rails31_heroku_cedar#upgrading_from_previous_rails_31_releases
http://devcenter.heroku.com/articles/cedar
I had some Javascript problems (server-side on Heroku, locally everything was fine) that went away when I
* moved all my Javascript into a separate file instead of application.js
* removed require_tree from application.js and instead called up every javascript I wanted by name
* removed bootstrap.js from my app/assets/javascript folder
My guess is that compilation somehow screws things up.
I hope you did a local pre-compilation of assets before your latest Heroku push (as advised in one of the responses above).
Please check if your system is blocking the execution of JavaScripts. For this, open up the console while you are on your Heroku app, and check for exceptions. In case you see exceptions related to JavaScripts being blocked, that could be the issue. In my case, the same happened, and unfortunately, I was not able to do anything about it, as I didn't have admin privileges.

Categories

Resources