Reputation: 9580
TLDR:
What can you do to combine multiple CoffeeScript files into one JS file, in RoR, all under the same anonymous function block?
Long version:
I have a few CS files that will be loaded for part of a RoR web app. I'm wondering: what is a good way to separate concerns with CoffeeScripts and Ruby on Rail 3.1's asset pipeline?
Let's use the following as example code:
main.js.coffee
window.MyApp = {} # to escape the CoffeeScript anonymous function block
# (I like the anonymous function block because it protects my other
MY_GLOBAL_SETTING = "world!"
$.click "#my_button" myApp.sayHello
# (I could use something like goog.bind here instead of using myApp. Any suggestions? Fat arrow?)
hello.js.coffee
MyApp.sayHello = sayHello () ->
doComplicatedStuff()
alert("Hello #{ MY_GLOBAL_SETTING }")
complicated.js.coffee
doComplicatedStuff = () ->
# some really complicated algorithm, for example
true
I have my assets directory structured like the following:
assets/
application.js
application/
# javascript that gets used with the main application
secondary_page.js
secondary_page/
complicated.js.coffee
hello.js.coffee
main.js.coffee
secondary.js
//= require secondary_page/main.js.coffee
//= require secondary_page/complicated.js.coffee
//= require secondary_page/hello.js.coffee
I used to compile the files together with CoffeeScript as part of the build process, but now I want to use the asset pipeline instead. I'm drinking the RoR 3.1 kool-aid! Haha, seriously though, the asset pipeline looks awesome.
The problem I'm experiencing is that secondary.js looks like the following:
(function() {
// main.js
).call(this);
(function() {
// complicated.js
).call(this);
(function() {
// hello.js
).call(this);
This prevents local variables from being shared amongst the entire code. MY_GLOBAL_SETTING and doComplicatedStuff aren't available to sayHello.
So... what should I do? I can't think of a good way without introducing my own custom compilation step again.
Upvotes: 0
Views: 568
Reputation: 77416
This is a common question for Rails developers starting to use CoffeeScript. See, for example:
Solutions abound. The simplest is to preface variable declarations that you want to be visible outside of a particular file with @
, since the this
will point to window
in the outermost context of each file, and x
points to window.x
when no local x
is defined.
Upvotes: 2
Reputation: 4144
Probably the best way to do this is to leave them in their own anonymous scopes but export the individual functions you need access to from other modules. From Trevor Burnham's Coffeescript book, he recommends you do this (which works in node and browsers):
root = global ? window
root.exportableFunction = exportableFunction
root.MY_GLOBAL_SETTING = some: 'Setting'
Upvotes: 0