Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Rails Problem: Problem Implementing .js Library with non .js files dependencies [(WebpJS) Using Rails 4]

Problem

This is a Ruby on Rails issue. The problem is pretty straight forward: I am attempting to implement .js libraries that require non-js files to be in the same directory in order to work.

An example of this is the webpjs javascript library which polyfills the ability for the next-generation Webp(Weppy) image format be supported by browsers that don't natively support it, such as Firefox, desktop and mobile versions safari, and even IE6.

I've been able to verify the library works outside of Rails by merely following the defacto instructions of including the library and its dependency, a .swf file, in the same directory and attaching both files in the header or footer of the .html/.haml file. I've been able to even have the library mentioned and verified to be valid to be mentioned on CanIUse.com after testing the library on iOS Safary, IE6, IE8 and 10; and Firefox.

Nonetheless, when I attempt to integrate the library in any rails app via the assets/javascripts/ folder, the app doesn't implement the library correctly (including the shouter app everyone who participated in Thoughtbot's Intermediate Rails Course created) .

What I've attempted to do to solve the problem with no luck:

Naturally I attempted seeing if the removal of the sprocket directive //= require_tree . and manually inserting the library in the application.html.haml file with the following link directive would work:

    = javascript_include_tag "webpjs-0.0.2", "data-turbolinks-track" => true 

Unfortunately, I've had no luck getting this to work either. I'm begun to think whether there's an implicit expectation for a folder called js these files are stored in being the issue given the asynchronous version I don't use but is still featured on the website being the following:

<script>(function(){var WebP=new Image();WebP.onload=WebP.onerror=function(){
if(WebP.height!=2){var sc=document.createElement('script');sc.type='text/javascript';sc.async=true;
var s=document.getElementsByTagName('script')[0];sc.src='js/webpjs-0.0.2.min.js';s.parentNode.insertBefore(sc,s);}};
WebP.src='data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';})();</script>

Again I know it's not the format or files, being able to successfully hook the library up to my XAMP local server configuration and including the files both outside of Rails, as well as within Wordpress, with no problems.

In addition, ImageMagick was able to handle the format just fine within my style directive below involving PaperClip:

class PhotoShout < ActiveRecord::Base
  has_attached_file :image, styles: {
    shout: ["200x200>", :webp]
  }
end

In general, trying out similar js libraries that have non .js dependencies and having the same issue, I thought this validates a forum entry.

In case it was a config-related issue, I attempted to do the following within Rails to see if it'll fix the problem:

Rack::Mime::MIME_TYPES[".webp"] = "image/webp"

Unfortunately, it didn't fix the problem. With no errors on my console, I have no clue what to do next; dealing with this issue all month and decided it's time to post the problem here.

Only thing I can think of is forcing JavaScript to not use the fingerprint digest on the .swf file specifically the library depends on for IE (leaving the config entry for fingerprint digesting enabled). Does anyone have any ideas on how to do that?

But then again, that doesn't explain why the library is unable to parse through the document at all for its base effect (the .swf if only for IE). If it was erroring out after being unable to locate the .swf file, The Chrome Dev Tools console would have notified me of an uncaught exception.

The popular Rails debugging gem better_errors didn't bring up anything either.

Any help the next few days would be greatly appreciated, Whether it's a fellow Treehouse Rails student or Jason Seifer .

Example Rails App demonstrating this issue

I have several image-heavy sites I have to make with this library for the remainder of this month. Nonetheless, here's a very skeleton app that has this issue reproduced I've provided in a Git repository.

https://github.com/lozandier/shouter_being_debugged

Example of what's supposed to happen

Suppose I had the following markup ignoring any backend and including various, alternate ways of including the script haml commented out:

