2016-02-25 53 views
1

我真的很喜歡這樣的NodeJS(和它的瀏覽器端的對應)處理模塊:語言用的NodeJS/CommonJS的風格模塊系統

var $ = require('jquery'); 

var config = require('./config.json'); 

module.exports = function(){}; 

module.exports = {...} 

我實際上是由ES2015 'import' spec這是非常相似,很失望大多數語言。

出於好奇,我決定去尋找它們實現甚至支持類似的導出/導入樣式其他語言,但無濟於事。

也許我失去了一些東西,或者更可能的是,我的谷歌foo是沒有達到標準,但是這將是非常有趣的,看看哪些其他語言以類似的方式工作。

有沒有人碰到類似的系統? 或者,也許有人甚至可以提供它不會經常使用的原因。

+0

您要查找的功能究竟是什麼,區分這兩個系統的功能是什麼? – svick

+0

@svick主要是require函數,它返回一個函數或其他結構化數據。 與'從x導入x'隱式創建全局可訪問屬性相反,只能在文件頂部完成。 – ISNIT

回答

3

這是幾乎不可能恰當地比較這些功能。人們只能比較它們在特定語言中的實現。我主要使用Java和nodejs語言收集了我的經驗。

我發現這些差異:

  • 可以使用require不僅僅是爲了使其他模塊提供給您的模塊的更多。例如,您可以使用它來解析JSON文件。
  • 您可以在代碼中使用require無處不在,而import只能在文件的頂部。
  • require實際執行所需的模塊(如果尚未執行),而import有着更爲聲明性特性。這對所有語言來說可能都不是這樣,但這是一種趨勢。
  • require可以從子目錄加載私有依賴項,而import通常對所有代碼使用一個全局名稱空間。再說一遍,這也不是真的,而只是一種傾向。

責任

正如你所看到的,require方法有多重責任:聲明模塊依賴和讀取數據。這更好地與導入方法分開,因爲import應該只處理模塊依賴關係。我猜想,您可以使用require方法讀取JSON,它爲程序員提供了一個非常簡單的界面。我同意擁有這種簡單的JSON閱讀界面非常好,但是不需要將它與模塊依賴關係機制混合使用。可以有另一種方法,例如readJson()。這將分離關注點,因此require方法僅用於聲明模塊依賴關係。

位置在代碼

現在,我們只使用require爲模塊依賴關係,這是一個不好的做法,使用其他地方比在您的模塊的頂部。當您在代碼中的任何地方使用它時,都很難看到模塊依賴關係。這就是爲什麼您只能在代碼頂部使用import語句的原因。

我看不到導入創建全局變量的地步。它僅爲每個依賴項創建一致的標識符,該標識符僅限於當前文件。正如我上面所說的,我建議只在文件的頂部使用require方法。它確實有助於提高代碼的可讀性。

它是如何工作

執行代碼加載一個模塊,也可以是一個問題的時候,尤其是在大項目。您可能會遇到一個循環,其中一個模塊需要傳遞自己。這可能很難解決。據我所知,的NodeJS處理這種情況,像這樣:當A需要B和B要求A和您的要求,然後開始:

  • 模塊系統會記住它目前加載
  • 它執行代碼在一個
  • 它會記住當前正在加載乙
  • 其B中執行代碼
  • 它會嘗試加載A,但A已經加載
  • 一個尚未完成加載
  • 它返回的一半裝A到B
  • B不指望能在半載

這可能是一個問題。現在,人們可以爭辯說,應該避免循環依賴,我同意這一點。但是,循環依賴只能在程序的不同組件之間避免。組件中的類通常具有循環依賴性。現在,模塊系統可以用於兩個抽象層:類和組件。這可能是一個問題。

接下來,require方法通常會導致單例模塊,它們不能在同一個程序中多次使用,因爲它們存儲全局狀態。然而,這不是系統的錯誤,但程序員錯誤地錯誤地使用系統。不過,我的觀察是,require方法誤導了特別是新程序員這樣做。

依賴管理

的依賴管理是底圖不同的辦法確實是一個有趣的問題。例如,Java在當前版本中仍然錯過了正確的模塊系統。再次,它宣佈了下一個版本,但誰知道這是否會成爲現實。目前,您只能使用OSGi獲取模塊,這遠非易於使用。

下層nodejs的依賴管理非常強大。但是,這也不完美。例如,通過模塊API公開的非私有依賴性(通常是一個問題)是通過模塊API公開的依賴性。但是,這是依賴管理的常見問題,因此它不限於nodejs。

結論

我想兩者都沒有那麼糟糕,因爲每個成功使用。然而,在我看來,importrequire有一些客觀優勢,如責任分離。因此,import可以被限制在代碼的頂部,這意味着只有一個地方可以搜索模塊依賴關係。此外,import可能更適合編譯語言,因爲這些不需要執行代碼來加載代碼。