To avoid defining your constants twice, I would use Rails to create a JS that contains your constants. I understand that I want to avoid using Rails in JS, but proper code separation should cover any such problems.
First define your constants in Ruby, for example, in config/environment.rb or in a custom initializer:
CONST_A = 3 CONST_B = 4 CONST_C = 5
Then create a new controller with one action, the sole purpose of which is to read the Ruby values ββand output them as JavaScript. For instance:
class JavascriptsController < ApplicationController caches_page :constants def constants render :template => 'constants.js.erb' end end
Note that the action is cached by the page to avoid unnecessary hits on the Rails stack.
Now create a view app/views/javascripts/constants.js.erb in which you display the Ruby values ββas a JavaScript object:
var constants = { a: <%= CONST_A %>, b: <%= CONST_B %>, c: <%= CONST_C %> };
Connect a simple route in config/routes.rb to connect to JavascriptsController actions:
map.connect '/javascripts/:action.js', :controller => 'javascripts'
Finally, include this JS in your layout before any other JS:
<%= javascript_include_tag 'constants' %>
That should do it. This line requests /javascripts/constants.js , which then defines the JS constants object. Although this JS is generated using Rails, it remains separate from any other JS files in the application and avoids duplicate definitions of your constants.
As mentioned earlier, you must cache the JavascriptsController#constants action. Also consider minimizing constants.js (i.e., removing unnecessary characters) and combining it with other JavaScript files to reduce HTTP requests. I use the AssetHat gem (disclaimer: I wrote it), which has successfully accelerated CSS and JS on some high-profile sites.