!!! 5 
%html{:lang => "en"} 
%head 
  %meta{:charset => "UTF-8"} 
  %meta{content: "width=device-width", name: 'viewport'}
  %link{:rel => "stylesheet", :href => "./stylesheets/main.css"}/ 
  %script{ src: 'javascripts/webpjs-0.0.2.min.js'}
  -# -:javascript
  -#   (function(){var WebP=new Image();WebP.onload=WebP.onerror=function(){
  -#   if(WebP.height!=2){var sc=document.createElement('script');sc.type='text/javascript';sc.async=true;
  -#   var s=document.getElementsByTagName('script')[0];sc.src='js/webpjs-0.0.2.min.js';s.parentNode.insertBefore(sc,s);}};
  -#   WebP.src='data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';})();
  %title WebP test 
  %img{src: "images/download.webp", alt: "Hopefully this is fixed"} 
%body 

In browsers that lack native support for the Webp image format --whether it's IE6, Firefox, or even the infamous Android browsers--the following should be the output generally to any image that's a webpjs file on the fly:

<!DOCTYPE html>
<html lang='en'></html>
<head>
  <meta charset='UTF-8'>
  <meta content='width=device-width' name='viewport'>
  <link href='./stylesheets/main.css' rel='stylesheet'>
  <script src='javascripts/webpjs-0.0.2.min.js'></script>
  <title>WebP test</title>
  <img alt='Hopefully this is fixed' src='data:image/png;base64,iVBOR…3DRogpFZntpgAAAAASUVORK5CYII'>
</head>
<body></body>

It's pretty straightforward what's going on here: The webpjs library will convert the .webp image to an optimized version of the image typically as a .png or .jpg image.

I've tested this library on a variety of alternate backend frameworks and languages with no issues (Node.js (Express), Wordpress, and spaghetti PHP) until I tried to utilize it with Rails. I'm inclined to say it has something to do with the asset pipeline or the rendering system I'm not understanding. Considering I tried defer, async, and other javascript tricks, I' do not know any other alternaties to force the script to execute differently if it was the problem.

In general, I have issues how to incorporate libraries that have non-js files as a fallback [which doesn't seem to be issue, because only ancient versions of IE need that file; doesn't explain why it's not working on Firefox within the Rails application(s)].

As a result, I cannot use

ActionView::Helpers::AssetTagHelper.register_javascript_expansion webpjs: ["webpjs.0.0.2.min", "file2", "file3"]
javascript_include_tag :webpjs 

That helper is to group.js files together rather than group it with another type of file related to it.

1 Answer

Alan Johnson
Alan Johnson
7,625 Points

Troubleshooting things like this can be pretty tricky. I've never tried using webpjs, so I can't comment on it specifically, but usually in cases like this I toss everything in under the correct spot in /app/assets, load the page up, and look at the browser console to see what assets couldn't be downloaded. Usually through a bit of trial and error while working through that list I'm able to get it all up and running!

Well it was partially solved by putting both files inside public, and then Chad Pytel of Thoughtbot let me know of a gotcha involving its way of checking whether a file is a .webp file or not: A simple substring check.

Of course, a regular expression would have been better; something like:

if (a.match(/[\w.\-\s]+(?=\.)+\.webp/ig))  

That's why it wasn't working inside Rails for images inside partials and so on but worked for static images because the caching/fingerprinting system usually associated with the file names.

The problem now for me since is changing the function to use this instead (I'm more familiar w/ Regular Expressions inside of PHP, Ruby, and other programming language with that check) AND be able to call the function via a callback if more WebP. images are added to the page or swapped dynamically.

For me, that will happen with my use of Foundation's Interchange JavaScript component for RWD images by Zurb, and my use of AJAX for dynamic content.

The library CAN do this, as seen on webpjs.appspot.com with the other variants of the library but it's not really implemented with this version of the library for typical, content image use of the WebP image format in a way that's easy to hook callbacks in order to force the conversion after page load... at least for me.

How I've attempted to debug

I would say I'm well versed with Chrome's Dev Tools; even familiar with doing profile checking, memory leak checking, painting issues analysis, network resources analyses, and so on.

That led me to doing stuff like the MIME edit I did.

I tried using Rails Panel which didn't help. The better_errors gem didn't help either.