开发者

Structuring coffeescript code?

Under Rails 3.1, I'm trying to find out how to move a few coffeescript classes away from my controller defa开发者_运维技巧ult coffeescript file (home.js.coffee) into another file, in order to structure the whole a little bit.

Does anyone know how to "include" a coffeescript file into another?


What you want to do is export functionality. For instance, if you start with

class Foo
  ...

class Bar extends Foo
  ...

and you decide you move Foo to its own file, that file should look like

class Foo
  ...

window.Foo = Foo

(where window.Foo = Foo makes Foo a global), and Bar's file should start with the Sprockets directive

#= require Foo

(assuming that you've named Foo's file Foo.js.coffee). Each file is compiled into JS independently, but Sprockets will ensure that Foo is included before Bar.

Note that, as a shortcut, you can get rid of the window.Foo = Foo line, and instead write

class window.Foo
  ...

or simply

class @Foo
  ...

to define a class named Foo that's attached to the window object.


While using the window object as a place to share functionality among different parts of your code can work quite well, it can get somewhat ugly when you're working on a big/complex codebase. Also, you have to handle loading all of the dependencies manually, which can get somewhat frustrating too. Many people just end up loading everything in every request, regardless of what's actually needed for that particular page.

There are plenty of libraries built in an attempt to solve those issues and make exporting and importing functionality among files more managable. One of the more common ones today is RequireJS which is an implementation of the CommonJS AMD specs. You can find other libraries and a comparison between them here, and there's a great tutorial on how to write modular JavaScript using those libraries over at Addy Osmani blog - which also talks about the new upcoming modules system in ES.next, which is quite interesting too.

I personally really like NodeJS's modules system (with the exports object and the require function), so I use node-browserify to package it up for working on the client side too. While that doesn't allow dynamically loading dependencies in an asynchronous way as the AMD specs does, it does allow to nicely share the same JavaScript code on both the client-side and server-side, which is a huge bonus for me (mainly because I'm working with NodeJS on the server side too, so I'm not sure how important that might be for you) and it handles packaging all of the dependencies together nicely for you (so they can be synchronously require()d) by parsing your JavaScript code and looking for plain require() calls to determine what a given script requires in order to run.


You can also do it like this:

@app = window.app ? {}

app.Foo = Foo

This will make app contain all your global classes, and window.app ? {} makes sure that you will only create one app.


I'm not sure that's directly possible (but someone feel free to correct me).

My understanding is that the CoffeeScript interpreter runs before Sprockets merges all of your assets. Since comments in .coffee files do not appear in the output, and since Sprockets uses //= code comment directives to build everything, I don't think there's a way to create Sprockets directives in CoffeeScript at this time.

You could still split up your work into multiple .coffee files and utilize a parent "directive" javascript file to combine the pieces (it could consist of just Sprockets directives, like how the stock application.js ships in Rails 3.1). Using the Sprockets //= require_tree directive, you could split your CoffeeScript and still keep your app fairly organized, but you'd still have plain ol' Javascript files lingering around managing Sprockets.

This question might explain the asset pipeline a little better. There's also some Sprockets helpers in the Edge documentation here: http://edgeapi.rubyonrails.org/classes/ActionView/Helpers/SprocketsHelper.html#method-i-sprockets_javascript_include_tag , but that then pushes the work into your views which might get ugly.

Hope that helps!


Use cake, you can define the order of files and also other custom steps like minify, etc

Make sure that you specify that all coffee files are combined into single .js output file.

https://github.com/jashkenas/coffee-script/wiki/[HowTo]-Compiling-and-Setting-Up-Build-Tools

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