2015-05-21 13 views
30

目前達不到這個確切的問題:圓形進口用的WebPack返回空的對象

FileA: 
var b = require file B 
var c = require file C 

FileB: 
var a = require file A 

FileC: 
var a = require file A 

當我運行代碼,我得到一個錯誤的文件C:

A.doSomething is not a function 

在那裏扔了一個調試器和看到A是空的物體。什麼是真的奇怪的是,我只得到文件C中的錯誤,但不是文件B.超級困惑在這裏。

+0

我寫了一個工具來檢查你的WebPack項目循環依賴:https://github.com/DelvarWorld/webpack-cyclic-dependency-檢查器 –

回答

58

這不是webpack的問題,而是CommonJS模塊的一個屬性。

當首先需要CommonJS模塊時,其exports屬性被初始化爲幕後的空對象。然後

module.exports = {}; 

該模塊可以決定延長此exports屬性,或者將其覆蓋。

exports.namedExport = function() { /* ... */ }; // extends 

module.exports = { namedExport: function() { /* ... */ } }; // overrides 

所以當A需要BB需要A之後,A沒有再次執行(這將產生一個無限循環),而是返回其當前exports財產。由於A需要位於文件最頂部的B,因此在導出任何內容之前,B模塊中的require('A')調用將產生一個空對象。

循環依賴關係的常見修復方法是將導入放在文件末尾之後已導出其他模塊所需的變量。

A

module.exports = { foo: 'bar' }; 
require('B'); // at this point A.exports is not empty anymore 

B

var A = require('A'); 
A.foo === 'bar'; 
+2

這應該是被接受的答案。謝謝 ! – Pcriulan

+0

嘿你:)謝謝它幫助我理解了這個問題。但是如果在A中,你需要訪問由B導出的某個屬性?在我的代碼庫中,我剛剛用'exports.attribute'替換了'module.exports',它現在可以工作,但感覺不是很自然 –

+0

你可以在B中做同樣的事情''module.exports = {bar:'foo'} ; var A = require('a');',then'module.exports = {foo:'bar'}; var B = require('B');'。如果你的出口依賴於對方,那麼你應該通過擴展'exports'而不是覆蓋它來逐步建立它們。 –