2011-05-27 13 views
32

Under Rails 3.1, estoy tratando de encontrar cómo mover algunas clases de coffeescript desde mi archivo de coffeescript predeterminado del controlador (home.js.coffee) a otro archivo, para estructurar el conjunto un poco.¿Código de coffeescript de estructuración?

¿Alguien sabe cómo "incluir" un archivo coffeescript en otro?

Respuesta

62

Lo que quieres hacer es exportar funcionalidad. Por ejemplo, si usted comienza con

class Foo 
    ... 

class Bar extends Foo 
    ... 

y decide mover Foo a su propio archivo, ese archivo debe ser similar

class Foo 
    ... 

window.Foo = Foo 

(donde window.Foo = Foo hace Foo un mundial), y Bar 's archivo debe comenzar con la directiva Piñones

#= require Foo 

(asumiendo que usted ha nombrado Foo 's archivo Foo.js.coffee). Cada archivo se compila en JS de forma independiente, pero Sprockets se asegurará de que se incluya Foo antes de Bar.

Tenga en cuenta que, como un acceso directo, usted puede deshacerse de la línea window.Foo = Foo, y en lugar de escribir

class window.Foo 
    ... 

o simplemente

class @Foo 
    ... 

para definir una clase llamada Foo que se une a la window objeto.

+1

Gran respuesta Trevor, muchas gracias. – plang

+6

¡Hola Trevor, escribiste el libro de coffeescript PragProg! Es un honor ... – plang

+0

No hay problema, es lo que hago. :) –

0

No estoy seguro de que sea directamente posible (pero alguien no dude en corregirme).

Según tengo entendido, el intérprete de CoffeeScript se ejecuta antes de que Sprockets fusione todos sus activos. Como los comentarios en los archivos .coffee no aparecen en la salida, y dado que Sprockets usa las directivas de comentario de código //= para compilar todo, no creo que haya una forma de crear directivas de Sprockets en CoffeeScript en este momento.

Aún podría dividir su trabajo en varios archivos .coffee y utilizar un archivo javascript padre "directivo" para combinar las piezas (podría consistir solo en directivas de Piñones, como la stock application.js en Rails 3.1) . Utilizando la directiva Sprockets //= require_tree, podría dividir su CoffeeScript y mantener su aplicación organizada, pero todavía tendría archivos Javascript simples en torno a la administración de Sprockets.

This pregunta podría explicar un poco mejor la cartera de activos. También hay algunos ayudantes de Piñones en la documentación de Edge aquí: http://edgeapi.rubyonrails.org/classes/ActionView/Helpers/SprocketsHelper.html#method-i-sprockets_javascript_include_tag, pero eso lleva el trabajo a tus vistas, lo que puede ponerse feo.

Espero que ayude!

+0

No sabe cómo funciona Piñones, pero '/ * * /' comentarios se mantienen en la salida CoffeeScript. ¿Funcionaría '/ * // = ... * /'? –

+1

En el código de CoffeeScript, puede simplemente usar '# = ...' –

6

Al utilizar el objeto window como un lugar para compartir la funcionalidad entre diferentes partes de su código puede funcionar bastante bien, puede ponerse algo feo cuando se trabaja en una base de código grande/compleja. Además, debe manejar la carga de todas las dependencias de forma manual, lo que también puede ser frustrante.Muchas personas acaban cargando todo en cada solicitud, independientemente de lo que realmente se necesita para esa página en particular.

Hay muchas bibliotecas creadas en un intento de resolver esos problemas y hacer que la exportación e importación de la funcionalidad entre los archivos sea más manejable. Uno de los más comunes en la actualidad es RequireJS que es una implementación del CommonJS AMD specs. Puede encontrar otras bibliotecas y una comparación entre ellas here, y hay un excelente tutorial sobre cómo escribir JavaScript modular utilizando esas bibliotecas en Addy Osmani blog, que también habla sobre el nuevo sistema de módulos en ES.next, que también es bastante interesante.

Personalmente me gusta NodeJS's modules system (con el objeto exports y la función require), así que uso node-browserify a embalar la unidad para trabajar en el lado del cliente también. Si bien eso no permite la carga dinámica de dependencias de manera asíncrona como lo hacen las especificaciones de AMD, sí permite compartir el mismo código JavaScript tanto en el lado del cliente como en el servidor, lo cual es una gran ventaja para mí (principalmente porque También estoy trabajando con NodeJS en el lado del servidor, así que no estoy seguro de qué tan importante pueda ser para ti) y maneja el empaquetado de todas las dependencias juntas muy bien para ti (para que puedan ser sincrónicamente require() d) al analizar tu Código JavaScript y buscando llamadas simples require() para determinar qué es lo que una secuencia de comandos dada requiere para ejecutarse.

+0

¡Gracias por la respuesta! – plang

6

También puede hacerlo de esta manera:

@app = window.app ? {} 

app.Foo = Foo 

Esto hará que app contienen todas sus clases globales, y window.app ? {} se asegura de que sólo creará una app.

Cuestiones relacionadas