2011-10-30 52 views
1

我最近開始在CoffeeScript中開發一個不平凡的項目,我正在努力處理註冊輸出等問題。我正在以非常'pythonesque'的方式編寫它,單個文件有效地成爲相關類和功能的「模塊」。我正在尋找的是在本地定義類和函數的最好方法,並且儘可能少地重複地在exports/window中定義。NodeJS:保持庫文件DRY

目前,我使用的每一個文件下面,保存在文件中寫exports.X = X一切:

class module 
    # All classes/functions to be included in exports should be defined with `@` 
    # E.g. 
    class @DatClass 

exports[name] = item for own name, item of module 

我也看了使用功能的可能性(比如, publish),它將在傳遞類exports/window取決於它的名字:

publish = (f) -> 
    throw new Error 'publish only works with named functions' unless f.name? 
    ((exports ? window).namespace ?= {})[f.name] = f 

publish class A 
# A is now available in the local scope and in `exports.namespace` 
# or `window.namespace` 

然而,這不符合功能工作的,據我所知,他們不能在CoffeeScript中「命名爲」(E 。G。 f.name始終爲''),因此publish無法確定正確的名稱。

有什麼方法可以像publish一樣工作,但可以使用函數嗎?或者處理這個問題的其他方法?

回答

2

這是一個醜陋的黑客攻擊,但你可以使用以下命令:

class module.exports 
    class @foo 
    @bar = 3 

然後:

require(...).foo.bar // 3 
+0

哈克,當然,但坦率地講整潔。 Works/w函數,如果你聲明像@fn =(args ...) - >'fn()'的結果。我對於一個人會非常想用這個.. –

+1

這非常整齊。是什麼讓它變得拙劣? – connec

+0

在我看來,這只是一種輕率的冒險行爲,因爲它不是任何官方文檔中提到的技術。儘管如此,這也可能與Node&CoffeeScript的btw有關。 –

0

(function (exports) { 
    // my code 

    exports.someLib = ... 
})(typeof exports === "undefined" ? window : exports); 

是一個巧妙的方法應該做你想做的。

如果編寫包裝器樣板文件是一個痛苦,然後使用構建腳本自動化它。

+0

我相信CoffeeScript中已經不正是當它編譯腳本。我的問題是,定義類正確地導致重複:'exports.SomeClass = class SomeClass',沒有第二個'SomeClass'結果函數將不會有'name'屬性,這禁止了有用的反射。 – connec

+0

@connec那麼是什麼?認真。只需執行'class SomeClass',然後執行'exports.SomeClass = SomeClass'。我不稱之爲重複,我稱這具有明確的出口。 – Raynos

+0

夠公平的,但我希望有一個更簡潔的解決方案。如果你只有幾個類,但是對於有幾十個類的模塊(例外,令牌,節點等),你的方法沒有問題,這將是非常單調和容易出錯的。 – connec

0

我正在尋找的是用盡可能少重複地定義類和函數在本地和exports/window的最佳途徑。

這是不可能做到像

exports.x = var x = ...; 

東西沒有用JavaScript編寫x兩次(而不是訴諸黑magicks,即eval),同樣也適用於CoffeeScript的。 Bummer,我知道,但事情就是這樣。

我的建議是不要太掛在上面;這種重複是常見的。但是請問自己:「我是否真的需要導出這個函數或變量使它在本地可用?」乾淨的解耦代碼通常不會那樣工作。

0

「no named functions」規則有個例外:classes。這工作:http://jsfiddle.net/PxBgn/

exported = (clas) -> 
    console.log clas.name 
    window[clas.name] = clas 
... 
exported class Snake extends Animal 
    move: -> 
    alert "Slithering..." 
    super 5