2015-05-21 11 views
30

Premendo questo problema esatto momento:importazioni circolari con webpack ritorno oggetto vuoto

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

FileB: 
var a = require file A 

FileC: 
var a = require file A 

Quando si esegue il codice, ottengo un errore di file C:

A.doSomething is not a function 

gettato un debugger in là e ho visto che A è un oggetto vuoto. Che cosa è davvero strano è che sto ricevendo solo un errore nel file C, ma non il file B. Super confuso qui.

+0

ho scritto uno strumento per controllare il vostro progetto Webpack per le dipendenze circolari: https://github.com/DelvarWorld/webpack-cyclic-dependency- checker –

risposta

58

Questo non è un problema di webpack ma una proprietà di moduli CommonJS.

Quando un modulo CommonJS viene richiesto per la prima volta, la proprietà exports viene inizializzata su un oggetto vuoto dietro le quinte.

module.exports = {}; 

Il modulo può quindi decidere di estendere questa proprietà exports, o ignorarla.

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

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

Così, quando A richiede B e B richiede A subito dopo, A non è ancora eseguita (che produrrebbe un loop infinito), ma la sua attuale exports proprietà viene restituito. Dal A richiesto B nella parte superiore del file, prima di esportare qualsiasi cosa, la chiamata require('A') nel modulo B genererà un oggetto vuoto.

Una correzione comune per le dipendenze circolari consiste nel mettere le importazioni alla fine del file, dopo il che hai esportato le variabili richieste da altri moduli.

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

Questa dovrebbe essere la risposta accettata. Grazie ! – Pcriulan

+0

hey you :) grazie mi ha aiutato a capire il problema. Ma cosa succede se in A, è necessario accedere ad alcuni attributi esportati da B? Nel mio codebase ho appena sostituito 'module.exports' da' exports.attribute' e ora funziona ma non mi sembra molto naturale –

+0

Puoi sempre fare la stessa cosa in B. 'module.exports = {bar: 'foo'} ; var A = require ('a'); ', quindi' module.exports = {pippo: 'bar'}; var B = require ('B'); '. Se le tue esportazioni dipendono l'una dall'altra, dovresti costruirle progressivamente estendendo "esportazioni" invece di sovrascriverle. –

Problemi correlati