2015-05-21 4 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- checker –

ответ

58

Это не проблема с веб-пакетом, а свойство модулей CommonJS.

Когда сначала требуется модуль CommonJS, его свойство exports инициализируется пустым объектом за кулисами.

module.exports = {}; 

Модуль может решить продлить этот exports собственность или переопределить его.

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

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

Так что, когда A требует B и B требует A сразу после, A снова не выполняется (который будет производить бесконечный цикл), но его текущее exports имущество возвращается. Поскольку A требуется B в самом верху файла, перед экспортом ничего, вызов require('A') в модуле B даст пустой объект.

Общее исправление для круговых зависимостей заключается в том, чтобы поместить ваш импорт в конец файла, после вы экспортировали переменные, необходимые для других модулей.

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? В моей кодовой базе я просто заменил 'module.exports' на' export.attribute', и теперь он работает, но чувствует себя не очень естественно. –

+0

Вы всегда можете сделать то же самое в B. 'module.exports = {bar: 'foo'} ; var A = require ('a'); ', then' module.exports = {foo: 'bar'}; var B = require ('B'); '. Если ваш экспорт зависит друг от друга, вы должны постепенно наращивать их, расширяя «экспорт», а не переопределяя его. –

Смежные вопросы