2012-01-16 81 views
73

我有關於the node.js documentation on module caching一個問題:瞭解Node.js模塊:多個需要返回相同的對象?

模塊是他們第一次加載後緩存。這意味着 (其中包括)每次調用require('foo')將返回 完全相同的對象(如果它將解析爲相同的 文件)。

多次調用require('foo')可能不會導致模塊代碼爲 多次執行。這是一個重要的功能。通過它,可以返回 「部分完成」的對象,從而允許即使在它們會導致循環時也加載依附關係。

什麼意思是may

我想知道是否需要總是返回相同的對象。所以,如果我需要一個模塊app.js一個,改變內app.js出口對象(需要回報的),之後需要一個模塊app.js本身需要模塊一個,將我總是獲取該對象的修改版本,還是新的?

// app.js 

var a = require('./a'); 
a.b = 2; 
console.log(a.b); //2 

var b = require('./b'); 
console.log(b.b); //2 

// a.js 

exports.a = 1; 

// b.js 

module.exports = require('./a'); 
+4

在文檔中的這句話本來可以寫得更好。在我看來,*可能不*與*不允許*相同,即多次調用require('foo')**不能**導致模塊代碼被多次執行*。 – 2014-07-23 02:38:23

回答

3

的node.js在執行一些巨大的服務器項目有一些類型的緩存實現阻斷節點讀取文件的時間1000。

此高速緩存已列在require.cache對象中。我必須注意到,這個對象是可讀寫的,它可以在不殺死進程的情況下從緩存中刪除文件。

http://nodejs.org/docs/latest/api/globals.html#require.cache

OUH,忘了回答這個問題。 修改導出的對象不會影響下一次模塊加載。這會造成很大的麻煩...要求總是返回一個新的對象實例,不需要引用。 編輯文件並刪除緩存確實會更改導出的對象

做了一些測試後,node.js確實緩存了module.exports。修改require.cache[{module}].exports以新的修改後的返回對象結束。

+1

我發佈的代碼實際上是有效的。 'b.b'由值'2'定義。所以在這個例子中它是同一個對象。 – Xomby 2012-01-16 23:37:12

+1

同樣的結果。現在我真的很困惑... – moe 2012-01-16 23:48:30

+0

這是一個功能,在我眼裏相當有用。問題是如果我可以依靠它。該文件說「可能」,這使得它不清楚。 – Xomby 2012-01-16 23:55:52

0

嘗試drexhttps://github.com/yuryb/drex

drex是看一個模塊的更新和乾淨再需要更新後的 模塊。新代碼正在被要求()d,好像新的 代碼是完全不同的模塊,所以require.cache不是問題。

+1

問題在於另一個問題,但drex對於開發人員來說看起來非常酷。謝謝! – 2014-05-13 11:36:18

1

對於我所看到的,如果模塊名稱解析爲先前加載的文件,則將返回緩存的模塊,否則將單獨加載新文件。

也就是說,緩存基於實際文件名得到解決。這是因爲一般情況下,可以有不同版本的相同程序包安裝在不同級別的文件層次結構中,並且必須相應地加載。

我不確定的是,有些緩存失效的情況不是程序員的控制或意識,這可能會使無意中重新加載多個相同的包文件成爲可能。

47

如果同時app.jsb.js在同一項目(並在同一目錄下),然後駐留他們都將收到同一個實例的A。從node.js documentation

...到require('foo')每次調用會得到完全相同的對象返回,如果它會解決到同一個文件


的情況是不同的,當a.jsb.jsapp.js不同NPM模塊。例如:

[APP] --> [A], [B] 
[B] --> [A] 

在這種情況下,app.jsrequire('a')將解析的a.js不同的副本比require('a')b.js,因此返回不同實例的A。有一個blog post更詳細地描述這種行爲。

+0

使用兩個不同的A實例是好事還是壞事? – NeiL 2016-02-24 12:07:54

+0

「並在同一目錄中」。當[B]位於[App]所在的子文件夾中時,我收到了相同的實例。 – 2016-03-15 21:56:39

+3

我來找點別的,學到了新東西! TY – 2016-07-25 09:45:02

0

如果你想讓require(x)每次都返回一個新對象的原因只是因爲你直接修改那個對象 - 這是我遇到的情況 - 只是克隆它,並修改和使用只有克隆,像這樣:

var a = require('./a'); 
a = JSON.parse(JSON.stringify(a)); 
相關問題